skip to Main Content

I have created a form that contains two drop-down lists, when the user selects an item from the first list, the data for the second is automatically updated. I use jquery to do this and it works perfectly except that when I duplicate the form, the drop-down list N ° 1 of the duplicated form no longer updates the drop-down list N ° 2 so I would like to know how can I perform the same action on a cloned form (update a drop-down list by selecting one entered in another) and save the entries of all the cloned forms in a database.

Cordially!

here is the code i use

<form id="myForm">
 <div id="clonedSection1" class="clonedSection">    
  <select class="form-control" name="productName[]" id="productName" >
   <option value="0" selected>Selectionner le produit</option>
   <option value="copy">Copie</option>
   <option value="scan">Scan</option>
  </select>
  <select class="form-control" name="productPrice[]" id="quant" disabled>
   <option value="pu" selected>P.U</option>
  </select>
</div>
<div>
 <input type="button" id="btnAdd" value="add another name" />
 <input type="button" id="btnDel" value="remove name" />
</div>

<!-- script that allows you to modify the data in a drop-down list when an item is selected in another-->
<script type="text/javascript">
 $("#productName").change(function () {
  var val = $(this).val();
  if (val == "copy") {
  $("#quant").html("<option value='25'> 25$ </option>");
 } else if (val == "scan") {
  $("#quant").html("<option value='50'> 10$ </option>");
 }
});
</script>

<!-- script that clones the form-->
<script type="text/javascript">
 $(document).ready(function() {
 $("#btnAdd").click(function() {
  var num = $(".clonedSection").length;
  var newNum  = new Number(num + 1);

  var newSection = $("#clonedSection" + num).clone().attr("id", "clonedSection" + newNum);
  newSection.children(":nth-child(5)").children(":first").attr("id", "productName" + newNum).attr("name", "productName[]" + newNum);
  newSection.children(":nth-child(6)").children(":first").attr("id", "quant" + newNum).attr("name", "productPrice[]" + newNum);

  $(".clonedSection").last().append(newSection)
  $("#btnDel").attr("disabled","");

  });
  $("#btnDel").click(function() {
  var num = $(".clonedSection").length; // how many "duplicatable" input fields we currently have
        $("#clonedSection" + num).remove();     // remove the last element

        // enable the "add" button
        $("#btnAdd").attr("disabled","");

        // if only one element remains, disable the "remove" button
        if (num-1 == 1)
            $("#btnDel").attr("disabled","disabled");
    });

    $("#btnDel").attr("disabled","disabled");
  });
</script>

2

Answers


  1. There are some minor problems of your code:

    • Use classname instead of id for DOM elements that going to be cloned.
      It is because id is unique. Different elements should not share the
      same id. If you clone an element with id, there would be elements
      sharing the same id.
    • Use .on() instead of .change() for elements that generate
      dynamically.
    • I’m not sure if you really want to insert a new “clonedSection”
      inside the last “clonedSection”. If you are not going to do this and
      would like to insert new “clonedSection” right after the last
      “clonedSection”, use
      newSection.insertAfter($(".clonedSection").last());
    • value of .attr("disabled", <>) should be either true or false, but not "" and disabled
    $(document).ready(function() {
    
    	//use on() instead of change() for elements that generate dynamically
      $("body").on("change", ".productName", function() { 
        var _this = $(this);
        var quant = _this.closest(".clonedSection").find(".quant");
        var val = _this.val();
        if (val == "copy") {
          quant.html("<option value='25'> 25$ </option>");
        } else if (val == "scan") {
          quant.html("<option value='50'> 10$ </option>");
        }
      });
      
      $("#btnAdd").click(function() {
        var num = $(".clonedSection").length;
        var newNum = num + 1;
    
        var newSection = $("#clonedSection" + num).clone().attr("id", "clonedSection" + newNum);
        newSection.children(":nth-child(5)").children(":first").attr("id", "productName" + newNum).attr("name", "productName[]" + newNum);
        newSection.children(":nth-child(6)").children(":first").attr("id", "quant" + newNum).attr("name", "productPrice[]" + newNum);
    
    		newSection.insertAfter($(".clonedSection").last()); //insert right after the last clonedsection
        $("#btnDel").attr("disabled", false); //disabled should be either true/false but not ""
    
      });
      $("#btnDel").click(function() {
        var num = $(".clonedSection").length;
        $("#clonedSection" + num).remove();
        $("#btnAdd").attr("disabled", false);
        if (num - 1 == 1)
          $("#btnDel").attr("disabled", true);
      });
    
      $("#btnDel").attr("disabled", true);
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <form id="myForm">
    <!--If you are going to clone DOM element, please use classname instead of id-->
     <div id="clonedSection1" class="clonedSection">   
      <select class="form-control productName" name="productName[]">
       <option value="0" selected>Selectionner le produit</option>
       <option value="copy">Copie</option>
       <option value="scan">Scan</option>
      </select>
      <select class="form-control quant" name="productPrice[]">
       <option value="pu" selected>P.U</option>
      </select>
    </div>
    <div>
     <input type="button" id="btnAdd" value="add another name" />
     <input type="button" id="btnDel" value="remove name" />
    </div>

    Hope this help 😀

    Login or Signup to reply.
  2. I have written simple and clean code.

    Follow below steps:

    1. Don’t use ID so you need to use class name instead of id because of ID should be unique.
    2. If appending dynamically element then need to use .on() instead of .change() method.
    3. .cloned-section section should be separate from Add Button.
    4. Each time pick clone element by .cloned-section>div:nth-child(1) this nth-child method.
    5. Set value in input field by onchange .product-name class.
    6. Remove element by onclick .btn-remove class.
    7. When append clone element by append() method then select+input values need to set null so you can see in my jQuesy code and also see commented text.

    I hope below snippet will help you lot.

    $(document).on('click', '#btnAdd', function(){
      // Make clone by clone() method and append REMOVE button for remove section
      var cloneElement = $('.cloned-section>div:nth-child(1)').clone();
          cloneElement.append('<button type="button" class="btn btn-danger btn-remove"><span aria-hidden="true">&times;</span></button>');
      // Select value set Zero (0)
      cloneElement.find('select').val(0);
      // Input value set empty
      cloneElement.find('input').val('');
      $('.cloned-section').append(cloneElement);
    });
    
    // On change product name then set price on price field
    $(document).on('change', '.product-name', function(){
      var getValue = $(this).val();
      $(this).parent().find('.product-price').val(getValue+'%');
    });
    
    // Click on Remove button and delete product/price section
    $(document).on('click', '.btn-remove', function(){
      $(this).parent().remove();
    });
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    
    <div class="container my-2">
      <div class="row">
        <div class="col-sm-12">
          <form class="form-inline" id="myForm">
            <div class="cloned-section w-100">
              <div class="w-100 mt-2">    
                <select class="form-control w-50 product-name" name="productName[]">
                  <option value="0" selected>Select Product</option>
                  <option value="25">Copy</option>
                  <option value="50">Scan</option>
                  <option value="75">Paste</option>
                  <option value="100">Cut</option>
               </select>
               <input class="form-control w-25 product-price text-center" name="productPrice[]" readonly>
             </div>
           </div>
          <div class="w-100 mt-2">
            <button type="button" id="btnAdd" class="btn btn-success">Add Another Name</button>
          </div>
        </form>
       </div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search