CHAPTER 25

image

Using the Other Interactions

In this chapter, I describe the three remaining jQuery UI interactions: sortable, selectable, and resizable. These interactions are less used (and less useful) than draggable and droppable, which I described in Chapter 24. The interactions in this chapter can be useful, but they use models that are hard to highlight to the user. Because of that, they perform best as supplements to other, more conventional, approaches. Table 25-1 provides the summary for this chapter.

Table 25-1. Chapter Summary

Problem Solution Listing
Apply the sortable interaction Select the container element, and call the sortable method 1
Obtain the order that the user created with a sortable interaction Call the toArray or serialize method 2, 3
Enable dragging elements from one sortable item to another Use the connectWith setting 4
Connect a draggable element with a sortable item Use the connectToSortable setting on the draggable element 5
Specify which elements are sortable Use the items setting 6
Style the empty space created while a sortable item is being dragged Use the placeholder setting 7
Ignore a change in order Use the cancel method 8
Refresh the set of elements in a sortable item Use the refresh method 9
Get information about the sort operation in progress Use the ui object provided to event handler functions 10
Apply the selectable interaction Select the container element, and call the selectable method 11, 12
Prevent an element from being selected Use the cancel method 13
Apply the resizable interaction Use the resizable method 14
Resize multiple elements Use the alsoResize setting 15, 16
Limit the size of a resizable element Use the maxHeight, maxWidth, minHeight, and minWidth settings 17
Select the draggable edges and corners for a resizable element Use the handles setting 18

Using the Sortable Interaction

The sortable interaction lets the user change the order of a set of elements by dragging them around. You apply the sortable interaction by selecting the element that contains the individual items that you want to sort and then calling the sortable method, as shown in Listing 25-1.

Listing 25-1.  Using the sortable Interaction

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.sortable { width: 100px; background-color: lightgrey; font-size: large;
            float: left; margin: 4px; text-align: center; border: medium solid black;
            padding: 4px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#sortContainer").sortable();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="sortContainer">
        <div id="item1" class="sortable">Item 1</div>
        <div id="item2" class="sortable">Item 2</div>
        <div id="item3" class="sortable">Item 3</div>
    </div>
</body>
</html>

In Listing 25-1, I created a number of div elements and assigned them to the sortable class. This class has no effect on the interaction: I use it only to style the elements. To create the interaction, I select the parent div element (the one whose id is sortContainer) and call the sortable method. The result is that I can change the order of my three div elements simply by dragging them into a new position. You can see the effect in Figure 25-1 (although, like all the examples in this chapter, you will get a better sense of what is happening by running the example in the browser).

9781430263883_Fig25-01.jpg

Figure 25-1. Sorting items by dragging them

To demonstrate the sortable interaction, I dragged the element labeled Item 2 to the right of the browser window. Once I drag the element past the one labeled Item 3, jQuery UI rearranges the items so that they are in a new order. I only dragged an element one position, but you can move them around several positions at a time.

Getting the Sortable Order

At some point, you need to know the order that the user created by moving the elements around. To get this information, you can call the toArray method, which returns a JavaScript array of the id attribute values for the sorted elements. Listing 25-2 shows the addition of a button to the example that writes the current order to the console.

Listing 25-2.  Obtaining the Sorted Element Order

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#sortContainer").sortable();
  
        $("<div id=buttonDiv><button>Get Order</button></div>").appendTo("body");
        $("button").button().click(function() {
            var order = $("#sortContainer").sortable("toArray");
            for (var i = 0; i < order.length; i++) {
                console.log("Position: " + i + " ID: " + order[i]);
            }
        });
    });
</script>
...

You can see the effect in Figure 25-2. When the button is pressed, I call the toArray method and enumerate the contents of the resulting array to the console.

9781430263883_Fig25-02.jpg

Figure 25-2. Adding a button to write out the sort order

For the order in the figure, pressing the button produces the following output:

Position: 0 ID: item2
Position: 1 ID: item3
Position: 2 ID: item1

You can also use the serialize method to generate a string that can easily be used with a form. Listing 25-3 provides an example.

