Draggable and Droppable - jQuery UI - Web Development with jQuery (2015)

Web Development with jQuery (2015)

Part II. jQuery UI

Chapter 12. Draggable and Droppable

Beginning with this chapter, the discussion shifts to the jQuery UI library. The jQuery UI library is a collection of reusable components that enables you create user-interface functionality quickly. The jQuery UI library handles a variety of tasks, such as making elements in a document draggable or making a list of items that you can rearrange by dragging and dropping, and many other UI tasks that you learn about in the remaining chapters of this book.

The jQuery UI library is functionality that exists outside jQuery's core framework you've been using and learning about throughout the preceding chapters of this book. The jQuery UI library is a series of jQuery plugins that handles these different UI tasks. In the spirit of jQuery's API, the library makes certain UI tasks much easier to implement.

You can download jQuery UI library components from http://ui.jquery.com/download. The website enables you to customize your download based on which UI components you want to use, and it offers this customization so that you can add the least amount of JavaScript possible, which, in turn, reduces overhead like file size and bandwidth. The source code download for this book is available free from www.wrox.com/go/webdevwithjquery and includes the entire jQuery UI package, which comprises all jQuery UI library plugins. For testing and learning purposes, this is fine; however, if you want to use UI library components in a real, production website, you should customize your jQuery UI library download to include only the components that you will use in your application because the entire library is a sizable file weighing in at 229.56 KB packed (all white space, comments, and line breaks removed), or 347.82 KB fully unpacked and uncompressed—a fairly large file download.

This chapter begins coverage of the jQuery UI library with the Draggable and Droppable libraries. This contrasts with the coverage presented in Chapter 11, “HTML5 Drag and Drop,” which presents how to use HTML5's native drag-and-drop API. The key differences between the HTML5 drag-and-drop API and the jQuery UI's Draggable and Droppable API is that the HTML5 API can be used between multiple, independent browser windows (even different browser windows of completely different browsers), and even between different applications, assuming the applications in question use a browser component such as WebKit (Apple, et al.), Blink (Google, et al.), Gecko (Mozilla), or Trident (Microsoft). HTML5's drag-and-drop API also provides the ability to upload one or more files via drag-and-drop.

The Draggable and Droppable jQuery UI libraries provide similar functionality, but this functionality is limited to working within one browser window. Its functionality does not allow dragged content to leave the boundaries of the browser window. Whichever you choose to use depends upon what your project goals include for functionality.

The Draggable library gives you the ability to make any element on a page draggable. In the most rudimentary sense, that means you can move elements around in a document with your mouse and arrange those elements however you like. The next section introduces the Draggable jQuery UI API.

Making Elements Draggable

Making an element draggable is easy: First, you need to include the UI library that includes the Draggable plugin; then, after you make a selection with jQuery, you simply chain the method draggable() to the selection, like so:

$('div#anElementIdLikeToDrag').draggable();

The preceding code makes the <div> element with the id name anElementIdLikeToDrag, a draggable element, which means that you can move the element anywhere in the document with your mouse. The ability to make elements draggable gives you more options in terms of how your applications function, giving you many of the same options that you have developing desktop applications.

The actual code behind the scenes, enabling the drag operation, isn't complex, but it's yet another thing that jQuery allows you to take several lines of code and compress them into little code. In this case, it's a simple function call.

To show you just how easy it is to make an element draggable, the following presents an example in which you create a file manager that looks somewhat like Mac OS X Finder. You begin with the XHTML5 base, which is presented in the following markup (Example 12-1):

<!DOCTYPE HTML>

<html xmlns='http://www.w3.org/1999/xhtml'>

<head>

<meta http-equiv='content-type'

content='application/xhtml+xml; charset=utf-8' />

<meta http-equiv='content-language' content='en-us' />

<title>Finder</title>

<script src='../jQuery.js'></script>

<script src='../jQueryUI.js'></script>

<script src='Example 12-1.js'></script>

<link href='Example 12-1.css' rel='stylesheet' />

</head>

<body>

<div id='finderFiles'>

<div class='finderDirectory' data-path='/Applications'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Applications</span>

</div>

</div>

