Yograj Gupta
Yograj Gupta

Reputation: 9869

How to make all div draggable with in a parent container

There is a div with id parentDiv, and there are some div with class block1 in parentDiv divl

like

<div id="btn"><input name="click" type="button" value="Click" class='button" /></div>

<div id="parentDiv">
    <div class="block1" style=" width:100px; height:100px; background:orange;">I am Block1</div>
    <div class="block1" style=" width:100px; height:100px; background:orange;">I am Block1</div>
</div>

and In JQuery, div with class block1, are draggable.

$(function(){
    $('.block1').draggable({
        drag: function() {
           $('.block1').text('Drag Now!');
        },
        stop: function() {
           $('.block1').text('Stop Now!');
        }
    });
});

These div are working as aspect, but the problem is, if any new div with block1 is appended in the parentDiv by clicking on btn input like

$('#btn').on('click', 'input.button', function(){
    var $newDiv=$('<div class="block1" style=" width:100px; height:100px; background:green;">I am Block1</div>');
});

that is not draggable.

Yes, It will not work, because it was not in DOM.

We are able to define a click event on #btn div to its children input.button, and if we add new input with class button in this #btn div, all will work as aspect.

So my question is, Is there a way to make all div draggable with in a parent container parentDiv, like we can do with #btn div?

Upvotes: 5

Views: 4877

Answers (4)

$('#maindiv div").draggable({container:"#maindiv",scroll:false}) 

and now you can do what ever you want

Upvotes: -1

Stuart Wakefield
Stuart Wakefield

Reputation: 6414

You can use the jQuery on method with the mouseover event to bind uninitialized draggable children:

$(".parentDiv").on("mouseover", ".block1", function() {

    // Use the UI pseudo-selector to check that
    // it is not already draggable
    if(!$(this).is(":ui-draggable"))
        $(this).draggable({
            /* Options */
        });
});

For convenience, wrapped in a function that extends jQuery:

$.fn.extend({

    /**
     * Children of the element with the given selector
     * will automatically be made draggable
     * @param {String} selector
     *  The selector of the child / descendant elements
     *  to automatically be made draggable
     * @param {Object} opts
     *  The options that would normally be passed to the
     *  draggable method
     * @returns
     *  The jQuery array for chaining
     */
    draggableChildren: function(selector, opts) {

        // On using event delegation to automatically
        // handle new child events
        $(this).on("mouseover", selector, function() {

           // Check that draggable not already initialized
           if(!$(this).is(":ui-draggable"))

               // Initialize draggable
               $(this).draggable(opts);
        });

        // Return this for chaining
        return this;
    }
});

You can use this as follows:

$(".parentDiv").draggableChildren(".block1", {
    drag: function() {
        $(this).text('Drag Now!');
    },
    stop: function() {
        $(this).text('Stop Now!');
    }
});

Here is a fiddle showing it in action

Upvotes: 5

Shyju
Shyju

Reputation: 218722

You need to set the containment property to parent to restrict the area.

$("#yourItem" ).draggable({ containment: "parent" });

To enable draggable for the new dynamic item, what you can do is, move the code which binds the draggablity feature to a method and call that method after you add new item to the DOM

 function BindDraggable()
 {
    $('.block1').draggable({
        drag: function() {
           $('.block1').text('Drag Now!');
        },
        stop: function() {
           $('.block1').text('Stop Now!');
        },
        containment: 'parent'
    });
 }

Now call it on document ready and soon after you add new content

$(function(){
  BindDraggable();

  $('#btn').on('click', 'input#button', function(){
    var $newDiv=$('<div class="block1" style=" width:100px; height:100px; background:green;">I am Block1</div>');
    //to do :attach the new item to the DOM

    BindDraggable();
});

});

Upvotes: 1

Carlos Martinez T
Carlos Martinez T

Reputation: 6528

You need to use the "live" function of jquery to add events and functions on future elements.

This code is borrowed from another post (http://stackoverflow.com/questions/1805210/jquery-drag-and-drop-using-live-events)

(function ($) {
   $.fn.liveDraggable = function (opts) {
      this.live("mouseover", function() {
         if (!$(this).data("init")) {
            $(this).data("init", true).draggable(opts);
         }
      });
      return $();
   };
}(jQuery));

Now instead of calling it like:

$(selector).draggable({opts});

...just use:

$(selector).liveDraggable({opts})

Upvotes: 2

Related Questions