Listing 25-3.  Using the serialize Method

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.sortable { width: 100px; background-color: lightgrey; font-size: large;
            float: left; margin: 4px; text-align: center; border: medium solid black;
            padding: 4px;}
            #buttonDiv {clear: both}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#sortContainer").sortable();
      
            $("<div id=buttonDiv><button>Get Order</button></div>").appendTo("body");
            $("button").button().click(function() {
                var formstring = $("#sortContainer").sortable("serialize");
                console.log(formstring);
            })
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="sortContainer">
        <div id="item_1" class="sortable">Item 1</div>
        <div id="item_2" class="sortable">Item 2</div>
        <div id="item_3" class="sortable">Item 3</div>
    </div>
</body>
</html>

Notice that I had to change the id values of the sortable elements. The serialize method looks for a pattern of <key>_<index> when generating its string. The output for the order shown in Figure 25-2 is as follows:

item[]=2&item[]=3&item[]=1

Configuring the Sortable Interaction

The sortable interaction relies on the draggable interaction I described in Chapter 24. This means that the options I described for that interaction (such as axis and tolerance) can be applied with the same effect to configure sortable interactions. I won’t describe those settings again. Instead, Table 25-2 shows the settings that are unique to the sortable interaction and the most useful. I describe these settings in the sections that follow.

Table 25-2. Sortable Settings

Setting Description
connectWith Specifies another sortable element to connect to so that items can be dragged between them. The default is false, meaning that there is no connection.
dropOnEmpty When false, items cannot be dropped on a connected sortable interaction that contains no items. The default is true.
items Specifies the items that will be sortable through a selector. The default is > *, which selects any descendant of the element on which the sortable method has been called.
placeholder Specifies a class that will be assigned to the element that is created to preserve space while a sortable item is being dragged to a new location.

Connecting Sortable Interactions

The sortable feature I like most is the ability to connect two sortable interactions, allowing items to be dragged between them. You achieve this using the connectWith setting, specifying a selector that matches the element you want to connect with. You can create a bidirectional connection by using the connectWith setting on both sortable elements, as shown in Listing 25-4.

Listing 25-4.  Connecting Sortable Interactions

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.sortable { width: 100px; background-color: lightgrey; font-size: large;
            margin: 4px; text-align: center; border: medium solid black; padding: 4px;}
        #fruitContainer {position: absolute; right:50px}
        #flowerContainer {position: absolute; left:50px}
        div.flower {background-color: lightgreen}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#fruitContainer").sortable({
                connectWith: "#flowerContainer"
            });
            $("#flowerContainer").sortable({
                connectWith: "#fruitContainer"
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="fruitContainer" class="sortContainer">
        <div id="fruit_1" class="sortable fruit">Apple</div>
        <div id="fruit_2" class="sortable fruit">Orange</div>
        <div id="fruit_3" class="sortable fruit">Banana</div>
        <div id="fruit_4" class="sortable fruit">Pear</div>
    </div>
    <div id="flowerContainer" class="sortContainer">
        <div id="flower_1" class="sortable flower">Aster</div>
        <div id="flower_2" class="sortable flower">Peony</div>
        <div id="flower_3" class="sortable flower">Lily</div>
        <div id="flower_4" class="sortable flower">Orchid</div>
    </div>
</body>
</html>

In Listing 25-4, I created two groups of items and called the sortable method on their container element. I used the connectwith setting to associate each sortable with the other, and Figure 25-3 shows the result.

9781430263883_Fig25-03.jpg

Figure 25-3. Dragging elements between connected sortable interactions

Connecting a Draggable Element with a Sortable Element

You can also connect a draggable element with a sortable one. You do this by applying the connectToSortable setting on the draggable element, specifying a selector that matches the draggable element you want to connect to. Listing 25-5 shows how this is done.

Listing 25-5.  Connecting a Draggable Element and a Sortable Element

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.sortable { width: 100px; background-color: lightgrey; font-size: large;
            margin: 4px; text-align: center; border: medium solid black; padding: 4px;}
        #fruitContainer {position: absolute; right:50px}
        #flowerContainer {position: absolute; left:50px}
        div.flower {background-color: lightgreen}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#fruit_1").draggable({
                connectToSortable: "#flowerContainer",
                helper: "clone"
            });
            $("#flowerContainer").sortable();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="fruitContainer" class="sortContainer">
        <div id="fruit_1" class="sortable fruit">Apple</div>
    </div>
    <div id="flowerContainer" class="sortContainer">
        <div id="flower_1" class="sortable flower">Aster</div>
        <div id="flower_2" class="sortable flower">Peony</div>
        <div id="flower_3" class="sortable flower">Lily</div>
        <div id="flower_4" class="sortable flower">Orchid</div>
    </div>
