Search code examples
jquerycheckboxtoggleclonebootstrap-switch

Bootstrap Toggle for Checkbox adding extra div


We have a form where users can create a shipping type by entering a name in a text field and optionally toggle a checkbox. To add another shipping type, we use jQuery's clone method to rebuild the fields one or more times.

My goal is to change the checkbox into a toggle using bootstrap-toggle. This works fine for the first toggle, but subsequent sets of cloned fields fail.

I've stripped down my initial code to the most basic example to try to get this to function to no avail:

<div id="shipping_fields" class='shipping_fields'>
    <input id="shippings_hide_1" name="shippings1[hide][]" type="checkbox" value="0" data-toggle="toggle" class="hidden">
</div>
<span class='go indent padbot instruction clear'><a href="#" id="add_shipping_button"><i class='fa fa-plus-circle'></i> Add Another Shipping Option</a></span>

<script type="text/javascript">
  function addShippingToPage(event) {
    event.preventDefault();
    $('#shipping_fields').clone().show().
      removeAttr('id').
      insertAfter('.shipping_fields:last')
  }
  function removeShippingFields() {
    $('#shipping_fields_template').remove()
  }
  jQuery("#add_shipping_button").click(addShippingToPage);
  jQuery("#new_event").submit(removeShippingFields);
</script>

Bootstap-toggle converts my checkbox to look like this on page load, and the toggle works fine:

<div id="shipping_fields" class="shipping_fields">
    <div class="toggle btn btn-default off" data-toggle="toggle" style="width: 58px; height: 34px;">
        <input id="shippings_hide_" name="shippings[hide][]" type="checkbox" value="0" data-toggle="toggle" class="hidden">
        <div class="toggle-group">
            <label class="btn btn-primary toggle-on">On</label>
            <label class="btn btn-default active toggle-off">Off</label>
            <span class="toggle-handle btn btn-default"></span>
        </div>
    </div>
</div>

When I add another field using my addShippingToPage function, the cloned HTML looks exactly the same. However, when I attempt to toggle the button, it ends up creating an entire copy of the preceding bootstrap-toggle code inside the first opening div, and of course the toggle fails to move.

I have tried everything I can think of -- including trying Boostrap-switch which simply fails using clone, and renaming the classes and IDs to ensure differentiation -- but I cannot get this to work. Any guidance is appreciated!


Solution

  • The problem is that Bootstrap is generating a new "bootstrap-toggle" code inside of the one already existed. So, you need to clone your div without "bootstrap-toggle" code, and then add to it through jquery.

    Your input should be a normal checkbox (without data-toggle="toggle"):

    <input id="shippings_hide_1" name="shippings1[hide][]" type="checkbox" value="0" class="hidden">
    

    And your addShippingToPage function should bring "bootstrap-toggle" code to your new checkbox.

    function addShippingToPage(event) {
      event.preventDefault();
      $('#shipping_fields').clone().show().
         removeAttr('id').
         insertAfter('.shipping_fields:last');
      $("input:last").bootstrapToggle(); // This will add "bootstrap-toggle" only to the last checkbox.
    }