Refresh draggable shell

I have a drag and drop element that contains a restriction as a parent. This works fine, but the contents of the div can change, making it taller. Is there a way to trigger a drag event that ensures that it does not move from its parent. Since right now it can overlap the parent object until it is dragged, and then click on it.

Regards Mark

+6
jquery jquery-ui
source share
3 answers

I have implemented a small plugin that does what you want. It can provide protection after resizing the dragged file, and even works when you are in the middle of the drag and drop. I tested it with jQuery UI 1.8.6 and jQuery 1.4.3, but it may break with past or future versions as it must use internal methods.

Working demo

http://jsbin.com/uvino4/27

Full source code

Plugin

/* * jQuery UI RefreshContainment v0.1 * * A plugin for jQuery UI Draggable. It adds a refreshContainment method to * every draggable which allows you to use the containment option on draggables * with dynamically changing sizes. * * Depends: * jquery.ui.core.js * jquery.ui.widget.js * jquery.ui.mouse.js * jquery.ui.draggable.js */ (function ($){ var $window = $(window); // We need to know the location of the mouse so that we can use it to // refresh the containment at any time. $window.data("refreshContainment", {mousePosition: {pageX: 0, pageY: 0}}); $window.mousemove(function (event) { $window.data("refreshContainment", { mousePosition: {pageX: event.pageX, pageY: event.pageY} }); }); // Extend draggable with the proxy pattern. var proxied = $.fn.draggable; $.fn.draggable = (function (method){ if (method === "refreshContainment") { this.each(function (){ var inst = $(this).data("draggable"); // Check if the draggable is already being dragged. var isDragging = inst.helper && inst.helper.is(".ui-draggable-dragging"); // We are going to use the existing _mouseStart method to take care of // refreshing the containtment but, since we don't actually intend to // emulate a true _mouseStart, we have to avoid any extraneous // operations like the drag/drop manager and event triggering. // So we save the original member values and replace them with dummies. var ddmanager = $.ui.ddmanager; $.ui.ddmanager = null; var trigger = inst._trigger; inst._trigger = function () { return true; } var mousePosition = $window.data("refreshContainment").mousePosition; var fakeEvent = { pageX: mousePosition.pageX, pageY: mousePosition.pageY }; inst._mouseStart(fakeEvent); // Return those extraneous members back to the original values. inst._trigger = trigger; $.ui.ddmanager = ddmanager; // Clear the drag, unless it was already being dragged. if (!isDragging) { inst._clear(); } }); return this; } else { // Delegate all other calls to the actual draggable implemenation. return proxied.apply(this, arguments); } }); })(jQuery); 

HTML demo

 <!DOCTYPE html> <html> <head> <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" /> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script> <meta charset=utf-8 /> <title>JS Bin</title> <style> #container { width: 20em; height: 20em; border: 0.5em solid black; } .draggable { width: 5em; height: 5em; border: 0.2em solid black; position: absolute; } #one { background-color: #F55; } #two { background-color: #5F5; } </style> </head> <body> <div id="container"> <div class="draggable" id="one">drag me</div> <div class="draggable" id="two">drag me</div> </div> </body> </html> 

JavaScript demo

 var draggables = $('.draggable'); draggables.draggable({containment: 'parent', stack: draggables}); var resizeDraggables = function (){ draggables. each(function (){ var size = 5 + Math.random() * 5; size = size.toString() + "em"; $(this).css({width: size, height: size}); }). draggable("refreshContainment"); }; resizeDraggables(); setInterval(resizeDraggables, 2000); 
+10
source share

It works?

 $("#yourcontainment").bind("resizestop", function () { $(".yourdraggables").draggable("option", "containment", $("#yourcontainment")); }); 

You must fire the resizeestop event if you are not using the resizable jQuery UI.

+3
source share

Since you are resizing the [contained] elements, you must implement your own handler for the results. jQuery knows what to do while dragging and dropping, but there are many possible behaviors during resizing:

  • prevent content resizing Element
  • moves internal elements (in which direction)
  • delete items

You can imagine a series of dummy scenarios for different user interface restrictions.

Just create the PostionValidator () method for all objects of the contained class and execute it after calling the modification method.

0
source share

All Articles