Sarah
Sarah

Reputation: 67

Change web form elements if number changes

I've got a web form which will add in questions based on the number that the user ticks (ie in the drop down box they enter that they have 5 children, it add in questions for each of those 5 children.)

I can get it to dynamically add in the required number of fields when you first click it, but how would I go about making it update if they chose a different number of children later?

I have my function set out as below:

HTML

<label for="kids" class="kidsno">Number of children</label>
<select type="number" id="kids" class="kidsno" required onchange="KidsInfo()">
    <option value="0">0</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
</select>

JavaScript

function KidsInfo() { 
    var num = $('#kids').val(); 
       inum = parseInt(num); 
       var $name = $('<ul class="flex-outer"> <li> <label for="kidfirst">First Name *</label><input type="text"' + 
                    ' id="kidfirst" name="kidfirst" placeholder="Enter first name here" required></li> ' + 
                    ' <li> <label for="kidlast">Last Name *</label><input type="text"id="kidlast" name="kidlast" ' + 
                    ' placeholder="Enter last name here" required></li> ') 
       var $age = $('<ul class="flex-outer"><li> <label for="childDOB">Date of Birth *</label>' + 
                    ' <input type="date" id="ChildDOB" name="dateofbirth"> </li><li><label for="kidgen">Gender *</label>' + 
                    '   <input list="gender" id="gen" name="gender" placeholder="Enter or select gender here" required> ' + 
                    '<datalist id="gender"><option value="Male"><option value="Female"> <option value="Prefer not to say"> </datalist></li><br/>') 
        
       $("<legend>Children's Information</legend>").appendTo($(".children")); 
        
    for (i=0; i < inum; i++) { 
        
        $name.add($age).clone().appendTo($(".children")); 
    } 
    $("</ul>").appendTo($(".children")); 
} 

Upvotes: 1

Views: 104

Answers (2)

arbuthnott
arbuthnott

Reputation: 3819

I think what you need is for one onchange method to handle everything: both increases and decreases to the number of child records needed.

I'm guessing at your form structure, but the method below should be the right idea. It adds/removes child records to the DOM as needed, and doesn't overwrite existing ones (losing input data) if they will still show. It also uses a .show/.hide to handle updates back to zero, and an outer container for child input data pre-exists in the form.

function KidsInfo() { 
    var num = $('#kids').val(); 
       inum = parseInt(num); 
       var $name = $('<ul class="flex-outer"> <li> <label for="kidfirst">First Name *</label><input type="text"' + 
                    ' id="kidfirst" name="kidfirst" placeholder="Enter first name here" required></li> ' + 
                    ' <li> <label for="kidlast">Last Name *</label><input type="text"id="kidlast" name="kidlast" ' + 
                    ' placeholder="Enter last name here" required></li> ');
       var $age = $('<ul class="flex-outer"><li> <label for="childDOB">Date of Birth *</label>' + 
                    ' <input type="date" id="ChildDOB" name="dateofbirth"> </li><li><label for="kidgen">Gender *</label>' + 
                    '   <input list="gender" id="gen" name="gender" placeholder="Enter or select gender here" required> ' + 
                    '<datalist id="gender"><option value="Male"><option value="Female"> <option value="Prefer not to say"> </datalist></li><br/>');
      var $childform = $('<div class="childdata"></div>').append($name).append($age);
      
      // first remove extra records if they are there
      $('.childdata').each(function(i, elem) {
          if (i >= inum) {
              $(elem).remove();
          }
      });
      
      // now add records if necessary
      var existing = $('.childdata').length;
      for (var i = existing; i < inum; i++) {
          $('.children').append($childform.clone());
      }
      
      // now show/hide as appropriate
      if (inum > 0) {
          $('.children').show();
      } else {
          $('.children').hide();
      }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="kids" class="kidsno">Number of children</label>
<select type="number" id="kids" class="kidsno" required onchange="KidsInfo()">
    <option value="0">0</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
</select>

<div class="children" style="display: none;">
    <legend>Children's Information</legend>
</div>

Upvotes: 1

Manuel Otto
Manuel Otto

Reputation: 6540

You could rebuild the .children's content each time number of kids is changed:

var name_template = '<ul class="flex-outer"> <li> <label for="kidfirst">First Name *</label><input type="text"' + 
                    ' id="kidfirst" name="kidfirst" placeholder="Enter first name here" required></li> ' + 
                    ' <li> <label for="kidlast">Last Name *</label><input type="text"id="kidlast" name="kidlast" ' + 
                    ' placeholder="Enter last name here" required></li>';

var age_template = '<ul class="flex-outer"><li> <label for="childDOB">Date of Birth *</label>' + 
                    ' <input type="date" id="ChildDOB" name="dateofbirth"> </li><li><label for="kidgen">Gender *</label>' + 
                    '   <input list="gender" id="gen" name="gender" placeholder="Enter or select gender here" required> ' + 
                    '<datalist id="gender"><option value="Male"><option value="Female"> <option value="Prefer not to say"> </datalist></li><br/>'

var legend_template = "<legend>Children's Information</legend>"

function KidsInfo() { 
    var num = $('#kids').val(); 
    inum = parseInt(num);
    var html = ''
    for (i=0; i < inum; i++) { 
        html += '<ul class="flex-outer">'
        html += name_template
        html += age_template
        html += legend_template
        html += '</ul>'
    }
    $(".children").html(html)
}

Upvotes: 0

Related Questions