添加HTML直到达到要求

问题描述 投票:0回答:2

我正在尝试创建一个表单,在该表单中,我需要用户添加至少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>
javascript html
2个回答
0
投票

每次迭代时,您都将当前框添加到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>

0
投票

提示

将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>
© www.soinside.com 2019 - 2024. All rights reserved.