</body>
</html>

In Listing 25-5, I reduced the number of fruit items to one and made it draggable, connecting to the sortable list of flowers. The result is that the draggable item can be added to the sortable list, as shown in Figure 25-4. This setting works best when the helper setting for the draggable item is clone. It will work for other values, but an error will be reported.

9781430263883_Fig25-04.jpg

Figure 25-4. Connecting a sortable item and a draggable item

Selecting the Sortable Items

You can be selective about which items in the container are sortable. You do this through the items setting, the value of which is a selector that matches the elements you want to enable sorting for. Elements that do not match the selector cannot be rearranged. Listing 25-6 demonstrates.

Listing 25-6.  Selecting Specific Elements to Be Sortable

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.sortable { width: 100px; background-color: lightgrey; font-size: large;
            margin: 4px; text-align: center; border: medium solid black; padding: 4px;}
        #fruitContainer {position: absolute; right:50px}
        #flowerContainer {position: absolute; left:50px}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("div.flower:even").css("background-color", "lightgreen")
            $("#flowerContainer").sortable({
                items: ".flower:even"
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="flowerContainer" class="sortContainer">
        <div id="flower_1" class="sortable flower">Aster</div>
        <div id="flower_2" class="sortable flower">Peony</div>
        <div id="flower_3" class="sortable flower">Lily</div>
        <div id="flower_4" class="sortable flower">Orchid</div>
    </div>
</body>
</html>

In Listing 25-6, I used the items setting to specify that only the even-numbered elements in the container should be sortable. In Figure 25-5, the Aster and Lily elements can be sorted, but the Peony and Orchid elements won’t respond to being dragged and remain in position.

9781430263883_Fig25-05.jpg

Figure 25-5. Selecting the items that can be sorted

There is an oddity you should be aware of when using the items setting, and I have shown it in the last frame of the figure. An element that doesn’t match the selector cannot be dragged into a new position unless it has been dislodged by another element. So in the figure, I dragged the Aster element to a new position, which forces the Peony element to move. Once it is moved, the Peony element will respond to being dragged and sorted as though it matches the items selector.

Styling the Empty Space

While you are dragging an item into a new position, the space it leaves behind remains empty. You can apply a CSS class to this space through the placeholder setting. This can be a useful way to emphasize that the empty space is a drop target. Listing 25-7 shows the use of the placeholder setting.

Listing 25-7.  Using the placeholder Setting

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.sortable {width: 100px; background-color: lightgrey; font-size: large;
            margin: 4px; text-align: center; border: medium solid black; padding: 4px;}
        #flowerContainer {position: absolute; left:25%}
        .emptySpace {border: medium dotted red; height: 25px; margin: 4px}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#flowerContainer").sortable({
                placeholder: "emptySpace"
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="flowerContainer" class="sortContainer">
        <div id="flower_1" class="sortable ">Aster</div>
        <div id="flower_2" class="sortable ">Peony</div>
        <div id="flower_3" class="sortable">Lily</div>
        <div id="flower_4" class="sortable">Orchid</div>
    </div>
</body>
</html>

In Listing 25-7, I defined a CSS class called emptySpace, which defines sizes for the height and margin properties and defines a red dotted border. I specify this class using the placeholder setting and, as Figure 25-6 shows, when I drag an element to sort it, the space that it leaves behind is assigned to the emptySpace class.

9781430263883_Fig25-06.jpg

Figure 25-6. Using the placeholder setting

Using the Sortable Methods

The sortable interaction defines all of the standard jQuery UI methods, plus a few that are specific to working with sortable elements. Table 25-3 describes these methods.

Table 25-3. Sortable Methods

Method Description
sortable("destroy") Removes the interaction from the element
sortable("disable") Disables the sortable interaction
sortable("enable") Enables the sortable interaction
sortable("option") Changes one or more settings
sortable("toArray") Returns an array containing the sorted set of id attribute values (see the section “Getting the Sortable Order” for an example)
sortable("refresh") Refreshes the sortable interaction
sortable("cancel") Cancels a sort operation

Cancelling a Sort

You can use the cancel method to prevent elements from being sorted. This is something that should be done sparingly because it effectively ignores the actions that the user has taken. If you do cancel a sort, you should make sure the user knows why this happened. Listing 25-8 provides an example of using the cancel method in conjunction with the update event. The update event is triggered when the user releases the mouse button after having dragged an element to create a new sorted order. I describe the sortable events in the section “Using the Sortable Events.”

Listing 25-8.  Using the cancel Method

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.sortable {width: 100px; background-color: lightgrey; font-size: large;
            margin: 4px; text-align: center; border: medium solid black; padding: 4px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#error").dialog({autoOpen: false, modal: true})
          
            $("#flowerContainer").sortable({
                update: function() {
                    var sortedItems = $("#flowerContainer").sortable("toArray");
                    if (sortedItems[0] != "item_1") {
                        $("#error").dialog("open")
                        $("#flowerContainer").sortable("cancel")
                    }
                }
            });
        });
    </script>
</head>
<body>
    <div id="error">The King must be first</div>
    <h1>Jacqui's Flower Shop</h1>
    <div id="flowerContainer" class="sortContainer">
        <div id="item_1" class="sortable ">King</div>
        <div id="item_2" class="sortable ">Queen</div>
        <div id="item_3" class="sortable ">Jack</div>
        <div id="item_4" class="sortable">10</div>
    </div>
</body>
</html>

In Listing 25-8, I call the cancel method if the new sorted order that the user has created means that the King element isn’t in the first place in the list. I use the dialog widget, described in Chapter 22, to alert the user to the problem. Changes that affect the other sortable elements are allowed to continue.

Refreshing the Sortable Elements

The refresh method causes the sortable interaction to refresh its cache of the elements in the sortable container. Listing 25-9 shows how you can use this feature to add new sortable elements.

Listing 25-9.  Adding New Sortable Elements

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.sortable {width: 100px; background-color: lightgrey; font-size: large;
            margin: 4px; text-align: center; border: medium solid black; padding: 4px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#flowerContainer").sortable();
              
            var itemCount = 2;
              
            $("button").click(function() {
                $("<div id=flower_" + (itemCount++) + " class=sortable>Item " +
                  itemCount + "</div>").appendTo("#flowerContainer");
                $("#flowerContainer").sortable("refresh");
            })
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <button>Add Sortable Item</button>
    <div id="flowerContainer" class="sortContainer">
        <div id="flower_1" class="sortable">Aster</div>
        <div id="flower_2" class="sortable">Peony</div>
    </div>
</body>
</html>

In Listing 25-9, I added a button to the document that adds new items to the sortable container and calls the refresh method to make sure that the items are properly sortable.

Using the Sortable Events

The sortable interaction supports all of the events defined by the draggable interaction, which I described in Chapter 24. Table 25-4 describes the events that are unique to the sortable interaction.

Table 25-4. Sortable Events

Event Description
change Triggered when positions change while an element is being sorted by the user
receive Triggered when an item is dragged to this sortable item from a connected one
remove Triggered when an item is dragged from this sortable item to a connected one
sort Triggered for each mouse move during a sort
update Triggered when the user stops dragging an item and the order of items has changed

When triggering these events, jQuery UI provides additional information via a ui object argument, which has the properties shown in Table 25-5.

Table 25-5. Sortable ui Object Properties

Property Description
helper Returns the helper element
position Returns the current position of the helper as an object with top and left properties
item Returns a jQuery object containing the currently dragged item
placeholder Returns a jQuery object containing the placeholder element
sender Returns a jQuery object containing the connected sortable from which the element originates (this property is null when there is no connected sortable)

Listing 25-10 shows the use of the ui object with the sort and change events.

Listing 25-10.  Using the change and sort Events

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.sortable {width: 100px; background-color: lightgrey; font-size: large;
            margin: 4px; text-align: center; border: medium solid black; padding: 4px;}
        #flowerContainer {position: absolute; left:10px}
        #info {position: absolute; right: 10px; border: medium solid black; padding: 4px}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#flowerContainer").sortable({
                sort: function(event, ui) {
                    $("#itemId").text(ui.item.attr("id"))
                },
                change: function(event, ui) {
                    $("#pos").text($("#flowerContainer *").index(ui.placeholder))
                }
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="flowerContainer" class="sortContainer">
        <div id="flower_1" class="sortable ">Aster</div>
        <div id="flower_2" class="sortable ">Peony</div>
        <div id="flower_3" class="sortable">Lily</div>
        <div id="flower_4" class="sortable">Orchid</div>
    </div>
    <div id="info" class="ui-widget">
        <div>Item ID: <span id="itemId">None</span></div>
        <div>Pos: <span id="pos">None</span></div>
    </div>
</body>
</html>

I use the events to display information about the sorting operation. For the sort event, I read the ui.item property and get the id attribute of the element being dragged. For the change event, I use the ui.placeholder property, and I use the index method to figure out its position among the sortable elements.

Using the Selectable Interaction

The selectable interaction allows the user to select one or more elements, either by dragging the mouse or by clicking individual elements. You apply the interaction through the selectable method as demonstrated in Listing 25-11.

Listing 25-11.  Applying the Selectable Interaction

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        div.flower {width: 200px; background-color: lightgrey; font-size: large;
            margin: 4px; text-align: center; border: medium solid black; padding: 4px;}
        #flowerContainer {position: absolute; left:10px}
        div.ui-selected {border: medium solid green; background-color: lightgreen}
        div.ui-selecting {border: medium solid green}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#flowerContainer").selectable();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="flowerContainer">
        <div id="flower_1" class="flower">Aster</div>
        <div id="flower_2" class="flower">Peony</div>
        <div id="flower_3" class="flower">Lily</div>
        <div id="flower_4" class="flower">Orchid</div>
    </div>
</body>
</html>

You apply the selectable interaction to the element that contains the elements you want the user to be able to select. In this case, I use the same div elements I used for the sortable interaction earlier in the chapter. I select the container and call the selectable method as follows:

...
$("#flowerContainer").selectable();
...

Although I have now applied the selectable interaction to my container, I need to define a pair of CSS styles for specific classes to give the user visual feedback. Here are the styles I associated with these classes:

...
div.ui-selected {border: medium solid green; background-color: lightgreen}
div.ui-selecting {border: medium solid green}
...

The selectable interaction applies these classes to my elements to reflect their selection status. The ui.selecting class is applied when the user is dragging the mouse to select the elements in a specific area, and the ui-selected class is applied when an element has been selected (either because the user has clicked the element or because it was in the area covered by a mouse drag). I used simple styles that just apply green borders and backgrounds. You can see the effect of selecting elements by dragging the mouse in Figure 25-7.

9781430263883_Fig25-07.jpg

Figure 25-7. Selecting elements with a mouse

The user must start dragging the mouse within the container element to start the selection process. You can see the outline of the area that has been selected (known as the marquee) in the middle frame of the figure—at that point, jQuery UI has applied the ui-selecting class. When the mouse is released, the elements that the marquee overlaps are selected and the ui-selected class is applied, as shown in the last frame of the figure.

The user can also select elements by clicking on them. Multiple elements can be selected, and holding the Control/Meta key allows for noncontiguous selections. If you find that clicking causes a single selected element to toggle, you need the addition shown in Listing 25-12.

Listing 25-12.  Enabling Multiple Element Selection for the Selectable Interaction

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#flowerContainer")
            .bind("mousedown", function(e) {e.metaKey = true;})
            .selectable();
    });
