我正在尝试创建一个表单,在该表单中,我需要用户添加至少3年的地址数据。但是我在添加和删除字段时遇到问题,具体取决于用户是否输入正确的年份。
例如,将1加到下面的年份框中3次可以正常工作。我得到了3组地址字段,但是,如果用户然后将最后一组更改为2年,则会添加第4个,实际上什么也不会发生。
如果再将第二个地址更改为2/3年,则它似乎也会出现故障,它会删除下面的地址,但是将其更改回1年并不会重新添加这些其他字段。
希望这很有意义,我只需要动手就能使这种逻辑起作用,因为我无法弄清楚。不要评论我创建的用于生成HTML的函数,这只是为了完成这项工作,请坚持这个主题。
注意:忽略底部的3个功能,这些不是问题,也不是我的优先事项。
let addresses = {
'#years_at_address_0': { /* The default one */
elm: document.querySelector('#years_at_address_0'),
value: 0,
parent: '#previousAddress',
added: false
}
};
function setupAddressChecking(watch)
{
if (addresses[watch] === undefined) {
addresses[watch] = {
elm: document.querySelector(watch),
value: 0,
parent: '#previousAddress' + (Object.keys(addresses).length > 0 ? Object.keys(addresses).length : ''),
added: false
};
}
let count = Object.keys(addresses).length;
addresses[watch].elm.addEventListener('change', function() {
if (this.value && addresses[watch].value !== this.value) {
addresses[watch].value = parseInt(this.value);
if (calculateYears() && !addresses[watch].added) {
document.querySelector('#yearsAdditional').appendChild(createNewAddress());
addresses[watch].added = true;
setupAddressChecking('#years_at_address_'+count);
}
}
});
}
function calculateYears()
{
let count = 0;
let remove = false;
const keys = Object.keys(addresses);
for(var i = 0; i < keys.length; i++) {
let current = addresses[keys[i]];
if (count > 3) {
remove = true;
current.added = false;
document.querySelector(current.parent).parentNode.removeChild(document.querySelector(current.parent));
delete addresses[keys[i]];
}
count += current.value;
}
if (count === 3) {
return false;
}
return !remove;
}
function createNewAddress()
{
let count = Object.keys(addresses).length;
return createHTML({
0: { elm: createElement('div', {'id': 'previousAddress' + count}), root: null },
1: { elm: createElement('div'), root: 0 },
2: { elm: createElement('div'), root: 1},
3: { elm: createElement('label', {'for': 'previous_address', 'text': 'Address'}), root: 2},
4: { elm: createElement('div'), root: 1},
5: { elm: createElement('textarea', {
'cols': 40,
'id': 'previous_address' + count,
'name': 'finprop_previous_address',
'placeholder': 'Previous Address',
'rows': 4
}), root: 4},
6: { elm: createElement('div'), root: 1},
7: { elm: createElement('div', { 'id': 'previous_row_postcode' + count}), root: 0 },
8: { elm: createElement('div'), root: 7 },
9: { elm: createElement('label', {'for': 'previous_postcode', 'text': 'Postcode *'}), root: 8 },
10: { elm: createElement('div'), root: 7 },
11: { elm: createElement('input', {
'id': 'previous_postcode' + count,
'name': 'previous_postcode',
'placeholder': 'Postcode',
'type': 'text',
'maxlength': 8
}), root: 10 },
12: { elm: createElement('div'), root: 7 },
13: { elm: createElement('div', {'id': 'row_months_years_at_address' + count}), root: 0 },
14: { elm: createElement('div'), root: 13 },
15: { elm: createElement('label', {'for': 'years_at_address_' + count, 'text': 'How long at address *'}), root: 14 },
16: { elm: createElement('div'), root: 13 },
17: { elm: createElement('div'), root: 16 },
18: { elm: createElement('input', {
'id': 'years_at_address_' + count,
'maxlength': 2,
'min': 0,
'name': 'finprop_years_at_address',
'placeholder': 'Years',
'size': 4,
'type': 'text',
'class': 'years_at_address'
}), root: 17 },
19: { elm: createElement('div'), root: 16 },
20: { elm: createElement('input', {
'id': 'months_at_address_' + count,
'maxlength': 2,
'min': 0,
'name': 'finprop_months_at_address',
'placeholder': 'Months',
'size': 4,
'type': 'text'
}), root: 19 },
21: { elm: createElement('div'), root: 13 }
})[0].elm;
}
function createHTML(elements)
{
let keys = Object.keys(elements);
for (var i = 0; i < keys.length; i++) {
if (elements[keys[i]].root === null || elements[keys[i]].root === i) {
continue;
}
elements[elements[keys[i]].root].elm.appendChild(elements[keys[i]].elm);
}
return elements;
}
function createElement(type, options)
{
let elm = document.createElement(type);
if (options) {
for(var i = 0; i < Object.keys(options).length; i++) {
let key = Object.keys(options)[i];
if (key === 'text') {
elm.innerHTML = options[key];
continue;
}
elm.setAttribute(key, options[key]);
}
}
return elm;
}
setupAddressChecking('#years_at_address_0');
fieldset > div {
padding: 10px;
margin: 5px;
background: whitesmoke;
border: 1px solid lightgray;
}
<fieldset>
<h3>Address Details * denotes a required field</h3>
<div>
<div id="previousAddress0">
<div>
<div><label for="previous_address0">Address</label></div>
<div><textarea cols="40" id="previous_address0" name="finprop_previous_address0" placeholder="Previous Address" rows="4"></textarea></div>
<div></div>
</div>
<div id="previous_row_postcode0">
<div><label for="previous_postcode0">Postcode *</label></div>
<div><input id="previous_postcode0" name="previous_postcode0" placeholder="Postcode" type="text" maxlength="8">
</div>
<div></div>
</div>
<div id="row_months_years_at_address0">
<div><label for="years_at_address_0">How long at address *</label></div>
<div>
<div><input id="years_at_address_0" maxlength="2" min="0" name="finprop_years_at_address0" placeholder="Years" size="4" type="text" class="years_at_address0"></div>
<div><input id="months_at_address_0" maxlength="2" min="0" name="finprop_months_at_address0" placeholder="Months" size="4" type="text"></div>
</div>
<div></div>
</div>
</div>
</div>
<div id="yearsAdditional"></div>
</fieldset>
每次迭代时,您都将当前框添加到count
之后,以检查其是否大于3。这意味着在大多数情况下,如果最后一个框大于1,则将添加一个附加框被创建。
要更改此值,请添加当前year
值之前检查count
是否大于3。
count += current.value;
if (count > 3) {
remove = true;
current.added = false;
document.querySelector(current.parent).parentNode.removeChild(document.querySelector(current.parent));
delete addresses[keys[i]];
}
let addresses = {
'#years_at_address_0': { /* The default one */
elm: document.querySelector('#years_at_address_0'),
value: 0,
parent: '#previousAddress',
added: false
}
};
function setupAddressChecking(watch)
{
if (addresses[watch] === undefined) {
addresses[watch] = {
elm: document.querySelector(watch),
value: 0,
parent: '#previousAddress' + (Object.keys(addresses).length > 0 ? Object.keys(addresses).length : ''),
added: false
};
}
let count = Object.keys(addresses).length;
addresses[watch].elm.addEventListener('change', function() {
if (this.value && addresses[watch].value !== this.value) {
addresses[watch].value = parseInt(this.value);
if (calculateYears() && !addresses[watch].added) {
document.querySelector('#yearsAdditional').appendChild(createNewAddress());
addresses[watch].added = true;
setupAddressChecking('#years_at_address_'+count);
}
}
});
}
function calculateYears()
{
let count = 0;
let remove = false;
const keys = Object.keys(addresses);
for(var i = 0; i < keys.length; i++) {
let current = addresses[keys[i]];
count += current.value;
if (count > 3) {
remove = true;
current.added = false;
document.querySelector(current.parent).parentNode.removeChild(document.querySelector(current.parent));
delete addresses[keys[i]];
}
}
if (count === 3) {
return false;
}
return !remove;
}
function createNewAddress()
{
let count = Object.keys(addresses).length;
return createHTML({
0: { elm: createElement('div', {'id': 'previousAddress' + count}), root: null },
1: { elm: createElement('div'), root: 0 },
2: { elm: createElement('div'), root: 1},
3: { elm: createElement('label', {'for': 'previous_address', 'text': 'Address'}), root: 2},
4: { elm: createElement('div'), root: 1},
5: { elm: createElement('textarea', {
'cols': 40,
'id': 'previous_address' + count,
'name': 'finprop_previous_address',
'placeholder': 'Previous Address',
'rows': 4
}), root: 4},
6: { elm: createElement('div'), root: 1},
7: { elm: createElement('div', { 'id': 'previous_row_postcode' + count}), root: 0 },
8: { elm: createElement('div'), root: 7 },
9: { elm: createElement('label', {'for': 'previous_postcode', 'text': 'Postcode *'}), root: 8 },
10: { elm: createElement('div'), root: 7 },
11: { elm: createElement('input', {
'id': 'previous_postcode' + count,
'name': 'previous_postcode',
'placeholder': 'Postcode',
'type': 'text',
'maxlength': 8
}), root: 10 },
12: { elm: createElement('div'), root: 7 },
13: { elm: createElement('div', {'id': 'row_months_years_at_address' + count}), root: 0 },
14: { elm: createElement('div'), root: 13 },
15: { elm: createElement('label', {'for': 'years_at_address_' + count, 'text': 'How long at address *'}), root: 14 },
16: { elm: createElement('div'), root: 13 },
17: { elm: createElement('div'), root: 16 },
18: { elm: createElement('input', {
'id': 'years_at_address_' + count,
'maxlength': 2,
'min': 0,
'name': 'finprop_years_at_address',
'placeholder': 'Years',
'size': 4,
'type': 'text',
'class': 'years_at_address'
}), root: 17 },
19: { elm: createElement('div'), root: 16 },
20: { elm: createElement('input', {
'id': 'months_at_address_' + count,
'maxlength': 2,
'min': 0,
'name': 'finprop_months_at_address',
'placeholder': 'Months',
'size': 4,
'type': 'text'
}), root: 19 },
21: { elm: createElement('div'), root: 13 }
})[0].elm;
}
function createHTML(elements)
{
let keys = Object.keys(elements);
for (var i = 0; i < keys.length; i++) {
if (elements[keys[i]].root === null || elements[keys[i]].root === i) {
continue;
}
elements[elements[keys[i]].root].elm.appendChild(elements[keys[i]].elm);
}
return elements;
}
function createElement(type, options)
{
let elm = document.createElement(type);
if (options) {
for(var i = 0; i < Object.keys(options).length; i++) {
let key = Object.keys(options)[i];
if (key === 'text') {
elm.innerHTML = options[key];
continue;
}
elm.setAttribute(key, options[key]);
}
}
return elm;
}
setupAddressChecking('#years_at_address_0');
fieldset > div {
padding: 10px;
margin: 5px;
background: whitesmoke;
border: 1px solid lightgray;
}
<fieldset>
<h3>Address Details * denotes a required field</h3>
<div>
<div id="previousAddress0">
<div>
<div><label for="previous_address0">Address</label></div>
<div><textarea cols="40" id="previous_address0" name="finprop_previous_address0" placeholder="Previous Address" rows="4"></textarea></div>
<div></div>
</div>
<div id="previous_row_postcode0">
<div><label for="previous_postcode0">Postcode *</label></div>
<div><input id="previous_postcode0" name="previous_postcode0" placeholder="Postcode" type="text" maxlength="8">
</div>
<div></div>
</div>
<div id="row_months_years_at_address0">
<div><label for="years_at_address_0">How long at address *</label></div>
<div>
<div><input id="years_at_address_0" maxlength="2" min="0" name="finprop_years_at_address0" placeholder="Years" size="4" type="text" class="years_at_address0"></div>
<div><input id="months_at_address_0" maxlength="2" min="0" name="finprop_months_at_address0" placeholder="Months" size="4" type="text"></div>
</div>
<div></div>
</div>
</div>
</div>
<div id="yearsAdditional"></div>
</fieldset>
将HTML与循环相乘。在循环中是您所需的HTML。在循环之前设置一个if语句。
使用el.innerHTML = ""
进行重置。
let result = document.getElementById("result");
function createHTML(n, text) {
let res = "";
if (n < 4) {
for (let i = 0; i < n; i += 1) {
// Add your own HTML
res += `<form id="form-${i + 2}">`;
res += `<ul>`;
res += `<li><textarea></textarea></li>`;
res += `<li><span>Year</span><input class="year" type="text"></li>`;
res += `<li><span>Month</span><input class="month" type="text"></li>`;
res += `</ul>`;
res += `</form>`;
}
}
return res;
}
function multiply(n) {
result.innerHTML = "";
result.innerHTML = createHTML(n, "Heading");
}
form[id^="form-"] {
border: 1px solid lightgrey;
padding: 15px;
background: whitesmoke;
margin: 15px 0;
}
form[id^="form-"] ul {
list-style: none;
padding: 0;
}
<!-- First form -->
<form id="form-1">
<ul>
<li><textarea></textarea></li>
<li><span>Year</span><input class="year" type="text"></li>
<li><span>Month</span><input class="month" type="text"></li>
</ul>
<input type="text" onkeyup="multiply(this.value)">
</form>
<div id="result"></div>