BottyZ BottyZ - 1 year ago 42
Javascript Question

How to use Jquery to add / remove form elements

I'm currently designing / coding a new website for my employer who is a printer manufacturer. Customers can register to download software and manuals via the website.

I want to add a little bit of professionalism to the registration form and wondered if it was possible to do with jQuery. Note: My jQuery knowledge is very limited, but I'm trying to improve one that!

I have jquery, jquery easing and ui all linked in the page.

The part of the form I wish to meddle with looks like this:

html5 form

A customer usually has anywhere between 1 & 6 systems, all with their own serial number and possibly a license key. I'd initially like to just display the select system select box, then once a selection has been made show the serial number box. Then once this has been filled in also, then show the license key box and the 'add another system' button.

Then if a customer has another system, they can click the button and it will add a clone of the first (i.e. add a new select system box to be filled in, before showing the other boxes and another add system button). The only exception, would be that it would probably need a remove button, in case the customer hits add too many times. This new remove button could then be hidden when another system is selected.

So something like so:

jquery dynamic changes

I'd want to limit it to only allowing 6 sets of system details. Each time with a number amended onto the field name.

this section of the current html5 looks like so:

IGNORE THIS NOW UPDATED CODE AT THE BOTTOM (18/5/16)



<hr class="line">
<div class="eleven columns top-2 bottom-2">
<h3 class="title bottom-2">System Details</h3>
<div class="form-box">
<label>System <small>*</small>
</label>
<select name="system">
<option>Select system</option>
<option value="CPM-200">CPM-200</option>
<option value="CPM-100">CPM-100</option>
<option value="CPM-100H">CPM-100H</option>
<option value="CJ Pro">CJ Pro</option>
<option value="CJ-200C">CJ-200C</option>
<option value="CM-200">CM-200</option>
</select>
</div>
<div class="form-box">
<label>Serial Number <small>*</small>
</label>
<input type="text" name="serial1" class="text" required>
</div>
<!-- End Box -->
<div class="form-box">
<label>License Key (if known)</label>
<input type="text" name="license1" class="text" placeholder="e.g. ABCD1-EFGH2-IJKL3-MNOP4-QRST5" value="<?php echo htmlentities(strip_tags($company)); ?>">
</div>
<!-- End Box -->
<div class="form-box">
<a href="#" class="button medium secondary" style="margin-top: 35px; padding: 14px 30px;">Add Another System?</a>
</div>
<!-- End Box -->
</div>
<div class="clearfix"></div>
<input type="submit" value="Register" class="button medium color" />





As you can see, its quite complicated and a big ask! And I am out of my league, so some friendly pointers would be much appreciated.

Thank you.




EDIT 18/5



Please forgive my rudimental jquery code, like I said I'm no expert, but hoping you could all suggest some improvements. At the moment I add the html in as an append to the wrapper using the javascript, as this allows me to remove the systems.

So far I've managed to figure out how to add divs for each system, give them ids and only allow 6 in total. I can also remove systems if they were removed.

What I can't do is:

Show the serial box on more that the first id (as I don't know how to fix an id with a number of x after the name - i.e. system5 to show the serial5 box. Thoughts?

If a customer deletes a box, and then adds a new one, how do I make the new one have the lowest id number available. i.e. if a customer has all six systems, then deletes number 4, if they want to add another system again how do I get it to find that 4 and add a new system4?

Code as it is at the moment:



// Registration form element show / hide function
$(document).ready(function() {
var max_systems = 6; // maximum input boxes allowed
var wrapper = $(".system-wrap"); // Fields wrapper
var add_button = $(".system-button"); // Add button ID

var x = 1; // initial systems count
$(add_button).click(function(e){ // on add button click
e.preventDefault();
if(x < max_systems){ // max systems allowed
x++; // system increment
$(wrapper).append("<div class='system-wrap top-2 bottom-2'>" + "\n" + "<hr class='line bottom-2'>" + "\n" + "<div class='form-box'>" + "\n" + "<label>System <small>*</small></label>" + "\n" + "<select name='system" + x + "'>" + "\n" + "<option value=''>Select system</option>" + "\n" + "<option value='CPM-200'>CPM-200</option>" + "\n" + "<option value='CPM-100'>CPM-100</option>" + "\n" + "<option value='CPM-100H'>CPM-100H</option>" + "\n" + "<option value='CJ Pro'>CJ Pro</option>" + "\n" + "<option value='CJ-200C'>CJ-200C</option>" + "\n" + "<option value='CM-200'>CM-200</option>" + "\n" + "</select>" + "\n" + "</div>" + "\n\n" + "<div class='form-box' id='serial" + x + "'>" + "\n" + "<label>Serial Number <small>*</small></label>" + "\n" + "<input type='text' name='serial" + x + "' id='serialbox" + x + "' class='text' placeholder='e.g. 01234567L or CJP01-1234' value='' required>" + "\n" + "</div><!-- End Box -->" + "\n\n" + "<div class='form-box' id='license" + x + "'>" + "\n" + "<label>License Key (if known)</label>" + "\n" + "<input type='text' name='license" + x + "' class='text' placeholder='e.g. ABCD1-EFGH2-IJKL3-MNOP4-QRST5' value=''>" + "\n" + "</div><!-- End Box -->" + "\n" + "<div class='form-box remove-field'>" + "\n" + "<a href='#' class='button medium secondary' style='margin-top: 38px; padding: 14px 30px;'>Remove?</a>" + "\n" + "</div><!-- End Box -->" + "\n" + "</div>" + "\n\n" + "<div class='clearfix'></div>" + "\n"); // add remove button
}
});

$(wrapper).on("click",".remove-field", function(e){ // user click on remove text
e.preventDefault(); $(this).parent(".sys").remove(); x--;
})
});

$('#system').on('change',function(){
if ($(this).val() != "") {
$('#serial').show();
} else {
$('#serial').hide();
}
} );

$('#serialbox').on("keyup", function(){
if ($(this).val().length > 0) {
$('#license').show();
} else {
$('#license').hide();
}
} );

#serial, #license {
display: none;
}

<div class="eleven columns top-2 bottom-2 system-details">
<h3 class="title bottom-2">System Details</h3>
<p>You may register up to 6 different Lighthouse products below.</p>
<div class="systems top-2">

<div class="system-wrap">
<div class="form-box">
<label>System <small>*</small></label>
<select name="system" id="system">
<option value="">Select system</option>
<option value="CPM-200">CPM-200</option>
<option value="CPM-100">CPM-100</option>
<option value="CPM-100H">CPM-100H</option>
<option value="CJ Pro">CJ Pro</option>
<option value="CJ-200C">CJ-200C</option>
<option value="CM-200">CM-200</option>
</select>
</div>

<div class="form-box" id="serial">
<label>Serial Number <small>*</small></label>
<input type="text" name="serial" id="serialbox" class="text" placeholder="e.g. 01234567L or CJP01-1234" value="" required>
</div><!-- End Box -->

<div class="form-box" id="license">
<label>License Key (if known)</label>
<input type="text" name="license" class="text" placeholder="e.g. ABCD1-EFGH2-IJKL3-MNOP4-QRST5" value="">
</div><!-- End Box -->

<div class="clearfix"></div>

</div><!-- End System Wrap -->
</div><!-- End Systems -->





Thanks all.

Answer

I have made a rudimentary version what you are looking for.

  1. Put the divs that need to be generated in a #wrapper div.
  2. Give the initial div an id div0 and hide it using css
  3. Hide the serial key and license key fields too
  4. As needed (on document ready or on click of Add new system link), generate a new div from div0
  5. Attach event handlers to show serial key and license key fields as needed
  6. Show the generated div