<div class='finderDirectory' data-path='/Library'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Library</span>

</div>

</div>

<div class='finderDirectory' data-path='/Network'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Network</span>

</div>

</div>

<div class='finderDirectory' data-path='/Sites'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Sites</span>

</div>

</div>

<div class='finderDirectory' data-path='/System'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>System</span>

</div>

</div>

<div class='finderDirectory' data-path='/Users'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Users</span>

</div>

</div>

</div>

</body>

</html>

The following CSS sets up the styling for the Finder example:

html,

body {

width: 100%;

height: 100%;

}

body {

font: 12px "Lucida Grande", Arial, sans-serif;

background: rgb(189, 189, 189) url('images/Bottom.png') repeat-x bottom;

color: rgb(50, 50, 50);

margin: 0;

padding: 0;

}

div#finderFiles {

border-bottom: 1px solid rgb(64, 64, 64);

background: #fff;

position: absolute;

top: 0;

right: 0;

bottom: 23px;

left: 0;

overflow: auto;

}

div.finderDirectory {

float: left;

width: 150px;

height: 100px;

overflow: hidden;

}

div.finderIcon {

background: url('images/Folder 48x48.png') no-repeat center;

background-size: 48px 48px;

height: 56px;

width: 54px;

margin: 10px auto 3px auto;

}

div.finderIconSelected {

background-color: rgb(196, 196, 196);

border-radius: 5px;

}

div.finderDirectoryName {

text-align: center;

}

span.finderDirectoryNameSelected {

background: rgb(56, 117, 215);

border-radius: 8px;

color: white;

padding: 1px 7px;

}

The preceding XHTML and CSS are combined with the following JavaScript:

$(document).ready(

function()

{

$('div.finderDirectory')

.mousedown(

function()

{

$('div.finderIconSelected')

.removeClass('finderIconSelected');

$('span.finderDirectoryNameSelected')

.removeClass('finderDirectoryNameSelected');

$(this).find('div.finderIcon')

.addClass('finderIconSelected');

$(this).find('div.finderDirectoryName span')

.addClass('finderDirectoryNameSelected');

}

)

.draggable();

}

);

The preceding source code results in the document that you see in Figure 12.1.

image

Figure 12.1

In the preceding example, you created a layout of folders like that found in Mac OS X Finder. The only difference you'll notice between browsers is that the rounded-corner effect present on selected folders comes through only on newer browsers, whereas older versions of IE and Opera show square corners.

Basically, the gist of this example enables you to select a single folder at a time and drag those folders around to any position in the window.

To make the elements draggable, you included the jQuery UI library, which includes all the jQuery UI plugins, including the Draggable plugin.

<script src='../jQueryUI.js'></script>

The markup in this example is straightforward. The individual folders are all contained in the <div> element with the id name finderFiles; this container element is needed to assist in controlling the presentation of the folders.

<div id='finderFiles'>

Each folder resides in a container <div> element with the class name finderDirectory, with the path to the directory contained in the data-path attribute, which could then be used to implement AJAX functionality where the path of the folder is submitted asynchronously to the server and the server responds with the contents of that folder. Each folder has an icon and a name, so markup is put in place for each of these. The reasoning behind this specific structure makes more sense after you examine the style sheet, but you create one <div> element for the icon, which controls the position of the icon and sets the dimensions for the highlighted style. Then the name of the folder is contained in another <div> element, which has the name of the folder nested in a <span> element. The<span> element is used so that when the folder is highlighted, the background is applied to an inline element, and the background hugs the text, even if the text takes up multiple lines (refer to Figure 12.1).

<div class='finderDirectory' data-path='/Applications'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Applications</span>

</div>

</div>

The style sheet does all the work of making this raw lump of structural markup into a Finder-imitating document. The following reviews each rule in the style sheet and explains why each is needed. The <html> and <body> element are each given 100 percent width and height so that these both automatically take up the entire viewport.

html,

body {

width: 100%;

height: 100%;

}