</script>
...

When the user presses the mouse button, the ui-selecting class is applied. The ui-selected class is applied when the mouse button is released.

Configuring the Selectable Interaction

You can configure the selectable interaction using the settings described in Table 25-6.

Table 25-6. Selectable Settings

Setting Description
disabled When true, the interaction is initially disabled. The default is false.
autoRefresh When true, the interaction refreshes the size and position of each of the selectable elements at the start of each select operation. The default is true.
cancel A selector string that prevents matching elements from being selected.
delay See the delay setting on the draggable interaction in Chapter 24.
distance See the distance setting on the draggable interaction in Chapter 24.
filter A selector used to match selectable elements in the container. The default is *, which matches all elements.

Most of these settings are self-evident or are the same as for other interactions. Of particular interest, though, is the cancel setting, which you can use to make elements unselectable by the user. Listing 25-13 demonstrates.

Listing 25-13.  Using the cancel Setting

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#flowerContainer")
            .bind("mousedown", function(e) {e.metaKey = true;})
            .selectable({
                cancel: "#flower_3"
            });
    });
</script>
...

In this script, I use a selector that prevents the element with the ID of flower_3 from being selected. This works well when the user is selecting elements by clicking on them, but it doesn’t prevent selection by dragging. For this reason, use the cancel setting with care.

