动态插入新的输入字段后,无法设置输入值

时间:2020-07-09 20:17:44

标签: javascript

这就是它应该如何工作的。默认情况下,有两组input fields,其中percentage fields的值分别为50%。现在,每当添加新的input field时,都应将percentage field的值分配给所有percentage fields,例如,如果有3组,则percentage应当各占33.33%。如果有4个,则每个占25%。

现在的问题是,每当我添加一个新字段时,field并没有被第一次分割,而是又添加了另一个fields,那就是当它被分配到所有{{1}中时},但新的除外。

另一个问题是,如果我删除一个,则percentage不会减少。保持不变。

请注意,在javascript代码中,我必须两次声明percInput变量,一次是在click事件外部,一次是在click事件内部。这是因为在添加新字段之前,默认字段必须分配给每个默认字段的50%。这是我可以动态分配它的唯一方法,尽管我可以用html对其进行硬编码。

这是我到目前为止尝试过的:

const form = document.querySelector("form");
const span = document.querySelector("span");
const addBtn = document.querySelector("#addField");
const html = `
    <div class="url-pair">
        <input type="url" placeholder="3">
        <input type="text" class="perc">
        <button class="delete-btn" type="button">Delete</button>
    </div>
`;

let percInput = document.querySelectorAll('.urls-container .perc');
let percentage = (100 / percInput.length).toFixed(2).toString() + "%";

percInput.forEach((item) => {
    item.setAttribute("value", percentage);
});

const removeField = (e) => {
    if (!e.target.classList.contains('delete-btn')) return;
    e.target.parentElement.remove();
}

// delete field
form.addEventListener('click', removeField);

// add field and divide input value automatically
addBtn.addEventListener('click', () => {

    percInput = document.querySelectorAll('.urls-container .perc');
    percentage = (100 / percInput.length).toFixed(2).toString() + "%";

    percInput.forEach((item) => {
        item.setAttribute("value", percentage);
    });

    span.insertAdjacentHTML("beforeBegin", html);

});
<form action="#" method="POST">

  <div class="urls-container">
    <div class="url-pair">
      <input type="url" placeholder="1">
      <input type="text" class="perc">
      <button class="delete-btn" type="button">Delete</button>
    </div>

    <div class="url-pair">
      <input type="url" placeholder="2">
      <input type="text" class="perc">
      <button class="delete-btn" type="button">Delete</button>
    </div>

    <span></span>
  </div>

  <div>
    <div>
      <button type="button" id="addField">Add Field</button>
    </div>

    <div>
      <button type="submit">Create</button>
    </div>
  </div>

</form>

3 个答案:

答案 0 :(得分:2)

问题在于,在您将addBtn.addEventListener插入新文档之前,您正在input中计算百分比,因此,当您在文档中查询所有input元素时,想念您应该已经添加的那个。如果您只是在插入代码后将其移动到,则它将起作用。

并且,由于您需要在添加和删除元素时更新百分比,因此负责该操作的代码应分解为自己的函数,以便可以在添加或删除字段之后调用它。

const form = document.querySelector("form");
const span = document.querySelector("span");

// `.getElementById() is the fastest way to get an element
// reference when there is an ID. It's faster than .querySelector()
const addBtn = document.getElementById("addField");
const html = `
    <div class="url-pair">
        <input type="url" placeholder="3">
        <input type="text" class="perc">
        <button class="delete-btn" type="button">Delete</button>
    </div>
`;

let percInput = document.querySelectorAll('.urls-container .perc');
let percentage = (100 / percInput.length).toFixed(2).toString() + "%";

percInput.forEach((item) => {
    item.setAttribute("value", percentage);
});

const removeField = (e) => {
    if (!e.target.classList.contains('delete-btn')) return;
    e.target.parentElement.remove();
    
    // Now, call the code that updates the percentages
    updatePercentages();
}

// delete field
form.addEventListener('click', removeField);

// add field and divide input value automatically
addBtn.addEventListener('click', () => {
    // Insert the new element into the document first.
    span.insertAdjacentHTML("beforeBegin", html);
    
    // Now, call the code that updates the percentages
    updatePercentages();
});

function updatePercentages(){
    // This code only runs AFTER input elements have been added
    // or removed from the document.
    
    // Calculate your percentages based on what's in the document
    percInput = document.querySelectorAll('.urls-container .perc');
    percentage = (100 / percInput.length).toFixed(2).toString() + "%";
    
    // Then update the elements.
    percInput.forEach((item) => {
      item.setAttribute("value", percentage);
    });
}
<form action="#" method="POST">

  <div class="urls-container">
    <div class="url-pair">
      <input type="url" placeholder="1">
      <input type="text" class="perc">
      <button class="delete-btn" type="button">Delete</button>
    </div>

    <div class="url-pair">
      <input type="url" placeholder="2">
      <input type="text" class="perc">
      <button class="delete-btn" type="button">Delete</button>
    </div>

    <span></span>
  </div>

  <div>
    <div>
      <button type="button" id="addField">Add Field</button>
    </div>

    <div>
      <button type="submit">Create</button>
    </div>
  </div>