In the next rule, you give the Finder a Lucida Grande font, which is a Mac font used for most Apple-created Mac applications. If that font isn't available, you can use Arial, which is present on Windows. If that font is not present, use the generic sans-serif font. Thebackground is set to a shade of gray; then an image is tiled across the bottom of the window so that this document looks a little more like a real Finder window. The font color is set to a dark gray. Finally, the default padding and margin are removed from the <body>element, which is necessary to avoid scrollbars that would appear on the viewport due to the application of 100% width and height with the preceding style sheet rule.

body {

font: 12px "Lucida Grande", Arial, sans-serif;

background: rgb(189, 189, 189) url('images/Bottom.png') repeat-x bottom;

color: rgb(50, 50, 50);

margin: 0;

padding: 0;

}

The next rule positions the <div> element with the id name finderFiles, which contains all the folders. This <div> element is positioned absolutely and is set to take up nearly the entire viewport, except the bottom 23 pixels, and that is done by specifying opposing offset properties, which when present imply width and height. The background is set to white; there is a dark gray border placed across the bottom of the container; and finally, the overflow: auto; declaration is added so that when you have more folders and files than the container can hold, a scrollbar appears so that you can access folders and files off-screen.

div#finderFiles {

border-bottom: 1px solid rgb(64, 64, 64);

background: #fff;

position: absolute;

top: 0;

right: 0;

bottom: 23px;

left: 0;

overflow: auto;

}

The remaining style-sheet declarations set up the folders. The next rule puts the folders side by side and gives each fixed dimensions. The overflow: hidden; declaration prevents long folder names from extending outside the boundaries of the container.

div.finderDirectory {

float: left;

width: 150px;

height: 100px;

overflow: hidden;

}

The next rule handles the display of the folder icon. The <div> element sets the dimensions of the icon with the highlighting effect in mind, and the gray background applied to a selected folder is applied to the <div> element. The background image is sized using thebackground-size property to limit it to the actual dimensions of the folder's icon. The background-position is set to center so that it is centered both horizontally and vertically within the solid gray background color when the folder is highlighted. The <div> element is adjusted in position using top and bottom margin, and then it is centered inside its container <div> element using margin with auto as the value of the left and right margins. The result is a folder icon that looks more like a real Finder icon in OS X. Although, if you wanted to mimic Windows Explorer or another file management program, you might choose to deploy some of the same techniques.

div.finderIcon {

background: url('images/Folder 48x48.png') no-repeat center;

background-size: 48px 48px;

height: 56px;

width: 54px;

margin: 10px auto 3px auto;

}

The following rule defines the style for a selected folder. The class name finderIconSelected is applied to the <div> element with the class name finderIcon dynamically using jQuery.

div.finderIconSelected {

background-color: rgb(196, 196, 196);

border-radius: 5px;

}

The next rule centers the name of the folder.

div.finderDirectoryName {

text-align: center;

}

And finally, the last rule sets the style for the selected folder's name. A blue background, a little padding, white text, and rounded corners are added to make the folder name look more like the real Finder.

span.finderDirectoryNameSelected {

background: rgb(56, 117, 215);

border-radius: 8px;

color: white;

padding: 1px 7px;

}

And as you've no doubt come to expect, the JavaScript portion of this example is simple. You start with code that's required to make a folder selectable, which is done by adding a mousedown event. A mousedown event is used instead of, say, a click event, because you want a selection to take place even if the user moves the mouse cursor outside the boundaries of the folder while the mouse button is pressed. If users move the cursor while the button is pressed, that causes the element to be dragged. Because of that, you want the folder to be selected to show users that the folder they are dragging is selected.

$('div.finderDirectory')