Using the Selectable Interaction Methods

The selectable interaction defines only one unique method, as described in Table 25-7. The other methods are those that are common to all widgets and interactions.

Table 25-7. Selectable Methods

Method Description
selectable("destroy") Removes the interaction from the element
selectable("disable") Disables the selectable interaction
selectable("enable") Enables the selectable interaction
selectable("option") Changes one or more settings
selectable("refresh") Refreshes the selectable interaction; this is the manual alternative to using false for the value of the autoRefresh setting

Using the Selectable Interaction Events

The selectable interaction defines the events shown in Table 25-8.

Table 25-8. Selectable Methods

Event Description
create Triggered when the interaction is applied to an element.
selected Triggered when an item has been selected. If multiple items have been selected, this event will be triggered once for each of them.
selecting Triggered when the user has started the selection process (by pressing the mouse button or by dragging the mouse).
unselected Triggered when an item has been unselected. If multiple items have been unselected, this event will be triggered once for each of them.
unselecting Triggered when the user has started the unselection process by pressing the mouse button.

jQuery UI provides additional information for most of these events through a ui object. For the selected and selecting events, the ui object has a property called selected, which contains the HTMLElement corresponding to the element that has been (or is about to be) selected. For the unselected and unselecting events, the ui object has an unselected property that performs the same purpose.

