What You’ll Learn in This Hour:
Implementing drag-and-drop functionality
Making elements and children resizable
How to select multiple page elements using a bounding box
Creating sortable tables, lists, and containers
A special set of jQuery UI widgets are intended to provide generalized interactions for various elements. These widgets allow you to make elements draggable and droppable and provide sorting, box selection, and resize functionality to elements.
The jQuery UI interaction widgets can be attached to elements to provide a rich set of predefined interactions. The following sections cover the different interaction widgets and how to implement them in your web pages.
All jQuery UI interactions are based on two main components—the jQuery.widget
factory and the mouse widget. The jQuery.widget
factory provides the base functionality for all widgets including creation, disabling, enabling, and option settings. The mouse widget provides the base mouse interactions with the widget that captures mouse events and allows the widgets to interact with them.
The jQuery.widget
factory defines an interface that is used by all jQuery UI widgets. The options, methods, and events of the factory are available to all widgets. Table 19.1 lists the methods and events defined in the factory and available in all widgets.
You can get more information about the jQuery.widget
factory at http://api.jqueryui.com/jQuery.widget/.
The mouse interaction widget is automatically applied to all widgets. Typically, you will not need to interact with it much. However, it does expose a few options that are very useful at times. Those options are the following:
cancel
—Cancels interaction for specific elements. For example, to cancel mouse interactions for elements with class="label"
in the #item1
, you would use
$( "#item1" ).mouse( "option", "cancel", ".label" );
delay
—Delays the time after the mousedown
event occurs before the interaction takes place. For example, to add a 1-second delay for mouse interactions on #item2
, you would use
$( "#item2" ).mouse( "option", "delay", 1000 );
distance
—Specifies the distance in pixels the mouse must travel after the mousedown event occurs before the interaction should start. For example, to set the distance to 10 pixels for mouse interactions on #item3
, you would use
$( "#item3" ).mouse( "option", "distance", 10 );
Now that you have reviewed the widget interface and the mouse interaction widget, you are ready to look at some of the most common jQuery UI widgets—the draggable and droppable widgets. These widgets are designed to work in tandem.
You can define one element to be draggable and then another to be droppable. When draggable elements are dropped on droppable widgets, you can apply JavaScript and jQuery code to provide whatever interaction for the user you would like.
The draggable widget defines an element as draggable by holding down the mouse and moving it. This allows you to move the element to whatever position on the screen you would like.
The draggable widget will handle scrolling elements and provides several options to control the look and feel while dragging. Table 19.2 describes the more common draggable options. The following shows an example of attaching the draggable widget to an element with the cursor
and opacity
options:
$("#img1").draggable({cursor:"move", opacity:.5});
The draggable widget also provides the additional events so handlers can be attached to the element when dragging starts, is in progress, and stops. Table 19.3 lists the events that you can access on draggable items. The following shows an example of adding a dragstop
event to apply a bounce
effect when the item is dropped:
$("#drag1").draggable({cursor:"move", opacity:.5});
$("#drag1").on("dragstop", function(){$(this).effect("bounce", 1000); });
The droppable widget defines an element as a valid drop container usable by draggable items. This enables you to provide interactions between elements using simple mouse controls.
The droppable widget allows you to specify an accept function that can process the information about the event, such as mouse coordinates as well as the draggable item involved. Table 19.4 describes the more common droppable options. The following shows an example of attaching the droppable widget to an element and specifying the tolerance
level:
$("#div1"). droppable ({tolerance:"touch"});
The droppable widget also provides the additional events so handlers can be attached to the element when dragging and dropping. Table 19.5 lists the events that you can access on droppable items. The following shows an example of adding a dropactivate
event to apply a shake
effect when a droppable item is activated by a drag start:
$("#drop1").droppable({tolerance:"pointer"});
$("#drop1").on("dropactivate", function(){$(this).effect("shake", 1000); });
A frequent request for users is the capability to define the size and shape of images, lists, tables, and so on. The resizable widget provides the capability to easily resize an image with mouse controls. This allows users to resize page elements as they desire.
The resizable widget attaches several handle controls to the page elements that interact with the mouse to resize the elements. You can also resize other elements at the same time.
Table 19.6 describes the more common resizable options. The following shows an example of attaching the resizable widget to an element and specifying the aspectRatio
as true
:
$("#div1"). resizable ({aspectRatio:true});
The resizable widget also provides the additional events so handlers can be attached to the element when resizing. Table 19.7 lists the events that you can access on resizable items. The following shows an example of adding a resizestop
event to apply a pulsate
effect when a resizable item has finished being resized:
$("#resize1"). resizable ({aspectRatio:true });
$("#resize1").on("dropactivate", function(){$(this).effect("pulsate"); });
Another frequent request for users is the capability to easily select multiple items on a page using a bounding box. The selectable widget provides that functionality by allowing the user to draw a box, or “lasso,” around selectable children inside the selectable element using the mouse. Items inside the box are selected in the list.
Table 19.8 describes the more common selectable options. The following shows an example of attaching the selectable widget to an element and specifying the tolerance
as fit
:
$("#ul1"). selectable ({tolerance:"fit"});
The selectable widget also provides the additional events so handlers can be attached to the selectable element or its children when changing the selection. Table 19.9 lists the events that you can access on selectable items.
Each of the selectable events will pass the event
object along with a ui
object that will have a value for each of the events representing the selectable element. For example, the following code adds a selectableselected
event to an element and then accesses the selected
attribute:
$("#list1").selectable();
$("#list1").on("selectableselected ", function(e, ui){ ui.selected.effect("shake"); });
The .ui-selecting
class is appended to child elements that are currently being selected. After a child element is selected, the .ui-selected
class will be appended. This allows you to define some basic styles in CSS without having to add/remove classes in the selectable event handlers.
One of the coolest interactions provided by jQuery UI is the sortable widget. The sortable widget allows you to drag and reposition the order of HTML elements that are flowing together in a list, table, or just inside a container.
The sortable widget repositions the other elements as you drag an item. You can also link sortable containers together so that you can drag an item from one sortable container to another.
Table 19.10 describes the more common sortable options. The following shows an example of attaching a sortable widget to an element and specifying the tolerance
as fit
:
$("#ul1").sortable({tolerance:"fit"});
The sortable widget also provides the additional events so handlers can be attached to the sortable element or its children when sorting. Table 19.11 lists the events that you can access on selectable items.
Tip
jQuery UI will add the .ui-sortable-helper
class to the helper element being sorted. You can define your own settings in the CSS for the helper class to control the look while moving the element in the sortable
.
Each of the sortable
events will pass the event
object along with a ui
object that will have the following values attached to it:
helper
—jQuery object representing the helper object being dragged.
item
—jQuery object representing the actual object being sorted.
offset
—{top, left}
object for the current offset.
originalPosition
—{top, left}
object for the original position.
position
—{top, left}
object for the current position.
sender
—Sortable object that the item is being dragged from when dragging from one sortable to another.
For example, the following code connects #list1
to #list2
and then adds a sortreceived
event that will add a pulsate
effect on both the sender and recipient:
$("#list1").sortable({connectWith:"#list2"});
$("#list1").on("sortreceived", function(e, ui){
ui.sender.effect("pulsate");
$(this).effect("pulsate "); });
Using interaction widgets, you can easily provide some advanced features to your web pages. In this hour, you created some drag-and-drop elements by making some elements draggable and others droppable using jQuery UI draggable and droppable widgets.
Adding the selectable widget allowed you to draw a bounding box or lasso around multiple items. You used the resizable widget to make a container such as a <div>
resizable. You also resized the content inside.
Finally, you learned how to implement the sortable widget to sort items in a <div>
and <tbody>
. Elements from sortable containers can also be dragged from one container to another.
Q. Is it possible to create a custom interaction widget?
A. Yes. Using the jQuery UI jquery.widget
factory, you can create a custom widget and provide whatever functionality in the prototype that you need.
Q. Is there a way to prevent mouse events from occurring on elements inside an item extended with a jQuery UI widget?
A. Yes. The following code cancels mouse events for items in an element #myList
that have class="notSelectable"
:
$("#myList").mouse({ cancel:".notSelectable"});
The workshop consists of a set of questions and answers designed to solidify your understanding of the material covered in this hour. Try to answer the questions before looking at the answers.
1. When making an item draggable, what option should you use to keep the original in place while dragging?
2. What droppable event will be triggered when a draggable item is ready to be dropped in it?
3. True or False: It is not possible to keep a fixed ratio when using the resizable widget on an image.
4. Is there a way to limit what items are selected by the selectable widget?
1. Set helper
to "clone"
or another DOM object.
2. dropover
3. False. You can set the aspectRatio
option to set a fixed ratio.
4. Yes. Use the filter
option.
1. Open the code in Listing 19.3 and add a resize
handler for the #resize2
handler. Change the font-size
attribute based on the width and height the element is resized to.
2. Open the code in Listing 19.5 and modify the #sortTable
element so that it connects with #sorter2
. You will need to remove the axis
restriction and change the width
of #sort2
to handle the additional width.