1

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.

BottyZ
  • 145
  • 2
  • 10
  • Please post necessary `css` and `js` you have now to show step by step controls.. – Guruprasad J Rao May 17 '16 at 12:48
  • I would wrap that part of the form in a div and then you could just clone it and append when you click the add another button - I would pass through an array rather than changing the name of the cloned inputs as you would have to rename them all when one is removed (you may need default values for the optional fields). [See this for multiple value with the same name](http://stackoverflow.com/questions/7880619/multiple-inputs-with-same-name-through-post-in-php) – Pete May 17 '16 at 13:24
  • @Pete, Sure I can do the array instead, the processing is coded in php anyway so thats not an issue. I guess that way I'd also be able to regurgitate the values back into the form if there was an error too. – BottyZ May 17 '16 at 13:27

2 Answers2

1

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 = 11;
  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);
    var last_div_id_num = parseInt(last_div.attr("id").replace( /^\D+/g, '')); 

    //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.val("");
        new_serial_div.hide();
        new_licensekey.val("");
        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();
      }else{
        new_licensekey.val("");
        new_licensekey_div.hide();  
          
      }
    });
    
    new_serial.on("change", function(){
      if(new_serial.val().length == 0){
        new_licensekey.val("");        
        new_licensekey_div.hide();  
      }
    });
    
    /*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" />
Chintan
  • 773
  • 9
  • 18
  • Thanks so much for spending time on creating this code snippet. I've been working on some code myself and I've figured some of the basics out but got stuck at the appending the id numbers onto the divs. I'll edit my post above to show where I got to. – BottyZ May 18 '16 at 09:14
  • The problem I still have with yours above is the lack of being able to remove a system if it was added accidentally or no longer required. I also want to limit it to a maximum of six systems. I have setup code with a limit of six and also that removes the parent div of the system the remove button is next too but I can't then get it to find the id of the one removed to re-use if someone were to add another system again. I'll add my edited code above, to see what you think. Its a bit rudimentary I must admit, so hopefully you'll be able to see where I can improve/where I've gone wrong! – BottyZ May 18 '16 at 09:17
  • @BottyZ edited the answer with remove button logic and max 6 systems allowed. Let me know if there is anything – Chintan May 18 '16 at 11:58
  • thanks for having a go at revising. Your version seems much more sophisticated than mine already! Is there anyway to have the remove link appear as soon as another system is added? As currently, it only appears if you enter values in both the serial and license key boxes for the system just added. If a user doesn't enter any input in the serial and license boxes, they cannot remove the additional system. – BottyZ May 18 '16 at 12:09
  • I'm also assuming I would need to perform input verification via javascript instead of php for this form, otherwise everything would hide again upon an error during post submit, such as not entering a serial number in the serial box. – BottyZ May 18 '16 at 12:10
  • @BottyZ Now remove button is shown immediately after the div is added – Chintan May 18 '16 at 12:14
  • @BottyZ Input verification can be done. In fact, using HTML5 validation would prevent a blank serial box. If you need more sophisticated validation, you may use the jQuery validation plugin too. – Chintan May 18 '16 at 12:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/112289/discussion-between-chintan-and-bottyz). – Chintan May 18 '16 at 12:23
0

You can follow below steps.
1) You have to make a clone.
2) then if you want to delete any item then you have to delete on the behalf of $(this) in jquery.

HTML Part

                    <div class="row">
                       <div class="col-sm-12 key_expertise">
                          <div class="mdl-textfield mdl-js-textfield">
                             <input class=mdl-textfield__input name="profileExperience" id="" placeholder="Key Expertise">
                          </div>
                          <div class="mdl-textfield mdl-js-textfield">
                             <input class=mdl-textfield__input name="experienceYear" id="" placeholder="Key Expertise">
                          </div>
                          <div class="mdl-textfield mdl-js-textfield marginRight_none">
                             <input class=mdl-textfield__input name="experienceYear" id="" placeholder="Key Expertise">
                          </div>
                       </div>
                    </div>

                    <div class="row">
                       <div class="col-sm-12 input_add_delete first">
                          <div class="mdl-textfield mdl-js-textfield">
                             <input class=mdl-textfield__input name="profileExperience" id="" placeholder="Experience">

                          </div>

                             <div class="mdl-textfield mdl-js-textfield">
                                <input class=mdl-textfield__input name="experienceYear" id="" placeholder="Year">
                             </div>


                             <div class="mdl-textfield mdl-js-textfield">
                                <input class=mdl-textfield__input name="experienceTitle" id="" placeholder="Title">
                             </div>

                             <div class="mdl-textfield mdl-js-textfield">
                                <input class=mdl-textfield__input name="experienceCountry" id="" placeholder="Country">
                             </div>

                           <div class="add_input">
                             <a href="javascript:void(0);"> Add  <i class="zmdi zmdi-plus-circle zmdi-hc-fw"></i></a>
                          </div>
                          <div class="delete_input">
                             <a href="javascript:void(0);">Delete<i class="zmdi zmdi-minus-circle zmdi-hc-fw"></i></a>
                          </div>
                       </div>




                    </div>

                    <div class="row">
                    <div class="col-sm-12">
              <div class="text-right">
                <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect btn-highlight btn-default btn-submit" data-upgraded=",MaterialButton,MaterialRipple">Save  <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></button>
              </div>
            </div>
            </div>  



JQuery

$('.add_input').click(function(){
                 $(this).parents('.input_add_delete').clone(true, true).removeClass('first').insertAfter($(this).parents('.input_add_delete')).find("input").val("").siblings('label').remove(); 

              });                 

              $('.input_add_delete input').focus(function(){
                 $(this).parent('.mdl-textfield').addClass('is-dirty'); 
              });

              $('.delete_input').click(function(){
                 $(this).parents('.input_add_delete').remove();                        
              });

See Demo

  • thanks for your input. I'm struggling to see how yours will do what I need? I'm not sure if I'm just being a bit stupid? – BottyZ May 18 '16 at 12:11
  • Above mentioned code will fulfill your requirement for sure you can see demo http://www.ui-designer.in/aadi/profile-input-without-header here. Just click on plus icon – Ritesh Narang May 18 '16 at 12:25