Using the Resizable Interaction

The resizable interaction adds drag handles to elements that allow them to be resized by the user. Some browsers do this automatically with text areas, but the resizable interaction lets us apply this feature to any element in a document. Listing 25-14 shows the application of the resizable interaction that you perform using the resizable method.

Listing 25-14.  Applying the resizable Interaction

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        #aster, #lily {text-align: center; width: 150px; border: thin solid black;
            padding: 5px; float: left; margin: 20px}
        #aster img, #lily img {display: block; margin: auto}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#aster").resizable({
                alsoResize: "#aster img"
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="aster" class="ui-widget">
        <img src="aster.png" />
        Aster
    </div>
    <div id="lily" class="ui-widget">
        <img src="lily.png" />
        Lilly
    </div>
</body>
</html>

In Listing 25-14, I created two div elements whose contents are an img and some text. I select one of these in the script and apply the resizable method (using the alsoResize setting, which I’ll describe later in this chapter). jQuery UI adds a drag handle to the selected element, allowing me to resize it vertically and horizontally, as shown in Figure 25-8. In the figure, I increased the height of the element and reduced the width.

9781430263883_Fig25-08.jpg

Figure 25-8. Using the drag handle to change the dimensions of a resizable element

Configuring the Resizable Interaction

You can configure the resizable interaction using the settings described in Table 25-9. The resizable interaction relies on the draggable interaction I described in Chapter 24. This means that, in addition to the settings described in the table, you can configure the resizable interaction using the draggable settings as well, including delay, distance, grid, and containment.

Table 25-9. Resizable Settings

Setting Description
alsoResize A selector used to match elements that should be resized at the same time as the resizable element. The default is false, meaning no other elements are resized.
aspectRatio When true, the element’s aspect ratio is preserved when resized. The default is false.
autoHide When true, the drag handles are visible only when the mouse hovers over the resizable element. The default is false.
ghost When true, a semitransparent helper element is drawn to show the user what the new size of the element will be. The default is true.
handles Specifies where the drag handles will be placed on the resizable element. See later in this chapter for a list of supported values.
maxHeight Specifies the maximum height that the element can be resized to. The default is null, meaning no limit.
maxWidth Specifies the maximum width that the element can be resized to. The default is null, meaning no limit.
minHeight Specifies the minimum height that the element can be resized to. The default is 10 pixels.
minWidth Specifies the minimum width that the element can be resized to. The default is 10 pixels.

