添加新的输入字段不会更新现有输入字段的值

时间:2020-07-12 09:49:57

标签: javascript jquery

这就是它应该如何工作的。默认情况下,有两组输入字段,其中百分比字段的值均为50%。现在,无论何时添加新的输入字段,都应在所有百分比字段之间分配百分比字段值,例如,如果有3组,则每个百分比字段应该具有33.33%。如果有4,则各占25%。现在,这部分工作正常。

现在,我正在尝试在其之上添加更多功能。我将简要介绍这些功能以及与之相关的问题。

  1. 当用户单击percentage input field时,以前的值消失,用户键入一个新的百分比值,并在两个输入字段之间进行划分。但是问题在于,它在用户刚刚输入的值的末尾添加了两个"%"符号。

  2. 第二个问题是,假设用户在第一个percentage field或第二个input field中键入新的百分比值,然后通过Add Field按钮添加一个新的input field,这些百分比不会在所有输入值之间划分。新的percentage value没有考虑新的percInput。我能想到的一个原因是input field变量没有以某种方式更新。

  3. 第三个问题与第二个问题相似。如果用户先添加新的percentage value,然后在该新input field中键入percInput,则百分比值将完全不除。这也可能是因为percInput变量未更新。与此相关的另一个问题是,单击新的百分比输入字段不会像以前的默认字段一样删除先前的值。

  4. 这很奇怪。如果用户单击百分比输入字段,但未添加值,而是继续添加新字段,则百分比值将在所有百分比之间分配。

所有这些问题在某种程度上都是相互关联的,我感到它们都是由于一个变量calculatePercentage而引起的。我想添加新的输入字段时不会更新。以前,我使用percInput函数来更新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> `; // percentage variable and percentage calculation for the first time let percInput = document.querySelectorAll('.urls-container .perc'); let percentage = (100 / percInput.length).toFixed(0).toString() + "%"; percInput.forEach((item) => { item.setAttribute("value", percentage); }); const removeField = (e) => { if (!e.target.classList.contains('delete-btn')) return; e.target.parentElement.remove(); calculatePercentage(); } // percentage input variable update and percentage calculation const calculatePercentage = () => { percInput = document.querySelectorAll('.urls-container .perc'); percentage = (100 / percInput.length).toFixed(0).toString() + "%"; percInput.forEach((item) => { item.setAttribute("value", percentage); }); } // remove a field form.addEventListener('click', removeField); // add input field addBtn.addEventListener('click', () => { span.insertAdjacentHTML("beforeBegin", html); calculatePercentage(); }); const percInputChange = function() { let val = this.value, $allInputs = $(percInput); if(val > 100) { $allInputs.val((100 / $allInputs.length) + "%"); calculatePercentage(); }else { $(percInput).not(this).val( (100 - val) / ($allInputs.length - 1) + "%"); setTimeout(() => { this.value = this.value + "%"; }, 500); calculatePercentage(); return; } }; // event listener when user types in a new percentage value $( percInput ).on('keyup', percInputChange); // event listener to hide previous input value $( percInput ).focus(function() { this.value = ""; }); // event listener to divide the percetange values when the user clicks away $( percInput ).blur(function() { if(this.value === ""){ percInput.forEach(item => { item.value = ( 100 / percInput.length ).toFixed(0).toString() + "%"; return; }); } });变量,并在此起作用。但是当我在上述情况下尝试使用它时,它将无法正常工作。

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

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<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}}

我知道这篇文章很奇怪,有很多问题。但是请耐心等待,因为我仍在学习中,如果我不将自己推入这些复杂的编码问题并陷入困境,我将无法学习。昨天我整天都在根据自己的知识尝试各种方法。如果我尝试使用所有方法,则帖子的篇幅会很大。所以,请忍受我。请帮助有需要的编码员。谢谢

PS。我一起使用jQuery和JS,这不是正确的选择。但是,一旦解决问题,我将重构并更改它们。 PS。

1 个答案:

答案 0 :(得分:1)

我不太确定您要使用脚本真正实现什么目标。但是我可以通过删除冗余位来重新开始。以下代码段将允许您添加或删除输入行,并将相应地调整百分比。

也许您可以指定如何您希望脚本对任何用户输入做出反应?

// add flields:
function addfields(){
   let all=$('.urls-container'), r=$('div:last',all).clone(),
       url=r.find('input[type=url]')[0];
   url.placeholder=+url.placeholder+1;
   $('.perc',r).removeAttr('data-manual');
   all.append(r); calcperc();
 }
// even distribution:
function calcperc(){
  let fix=$('.perc[data-manual]'),sum=0;
  fix.each(function(){sum+=parseFloat(this.value)});
  let rest= $('.perc').not(fix);
  rest.val(((100-sum)/rest.length).toFixed(2)+'%')
}

// manual distribution:
function recalc(){let inps=$('.perc'),cur=parseFloat(this.value);
 if (inps.length>1){
  this.value=cur.toFixed(2)+'%'; this.dataset.manual=1;
  calcperc();
} else this.value="100%"
}
// delegated event management:
$('form')
 .on('submit',function(e){e.preventDefault()}) // de-activate submit for testing
 .on('change','.perc',recalc)
 .on('click','.delete-btn',function(){$(this).parent().remove();calcperc()})
 .on('click','#addField',addfields);
 
 // initial distribution:
 calcperc();
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

<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>

我的recalc()当前版本允许您覆盖百分比值的一个。然后将调整所有其他值,因此总和再次为100%。

还请注意,在我的版本中,recalc()事件是在input事件上触发的,而不是keyup事件,否则添加百分号的动作会严重干扰任何输入由用户尝试。

修改
Lastet编辑涉及在输入字段中使用data-manual属性“标记”手动更改的百分比。这将保护该字段免受将来的重新计算。其余百分比将在非固定字段之间平均分配。