Search code examples
javascriptjqueryhtmlmaterialize

jQuery Clone Then InsertAfter Cloning Numerous Times


I'm trying to create a dynamic form to demonstrate to a business partner.

The goal is to be able to add select elements as necessary when the button is clicked. However, when it's clicked it duplicates the template twice, not just once.

Here are just a few of the variations of the code I've tried and here is the JSFiddle:

$("#serviceTemplate").eq(0).clone().insertAfter(".serviceField:last");

$("#serviceTemplate").clone().insertAfter(".serviceField:last");

$("#serviceTemplate").eq(0).clone().insertAfter($(".serviceField").last());

Solution

  • The idea is simple since you are using $('select').material_select(); to initiate all select element (therefore it is unique and clone it might have some unexpected issue).

    Solution:

    1. When you click ADD call $('select').material_select('destroy'); to destroy and get the original element
    2. now you can clone it and append
    3. initiate all select use $('select').material_select();

    (Note: since the clone will also copy the id="serviceTemplate" it is a bad practice since id should be unique. Remove the id and use something like $(".serviceField").first() to target the original element.)

    $(document).ready(function() {
      $('select').material_select();
    });
    
    $("#addBtn").click(function() {
      $('select').material_select('destroy');
      $(".serviceField").last().after($(".serviceField").first().clone());
      $('select').material_select();
    });
    * {
      -webkit-box-sizing: border-box;
      -moz-box-sizing: border-box;
      -ms-box-sizing: border-box;
      box-sizing: border-box;
    }
    
    html,
    body {
      margin: 0;
      padding: 0;
      min-width: 100%;
      width: 100%;
      max-width: 100%;
      min-height: 100%;
      height: 100%;
      max-height: 100%;
    }
    
    form {
      padding: 2rem 0;
    }
    
    nav li a {
      padding: 0 .65rem;
    }
    
    nav,
    #search {
      background: #eee !important;
    }
    
    .brand-logo h4 {
      color: #444;
    }
    
    .brand-logo:before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 99;
    }
    
    #table {
      display: none;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/css/materialize.min.css" rel="stylesheet" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/js/materialize.min.js"></script>
    
    <div class="container">
      <div class="row">
        <form name="demo" id="demo" class="row">
          <div class="row">
            <div class="input-field col s12 m4">
              <input type="text" class="validate" placeholder="Your name..." />
              <label for="name">Full Name</label>
            </div>
    
            <div class="input-field col s12 m4">
              <input type="text" class="validate" placeholder="mm/dd/yyyy" required/>
    
              <label>Desired Appointment Date</label>
            </div>
          </div>
    
          <div class="row serviceField">
            <div class="input-field col s12 m3">
    
              <select class="service" required>
    							<option value="" disabled selected>-Please Select Service-</option>
    							<option value="1" data-cost="90">Virus Removal - $90</option>
    							<option value="2" data-cost="20">PC Tune-Up - $20</option>
    					</select>
    
              <label>Service Required</label>
            </div>
          </div>
    
    
    
          <div class="row">
            <div class="input-field col s12 m3">
              <div id="addBtn" class="btn black white-text">Add Another Service</div>
            </div>
          </div>
        </form>
      </div>
    </div>