.mousedown(

Inside the mousedown event, you write some logic for selecting the folder. First, you remove the class name finderIconSelected from the div.finderIconSelect element.

Then you repeat the selection; you remove the class name finderDirectoryNameSelected from the span.finderDirectoryNameSelected element.

This series of actions clears any previous selection when a new selection is made.

Now add the class names that you removed to the div.finderIcon and span elements that are selected.

function()

{

$('div.finderIconSelected')

.removeClass('finderIconSelected');

$('span.finderDirectoryNameSelected')

.removeClass('finderDirectoryNameSelected');

$(this).find('div.finderIcon')

.addClass('finderIconSelected');

$(this).find('div.finderDirectoryName span')

.addClass('finderDirectoryNameSelected');

}

Finally, you make each folder draggable by chaining the method draggable() to the call to mousedown().

.draggable();

The jQuery UI draggable() method lets you move the folders in the document to any position you like, similar to how Mac OS X's Finder works by default, enabling you to arrange the folders however you like. But the jQuery UI draggable() method enables you to do more than this. In the next section, you learn how to do ghosting and how to add the Droppable API into the mix.

Designating Drop Zones for Draggable Elements

Typically when you implement dragging on elements in your document, you want to designate somewhere for the elements being dragged to be dropped. jQuery UI provides another plugin for handling the drop portion of this; it is called Droppable. The jQuery UI Droppable plugin enables you to create and manipulate a variety of things associated with dropping one element onto another, including what happens while you drag one element over a drop zone and what happens when a drop takes place. jQuery allows you to have precision control over drag-and-drop, which lets you create a basic drag-and-drop implementation or a polished drag-and-drop implementation.

As you've already seen with the Draggable API, jQuery UI provides a concise, easy-to-use API for handling the drop side. To make an element into a droppable element, all you have to do is make a selection and call the droppable() method with the appropriate options, just as you did with the draggable() method. Options are provided via an object literal consisting of key, value pairs. The following example shows you what a droppable implementation looks like in the context of the Finder clone you've been building throughout this chapter:

$('div.finderDirectory')

.draggable({

helper: 'clone',

opacity: 0.5

})

.droppable({

accept: 'div.finderDirectory',

hoverClass: 'finderDirectoryDrop'

});

In the preceding code, you have a basic example implementation of the Droppable API. Each <div> element with the class name finderDirectory is made into a drop zone so that any directory can be dragged and dropped onto any other directory. To make the drop portion function properly, you pass some options to the droppable() method. The accept option lets you specify a selector that will be used to match what elements you want to allow to be dropped onto the drop zone. In this case, you want to allow only <div> elements with the class name finderDirectory to be dropped. Using this filter, you can add other drag-and-drop functionality within the same document without having conflict between different drag-and-drop implementations.

The hoverClass option allows you to change the style of the drop zone as a draggable element is dragged over the droppable element. You simply specify a class name as the value and then set up the appropriate styles in your style sheet.

In the following example (Example 12-2), you take the basic concept of the Droppable API that was demonstrated and apply the droppable() method to the Finder clone you've been building.

<!DOCTYPE HTML>

<html xmlns='http://www.w3.org/1999/xhtml'>

<head>

<meta http-equiv='content-type'

content='application/xhtml+xml; charset=utf-8' />

<meta http-equiv='content-language' content='en-us' />

<data-path>Finder</data-path>

<script src='../jQuery.js'></script>

<script src='../jQueryUI.js'></script>

<script src='Example 12-2.js'></script>

<link href='Example 12-2.css' rel='stylesheet' />

</head>

<body>

<div id='finderFiles'>

<div class='finderDirectory' data-path='/Applications'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Applications</span>

</div>

</div>

<div class='finderDirectory' data-path='/Library'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Library</span>

</div>

</div>

<div class='finderDirectory' data-path='/Network'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Network</span>

</div>

</div>

<div class='finderDirectory' data-path='/Sites'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Sites</span>

</div>

</div>

<div class='finderDirectory' data-path='/System'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>System</span>

</div>

</div>

<div class='finderDirectory' data-path='/Users'>

<div class='finderIcon'></div>

<div class='finderDirectoryName'>

<span>Users</span>

</div>

</div>

</div>

</body>

</html>

The preceding HTML is combined with the following CSS:

html,

body {

width: 100%;

height: 100%;

}

body {

font: 12px "Lucida Grande", Arial, sans-serif;

background: rgb(189, 189, 189) url('images/Bottom.png') repeat-x bottom;

color: rgb(50, 50, 50);

margin: 0;

padding: 0;

}

div#finderFiles {

border-bottom: 1px solid rgb(64, 64, 64);

background: #fff;

position: absolute;

top: 0;

right: 0;

bottom: 23px;

left: 0;

overflow: auto;

}

div.finderDirectory {

float: left;

width: 150px;

height: 100px;

overflow: hidden;

}