$(document).ready(function() {
  var max_divs = 6;
  var divs_present = 0;

  $("#add-another").click(function(e) {
    //prevent scroll
    e.preventDefault();

    //generate a new div based on div0 and attach the event handlers

    //console.log($("#wrapper :last-child"));
    //get the last generated div
    var last_div = $("div[id^='div']:last");

    //slice off the number at the end of the last div id for example 0 from div0
    var last_div_id_num = last_div.attr("id").slice(-1);

    //console.log($("#wrapper :last-child").attr("id"));
    //add one to the old id number and prefix div to get the id of the new div
    var new_id_num = (parseInt(last_div_id_num) + 1);
    var new_div_id = "div" + new_id_num;

    //clone div0
    var new_div = $("#div0").clone();

    //new_div.show();
    //change the id of the new div as calculated above
    new_div.attr("id", new_div_id);

    //find the system dropdown inside the new div etc
    var new_system = new_div.find(".system");
    var new_serial_div = new_div.find(".serial-div");
    var new_serial = new_div.find(".serial");
    var new_licensekey_div = new_div.find(".licensekey-div");
    var new_licensekey = new_div.find(".licensekey");
    var remove_btn_div = new_div.find(".remove-btn-div");
    var remove_btn = new_div.find(".remove-btn");

    //attach event handler: once system is selected, show the serial number field
    new_system.on("change", function() {
      console.log(new_div.find(".system :selected").text().length);
      if(new_div.find(".system :selected").text().trim() == "Select system"){
        //console.log("Compared");
        new_serial_div.hide();
        new_licensekey_div.hide();
      }else{
        new_serial_div.show(); 
      }
      //console.log("Im here!");
    });


    //attach event handler: once something is entered in the serial number field, show the next field
    new_serial.on("keyup", function() {
      //Please add validation as required here
      //console.log("Im here too!");
      if (new_serial.val().length > 0) {
        new_licensekey_div.show();
      }
    });
    
    /*new_licensekey.on("keyup", function(){
      if(new_licensekey.val().length > 0){
        remove_btn_div.show();  
      }
    });*/

    remove_btn.on("click", function(e){
      //prevent scroll
      e.preventDefault();
      --divs_present;
      new_div.remove();
      if(divs_present<max_divs){
        $("#add-another").show();  
      }
    });
    
    
    //append the new div to the wrapper div
    $("#wrapper").append(new_div);
    //finally, show the new div
    new_div.show();
    
    ++divs_present;
    
    //show the remove button
    if(divs_present>1){
      remove_btn_div.show(); 
    }
    
    if(divs_present==max_divs){
      $("#add-another").hide();  
    }

  });

  //trigger a click to generate the first div
  $("#add-another").trigger('click');
  //$("#system1").trigger('change');

});
.hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<!-- begin snippet: js hide: false -->
<hr class="line">
<div>
  <h3>System Details</h3>
  <div id="wrapper">
    <div id="div0" class="hidden">
      <div>
        <label>System <small>*</small>
        </label>
        <select name="system" class="system">
          <option>Select system</option>
          <option value="CPM-200">CPM-200</option>
          <option value="CPM-100">CPM-100</option>
          <option value="CPM-100H">CPM-100H</option>
          <option value="CJ Pro">CJ Pro</option>
          <option value="CJ-200C">CJ-200C</option>
          <option value="CM-200">CM-200</option>
        </select>
      </div>
      <div class="serial-div hidden">
        <label>Serial Number <small>*</small>
        </label>
        <input type="text" name="serial1" class="serial" required>
      </div>
      <!-- End Box -->
      <div class="licensekey-div hidden">
        <label>License Key (if known)</label>
        <input type="text" name="license1" class="licensekey" placeholder="e.g. ABCD1-EFGH2-IJKL3-MNOP4-QRST5" value="">
      </div>
      <!-- End Box -->
      <div class="remove-btn-div hidden">
        <a href="#" class="remove-btn">Remove</a>
      </div>
    </div>
  </div>
  <div>
    <a href="#" id="add-another">Add Another System?</a>
  </div>
</div>
<!-- End Box -->
<div class="clearfix"></div>
<input type="submit" value="Register" class="button medium color" />