Search code examples
jqueryhtmlclone

Jquery cloning and HTML arrays


Building a form to capture dimensions of freight entering a warehouse. The form has a row with four fields: Pieces, Width, Length, Height

At the end of the row is a button to add additional rows if there is more data to capture. i.e. There could be two pieces with one set of dimensions and another 2 pieces with different dimension. No way to know in advance how many rows of data will be captured. I have named the fields pieces[], length[], width[] and height[]

I have two problems.
1. When I use jquery to clone the row it adds 1 row the first time then 2 rows then 4 rows. i.e. it is replicating the new row not just the first row.

  1. When the row is cloned the values move into the new row. As you can see I have tried setting to zero but no effect. How do you manipulate HTML array fields in jquery?
//Add more dimensions if required
    var cloneCount = 0;
   $("#consignment_dimensions_button").click(function(){    
        $( "#consignment_dimensions")
            .clone()       
            .attr('name','consignment_dimensions'+cloneCount++)         
            .prependTo( "#consignment_dimensions" );   

            $('#consignment_dimensions_button:last').remove();
            $('#pieces[]:last').val)(0) 
            $('#length[]:last').val(0);
            $('#width[]:last').val(0);
            $('#height[]:last').val(0);
    });

//end of adding dimensions

and my HTML

    <div class="row" id='consignment_dimensions'>
      <div class="col-15">
        <label for="dims">Dimensions</label>
      </div>
      <div class="col-10">
        <input type="text" id="pieces[]" name="pieces[]" maxlength ="6" placeholder="Pieces">
      </div>

      <div class="col-15">
        <input type="text" id="length[]" name="length[]" maxlength ="6" placeholder="Length">
      </div>  

      <div class="col-15">
        <input type="text" id="width[]" name="width[]" maxlength ="6" placeholder="Width">
      </div>  

      <div class="col-15">
        <input type="text" id="height[]" name="height[]" maxlength ="6" placeholder="Height">
      </div>
         <div class="col-10">   
          <input type="button" class="my-button" name="consignment_dimensions_button" id="consignment_dimensions_button" value="Add more dims">  

          </div>    
      </div>

Solution

  • The first issue is because you prepend the clone() back in to the element you cloned from, hence the next time you clone it contains the original fields, plus all those previously prepended. To fix this prepend the content to a parent element of #consignment_dimensions. In the example below I used #container.

    Secondly, val(0) isn't working for you because the [ and ] characters have a special meaning in a selector and you need to escape them with \\ - although you're duplicating these id so I'd suggest removing this logic and replacing it with a class instead.

    That being said there's several other issues.

    • You're duplicating a lot of id attributes which need to be unique. In this case I'd suggest removing the id completely from all the elements and just using classes.
    • Instead of removing the button of each cloned set, just keep the button outside of the cloned HTML.
    • Your use of :last is invalid given that you're prepending content, so it will go to the start of the container. With the above amendments to the classes/ids it's redundant anyway.
    • Call removeAttr('id') on the clone to prevent duplicating its id

    $("#consignment_dimensions_button").click(function() {
      var $clone = $("#original.consignment_dimensions").clone().removeAttr('id').prependTo("#container");
      $clone.find('.pieces, .length, .width, .height').val(0);
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="container">
      <div class="row consignment_dimensions" id="original">
        <div class="col-15">
          <label for="dims">Dimensions</label>
        </div>
        <div class="col-10">
          <input type="text" class="pieces" name="pieces[]" maxlength="6" placeholder="Pieces">
        </div>
        <div class="col-15">
          <input type="text" class="length" name="length[]" maxlength="6" placeholder="Length">
        </div>
        <div class="col-15">
          <input type="text" class="width" name="width[]" maxlength="6" placeholder="Width">
        </div>
        <div class="col-15">
          <input type="text" class="height" name="height[]" maxlength="6" placeholder="Height">
        </div>
      </div>
      <input type="button" class="my-button" name="consignment_dimensions_button" id="consignment_dimensions_button" value="Add more dims">
    </div>