div.finderIcon {

height: 56px;

width: 54px;

background: url('images/Folder 48x48.png') no-repeat center;

background-size: 48px 48px;

margin: 10px auto 3px auto;

}

div.finderIconSelected,

div.finderDirectoryDrop div.finderIcon {

background-color: rgb(204, 204, 204);

border-radius: 5px;

}

div.finderDirectoryDrop div.finderIcon {

background-image: url('images/Open Folder 48x48.png');

}

div.finderDirectoryName {

text-align: center;

}

span.finderDirectoryNameSelected,

div.finderDirectoryDrop span.finderDirectoryNameSelected {

background: rgb(56, 117, 215);

border-radius: 8px;

color: white;

padding: 1px 7px;

}

Finally, you apply the following JavaScript, which extends the previous example presented in Example 12-1 with new code that enables the droppable() API:

$(document).ready(

function()

{

$('div.finderDirectory')

.mousedown(

function()

{

$('div.finderIconSelected')

.removeClass('finderIconSelected');

$('span.finderDirectoryNameSelected')

.removeClass('finderDirectoryNameSelected');

$(this).find('div.finderIcon')

.addClass('finderIconSelected');

$(this).find('div.finderDirectoryName span')

.addClass('finderDirectoryNameSelected');

}

)

.draggable({

helper : 'clone',

opacity : 0.5

})

.droppable({

accept: 'div.finderDirectory',

hoverClass: 'finderDirectoryDrop',

drop: function(event, ui)

{

var path = ui.draggable.data('path');

// Do something with the path

// For example, make an AJAX call to the server

// where the logic for actually moving the file or folder

// to the new folder would take place

// Remove the element that was dropped.

ui.draggable.remove();

}

});

}

);

The preceding source code gives you output in Safari on Mac OS X, as shown in Figure 12.2.

image

Figure 12.2

In the preceding example, you added the jQuery UI droppable() method to the Finder clone, which lets you designate areas in which draggable elements can be dropped. The jQuery UI Draggable and Droppable plugins both work in all modern browsers.

To set up the document for the Droppable library, you added a few rules to the style sheet, which define what an element looks like while you drag one element over another. From here on, the action of dragging one element over another element is referred to as thedragover event. jQuery UI simply refers to this event as over, but the native drag-and-drop API from Chapter 11 refers to this event as dragover.

In essence, the style that you use for dragover is simply the same style that you're already using to highlight a folder to indicate its selection, with just one difference: You swap out the default folder icon with an open folder icon. In the JavaScript portion, changing thedragover style in the style sheet is made possible by the addition of the class name, finderDirectoryDrop. This class name is added to the <div> element with class name finderDirectory. jQuery dynamically adds or removes the finderDirectoryDrop class name to or from this <div> element, allowing you to define a different style upon dragover.

So, you're reusing the “selected folder style” for folders where the dragover event is taking place, with the open folder icon being the only difference. Reusing that style is done simply by adding additional selectors that reference the <div> element with the dragover class name finderDirectoryDrop to the style sheet.

div.finderIconSelected,

div.finderDirectoryDrop div.finderIcon {

background-color: rgb(204, 204, 204);

border-radius: 5px;

}

div.finderDirectoryDrop div.finderIcon {

background-image: url('images/Open Folder 48x48.png');

}

div.finderDirectoryName {

text-align: center;

}

span.finderDirectoryNameSelected,

div.finderDirectoryDrop span.finderDirectoryNameSelected {

background: rgb(56, 117, 215);

border-radius: 8px;

color: white;

padding: 1px 7px;

}

The preceding reuses the selected folder style for dragover elements. To replace the default folder icon with an open folder icon, you use a more specific selector. The following selector is used to add the default folder icon:

div.finderIcon

The following selector overrides the preceding selector when a dragover event is taking place, providing an open folder icon instead of the default folder icon:

div.finderDirectoryDrop c.finderIcon

Next, you pass a few customizations to the draggable() method to accomplish two things. The first is that when a user begins to drag a folder icon, you want to use a duplicate of the icon to refer to the item that is being dragged. The second is to make the duplicate semitransparent. This is an effect known as ghosting, which creates a UI where when an element is dragged across the screen, a semitransparent duplicate of that element represents what is dragged, which resembles a ghost in appearance.

