Search code examples
jqueryhtmldraggablejquery-ui-draggable

how to use draggable on javascript appended fields?


I'm using Jquery draggable to create a part of an application that creates inputs, the inputs have to be draggable, in the project below (jsfiddle), you'll see that only the created fields aren't draggable but the one added directly in the html works why ?

https://jsfiddle.net/vtsjwb63/

html :

<div class="input_fields_wrap">
    <button class="add_field_button">Add More Fields</button>

    <div class="draggable ui-widget-content">
         <input type="text" name="mytext[]"/>
         <a href="#" class="remove_field">x</a>
    </div>
</div>

javascript :

$(document).ready(function() {
    var max_fields      = 10; //maximum input boxes allowed
    var wrapper         = $(".input_fields_wrap"); //Fields wrapper
    var add_button      = $(".add_field_button"); //Add button ID

    var x = 1; //initlal text box count
    $(add_button).click(function(e){ //on add input button click
        e.preventDefault();
        if(x < max_fields){ //max input box allowed
            x++; //text box increment
            $(wrapper).append(''
            + '<div class="draggable ui-widget-content added">'
            + '<p>not draggable anymore, why ?</p>'
            + '<input type="text" name="mytext[]"/>'
            + '<a href="#" class="remove_field">x</a>'
            + '</div>'
            ); //add input box
        }
    });

    $(wrapper).on("click",".remove_field", function(e){ //user click on remove text
        e.preventDefault(); $(this).parent('div').remove(); x--;
    })
    $( ".draggable" ).draggable({ grid: [ 5, 5 ], snap: true });
});

How can I fix that ?


Solution

  • The issue is because you only instantiate draggable() on the elements which are in the DOM when the page loads. To make the new elements draggable, you need to call draggable on them after appending them to the DOM. Try this:

    var max_fields = 10; // maximum input boxes allowed
    var wrapper = $(".input_fields_wrap"); 
    var add_button = $(".add_field_button");
    var draggableOptions = { grid: [ 5, 5 ], snap: true }   
    
    $(add_button).click(function(e) {
      e.preventDefault();
      if (wrapper.find('.draggable').length < max_fields) {
        $('<div class="draggable ui-widget-content added">'
          + '<p>not draggable anymore, why ?</p>'
          + '<input type="text" name="mytext[]"/>'
          + '<a href="#" class="remove_field">x</a>'
          + '</div>').appendTo(wrapper).draggable(draggableOptions); // < important change here
      }
    });
    
    $(wrapper).on("click", ".remove_field", function(e) {
      e.preventDefault();  
      $(this).parent('div').remove();
    })
    $(".draggable").draggable(draggableOptions);
    

    Working example