</form>

答案 1 :(得分:1)

因此,对于添加

您做对了,只是您想添加新元素之前以计算百分比。因此,只需将span.insertAdjacentHTML("beforeBegin", html)放在计算之前。

对于删除

同样,您已经具有删除权,您只需要在删除元素后再次计算百分比即可(就像添加元素时一样)。

为了使事情更清楚,我将计算代码放入一个名为calculatePercentage的新函数中,并在每次删除或添加一个元素后调用此函数以计算新值。

摘要:

const form = document.querySelector("form");
const span = document.querySelector("span");
const addBtn = document.querySelector("#addField");
const html = `
    <div class="url-pair">
        <input type="url" placeholder="3">
        <input type="text" class="perc">
        <button class="delete-btn" type="button">Delete</button>
    </div>
`;

let percInput = document.querySelectorAll('.urls-container .perc');
let percentage = (100 / percInput.length).toFixed(2).toString() + "%";

percInput.forEach((item) => {
    item.setAttribute("value", percentage);
});

const removeField = (e) => {
    if (!e.target.classList.contains('delete-btn')) return;
    e.target.parentElement.remove();
    calculatePercentage(); // Calculate after removal
}

// This function calculates the percentage
const calculatePercentage = () => {
    percInput = document.querySelectorAll('.urls-container .perc');
        percentage = (100 / percInput.length).toFixed(2).toString() + "%";

        percInput.forEach((item) => {
            item.setAttribute("value", percentage);
        });
}

// delete field
form.addEventListener('click', removeField);

// add field and divide input value automatically
addBtn.addEventListener('click', () => {

    span.insertAdjacentHTML("beforeBegin", html);
    
    calculatePercentage(); // Calculate after addition


});
<form action="#" method="POST">

  <div class="urls-container">
    <div class="url-pair">
      <input type="url" placeholder="1">
      <input type="text" class="perc">
      <button class="delete-btn" type="button">Delete</button>
    </div>

    <div class="url-pair">
      <input type="url" placeholder="2">
      <input type="text" class="perc">
      <button class="delete-btn" type="button">Delete</button>
    </div>

    <span></span>
  </div>

  <div>
    <div>
      <button type="button" id="addField">Add Field</button>
    </div>

    <div>
      <button type="submit">Create</button>
    </div>
  </div>

</form>

答案 2 :(得分:0)

这样的事情。

const form = document.querySelector("form");
const span = document.querySelector("span");
const addBtn = document.querySelector("#addField");
const html = `
    <div class="url-pair">
        <input type="url" placeholder="3" class="index">
        <input type="text" class="perc">
        <button class="delete-btn" type="button">Delete</button>
    </div>
`;

let percInput = [...document.querySelectorAll('.urls-container .perc')];
let percentage = (100 / (percInput.length)).toFixed(2).toString() + "%";

percInput.forEach((item) => {
    item.setAttribute("value", percentage);
});

const removeField = (e) => {
    if (!e.target.classList.contains('delete-btn')) return;
    e.target.parentElement.remove();
    recalculateRowVaues();
}

// delete field
form.addEventListener('click', removeField);

// add field and divide input value automatically
addBtn.addEventListener('click', () => {
    span.insertAdjacentHTML("beforeBegin", html);
    recalculateRowVaues();
});
function recalculateRowVaues() {
    percInput = [...document.querySelectorAll('.urls-container .perc')]; // So ist besser
    indexInput = [...document.querySelectorAll('.urls-container .index')];
    percentage = (100 / (percInput.length)).toFixed(2).toString() + "%";

    percInput.forEach((item) => {
        item.setAttribute("value", percentage);
    });
    indexInput.forEach((item, index) => {
        item.setAttribute("placeholder", index + 1);
    });
}
<form action="#" method="POST">

  <div class="urls-container">
    <div class="url-pair">
      <input type="url" placeholder="1" class="index">
      <input type="text" class="perc">
      <button class="delete-btn" type="button">Delete</button>
    </div>

    <div class="url-pair">
      <input type="url" placeholder="2" class="index">
      <input type="text" class="perc">
      <button class="delete-btn" type="button">Delete</button>
    </div>

    <span></span>
  </div>

  <div>
    <div>
      <button type="button" id="addField">Add Field</button>
    </div>

    <div>
      <button type="submit">Create</button>
    </div>
  </div>

</form>