.draggable({

helper : 'clone',

opacity : 0.5

})

The method of passing a JavaScript object literal containing key, value pairs is a common method used by jQuery plugins to provide customization options. This provides you with fine-grained control over how a plugin works. In the portion of JavaScript that callsdroppable(), you pass options like accept, which lets you filter which elements can be dropped on the droppable element by virtue of a selector.

.droppable({

accept: 'div.finderDirectory',

The next option specifies what class name is to be added to the drop element when a dragover event takes place. This option causes the class name finderDirectoryDrop to be added to the <div> element with the class name finderDirectory when a dragover event takes place.

hoverClass: 'finderDirectoryDrop',

In the last option passed to the droppable() method, you specify a function that is executed when the drop event takes place, which occurs when an element has been dragged over a drop zone and the mouse button released. Within this function is where you want to do whatever it is the act of dragging and dropping is intended to provide. In this case, you want to remove the folder being dropped and then make an AJAX call to the server. On the server side, you have code that actually moves the folder to the new location.

drop: function(event, ui)

{

var path = ui.draggable.data('path');

// Do something with the path

// For example, make an AJAX call to the server

// where the logic for actually moving the file or folder

// to the new folder would take place

// Remove the element that was dropped.

ui.draggable.remove();

}

});

In the preceding drop event, you can access properties associated with the drag-and-drop operation by specifying a second argument in the callback function you provide. The second argument is named ui; then the ui.draggable object gives you access to the element that has been dragged and dropped on this element. If you'd like to examine the ui object in its entirety, you can add console.log(ui); to the code, and the ui object will be output to your browser's debugging console, where you can examine everything it contains.

In the callback function that you assign to the drop option, you access the data-path attribute of the element being dragged, which contains the folder's absolute path. You could then send that path on to the server, along with the path of the folder that the dragged folder has been dropped on and actually move that folder to the new location programmatically. The function ends with the dragged element being deleted with a call to remove(), which would be the final operation that you would do upon implementing a drag-and-drop folder UI.

In the preceding examples, you learned how the jQuery UI draggable() and droppable() methods work in a real-life-oriented demonstration of a drag-and-drop implementation. These methods, combined with what you learned about the native drag-and-drop API inChapter 11, provide powerful and flexible methods of implementing drag and drop in a browser or application utilizing a browser component.

NOTE A comprehensive jQuery UI Draggable and Droppable reference is available in Appendix J, including all the options that you can pass to both the draggable() and droppable() methods and the ui object that you can optionally specify in the second argument to draggable and droppable event handlers.

Summary

In this chapter, you learned how to use the jQuery UI Draggable and Droppable plugins, which you can download à la carte from www.jquery.com. The jQuery website provides à la carte downloading for UI components so that you can include only the plugins that you need to use, which, in turn, helps keep your applications lean and efficient.

Throughout this chapter, you worked on building a file component similar to the one found in Mac OS X's Finder and saw how you can make folders into draggable elements as well as drop zones for draggable elements. You saw how you can control the nuisances of a drag-and-drop implementation via the options that jQuery UI allows you to pass to both the draggable() and droppable() methods, which help you to control what kind of drag operation you want, what the drag element looks like, what the drop element looks like, and the event handlers you can specify to execute code during specific events that take place during a drag-and-drop operation.

The next chapter presents another drag-and-drop UI concept that jQuery provides called Sortable.

Exercises

1. If you want to have a UI that allows users to drag elements around in a document and position those elements wherever they like, what would you use? (Hint: what function call?)

2. If you want to create draggable elements that work similarly to your operating system's file manager, where the original element remains in place, but when a drag operation starts, you drag around a clone of that element, how would you do that with jQuery UI? Write a sample program that achieves this.

3. If you want to make an element into a drop zone for draggable elements, what function call would you use?

4. Write the function call that you would use to add a class name to a drop zone while an element was being dragged over the top of it.

5. What option would you provide to the droppable() method if you want to limit the drag elements that can be dropped on the drop element? Also, what type of value would you provide to that option?