Resizing Related Elements

To my mind, alsoResize is the most useful setting for configuring the resizable interaction. It allows you to specify additional elements that will be resized along with the element to which you applied the resizable method. I use this mainly to ensure that content elements are resized in sync with their parent, as I demonstrated earlier in the chapter when I selected the img element to be resized with the div. First of all, it helps to understand what happens when you have content elements and don’t use the alsoResize setting. Listing 25-15 sets the scene.

Listing 25-15.  Resizing an Element with Content Without the alsoResize Setting

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#aster").resizable();
    });
</script>
...

Without the alsoResize setting, only the div element will change size. The content elements will be left as they are. You can see what happens in Figure 25-9.

9781430263883_Fig25-09.jpg

Figure 25-9. Resizing an element, but not its content

There are times when this is useful, but I find myself using the alsoResize setting almost every time I use the resizable interaction. For me, the neat thing about the alsoResize setting is that the matched elements are not limited to the contents of the element you are resizing. You can specify any element, as Listing 25-16 shows.

Listing 25-16.  Resizing Additional Elements with the alsoResize Setting

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#aster").resizable({
            alsoResize: "#aster img, #lily, #lily img"
        });
    });
</script>
...

In this script, I broadened the selection to include the other div and img elements in the document. This means that when I resize the resizable div element, jQuery UI resizes four elements simultaneously. You can see the effect in Figure 25-10.

9781430263883_Fig25-10.jpg

Figure 25-10. Resizing multiple elements

Constraining the Resizable Element Size

You can limit the size of resizable elements by applying the maxHeight, maxWidth, minHeight, and minWidth settings. The value for all four settings is a number of pixels or null, meaning that there is no limit. Listing 25-17 shows how you can use these settings.

image Tip  The default values for the minWidth and minHeight settings are 10 pixels. If the value is any smaller, jQuery UI cannot display the drag handles, which means the user would be unable to increase the size again. Use smaller values with caution.

Listing 25-17.  Limiting the Size of a Resizable Element

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#aster").resizable({
            alsoResize: "#aster img",
            maxWidth: 200,
            maxHeight: 150
        });
    });
</script>
...

image Tip  You can also use the containment setting that is defined by the draggable interaction, which I described in ­Chapter 24. This allows you to limit the maximum size of a resizable element to the size of another element.

Positioning the Drag Handles

You can specify which edges and corners can be dragged through the handles setting. The value for this setting is either all (meaning that all edges and corners are draggable) or a combination of compass points (n, e, s, w, ne, se, nw, sw) to specify individual corners and edges.

You can specify multiple values, separated by commas. The default value for this setting is e, s, se, which means that the lower-right corner (se) and the right (e) and bottom (s) edges will be draggable. jQuery UI draws a diagonal drag handle only in the lower-right corner and only if you have specified se as part of the handles value. For all other edges and corners, the cursor will change to indicate that dragging is possible when the mouse hovers above the edge or corner. Listing 25-18 shows the use of the handles setting.

Listing 25-18.  Using the handles Setting

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#aster").resizable({
            alsoResize: "#aster img"
        });
          
        $("#lily").resizable({
            alsoResize: "#lilyimg",
            handles: "n, s, e, w"
              
        });
    });
</script>
...

In this script, I made both div elements resizable and applied a custom set of drag handles to one of them. You can see how jQuery UI handles the visible drag handles and the cursor change in Figure 25-11.

9781430263883_Fig25-11.jpg

Figure 25-11. Using the handles setting

Summary

In this chapter, I explained and demonstrated three of the jQuery UI interactions: sortable, selectable, and resizable. These are less commonly used than the draggable and droppable interactions I described in Chapter 24, but they can still be useful if applied carefully. As with all of the interactions, the main challenge is in making the user aware that he or she can drag, select, sort, or resize an element when there are no standardized visual cues in web applications. For that reason, the interactions should be used as supplements to other mechanisms for interacting with your application or document. This allows advanced users to discover the advantages of the interactions, while other users rely on more obvious and conventional techniques.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.170.134