C H A P T E R  33

Using the jQuery Utility Methods

jQuery includes a number of utility methods that perform advanced operations on jQuery objects or that supplement the JavaScript language to provide features that are usually present in programming languages. You might never need any of these methods, but they are used internally by jQuery, and making them publicly available means that you can save time and effort when you come across an odd problem that the jQuery team has already solved.

Some of these methods are applied to jQuery objects, and some are called against the main jQuery function, which I have illustrated using the $ notation (described in Chapter 5). Table 33-1 provides the summary for this chapter.

Image

Image

Queues Revisited: Using General-Purpose Queues

In Chapter 10, I showed you how you could use the jQuery effects queue to manage a chain of effects to apply to a set of elements. In fact, the effects queue is just one queue and the feature is a general-purpose one you can use more widely. Table 33-2 restates the queue-related methods, tweaked for general-purpose use.

Image

When you use these methods without specifying a queue name, jQuery defaults to fx, which is the queue for visual effects. You can use any other queue name to create a queue of functions.

When applying jQuery queues to general use, you use the clearQueue method instead of the stop method. Stop has special support for jQuery effects that are not appropriate for broader use. Listing 33-1 provides an example of using a general-purpose queue.

Listing 33-1. Using a queue

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-1.7.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <script type="text/javascript">
        $(document).ready(function() {
            
            var elems = $('input'),
                       
            elems.queue("gen", function(next) {
                $(this).val(100).css("border", "thin red solid");
                next();
            });

            elems.delay(1000, "gen");

            elems.queue("gen", function(next) {
                $(this).val(0).css("border", "");
                $(this).dequeue("gen");
            });

           $("<button>Process Queue</button>").appendTo("#buttonDiv")
                .click(function(e) {
                    elems.dequeue("gen");
                    e.preventDefault();
                })

        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post">
        <div id="oblock">        
            <div class="dtable">
                <div id="row1" class="drow">
                    <div class="dcell">
                        <img src="astor.png"/><label for="astor">Astor:</label>
                        <input name="astor" value="0" required />
                    </div>
                    <div class="dcell">
                        <img src="daffodil.png"/><label for="daffodil">Daffodil:</label>
                        <input name="daffodil" value="0" required />
                    </div>
                    <div class="dcell">
                        <img src="rose.png"/><label for="rose">Rose:</label>
                        <input name="rose" value="0" required />
                    </div>                
                </div>
                <div id="row2"class="drow">
                    <div class="dcell">
                        <img src="peony.png"/><label for="peony">Peony:</label>
                        <input name="peony" value="0" required />
                    </div>
                    <div class="dcell">
                        <img src="primula.png"/><label for="primula">Primula:</label>
                        <input name="primula" value="0" required />
                    </div>
                    <div class="dcell">
                        <img src="snowdrop.png"/><label for="snowdrop">Snowdrop:</label>
                        <input name="snowdrop" value="0" required />
                    </div>            
                </div>
            </div>
        </div>
        <div id="buttonDiv"><button type="submit">Place Order</button></div>
    </form>
</body>
</html>

In this example, I add three functions to a queue called gen that operates on the input elements in the document. First, I use the val method to set all of the input values to 100 and the css method to add a border. Second, I use the delay method to add a 1-second delay to the queue. Finally, I use the val and css methods to reset the input elements to their original state.

I also added a button to the document that calls the dequeue method. Unlike with the effects queue, you are responsible for starting queue processing yourself. You can see the effect in Figure 33-1.

Image

Figure 33-1 Using a general-purpose queue

The functions that you place in the queue work in the same way as for the events queue and, as before, you are responsible for either calling the dequeue method or invoking the function that is passed as an argument. I tend to use the function argument—just because I often forget to specify the queue name when calling the dequeue method, which means that my queue grinds to a halt.

Manually Processing Queue Items

Of course, you don't have to trigger one queued function from another. You can rely on an external trigger to dequeue each item, such as the user pressing the button I added to the document. Listing 33-2 shows how you can do this.

Listing 33-2. Dequeuing functions explicitly

...
<script type="text/javascript">
    $(document).ready(function() {
                           
        $('input').queue("gen", function() {
            $(this).val(100).css("border", "thin red solid");
        }).queue("gen", function() {
            $(this).val(0).css("border", "");
        }).queue("gen", function() {
            $(this).css("border", "thin blue solid");
            $('#dequeue').attr("disabled", "disabled");
        });
        
       $("<button id=dequeue>Dequeue Item</button>").appendTo("#buttonDiv")
            .click(function(e) {
                $('input').dequeue("gen");          
                e.preventDefault();
            });              
    });     
</script>
...

In this script, I chained the queue calls together and added a function that sets a border on the selected elements and disables the button element. You must press the button to process each item in the queue—here is no automated chaining. You can see the sequence in Figure 33-2.

Image

Figure 33-2 Manually processing a queue

Utility Methods for Arrays

jQuery provides a number of useful methods for working with arrays. These methods are described in Table 33-3. For the most part, there are better ways of working with HTMLElement arrays—you can just use the standard jQuery methods for handling and filtering elements. For other kinds of arrays, these methods can be helpful.

Image

Using the grep Method

The grep method allows you to find all of the elements in an array that are matched by a filter function. Listing 33-3 provides a demonstration of this method.

Listing 33-3. Using the grep method

...
<script type="text/javascript">
    $(document).ready(function() {        
        var flowerArray = ["astor", "daffodil", "rose", "peony", "primula", "snowdrop"];
        
        var filteredArray = $.grep(flowerArray, function(elem, index) {
            return elem.indexOf("p") > -1;
        });
        
        for (var i = 0; i < filteredArray.length; i++) {
            console.log("Filtered element: " + filteredArray[i]);
        }
    });     
</script>
...

The filter function is passed two arguments. The first is the element in the array, and the second is the array index of that element. This function is called for each item in the array and you return true if you want the current item to be included in the filtered results.

In this example, I use the grep method on an array of strings, filtering out those that don't contain the letter p. I write the contents of the filtered array to the console, producing the following results:


Filtered element: peony
Filtered element: primula
Filtered element: snowdrop

You can supply an additional argument to the grep method. If this argument is true, the filtering process is inverted and the result contains the elements that the function filtered out. Listing 33-4 shows the effect of this argument.

Listing 33-4. Inverting the selection using the grep method

...
<script type="text/javascript">
    $(document).ready(function() {
        
        var flowerArray = ["astor", "daffodil", "rose", "peony", "primula", "snowdrop"];
        
        var filteredArray = $.grep(flowerArray, function(elem, index) {
            return elem.indexOf("p") > -1;    
        }, true);
        
        for (var i = 0; i < filteredArray.length; i++) {
            console.log("Filtered element: " + filteredArray[i]);
        }
        
    });     
</script>
...

This change produces the following results:


Filtered element: astor
Filtered element: daffodil
Filtered element: rose

Using the inArray Method

The inArray method lets you establish whether an array contains a specified value. The method returns the index of the item if it is in the array and -1 otherwise. Listing 33-5 demonstrates the inArray method.

Listing 33-5. Using the inArray method

...
<script type="text/javascript">
    $(document).ready(function() {
        var flowerArray = ["astor", "daffodil", "rose", "peony", "primula", "snowdrop"];

        console.log("Array contains rose: " + $.inArray("rose", flowerArray));
        console.log("Array contains lily: " + $.inArray("lily", flowerArray));
    });     
</script>
...

This script checks to see if the array of flowers contains rose and lily. The results are as follows:


Array contains rose: 2
Array contains lily: -1

Using the map Method

The map method lets you use a function to project the contents of an array or a map object into a new array, using a function to determine how each item is represented in the result. Listing 33-6 shows the use of the map method with an array.

Listing 33-6. Using the map method to project an array

...
<script type="text/javascript">
    $(document).ready(function() {
        var flowerArray = ["astor", "daffodil", "rose", "peony", "primula", "snowdrop"];

        var result = $.map(flowerArray, function(elem, index) {
            return index + ": " + elem;
        });
        
        for (var i = 0; i < result.length; i++) {
            console.log(result[i]);
        }
     });     
</script>
...

This mapping function is executed for each item in the array and is passed the item and its index in the array as arguments. The result from the function is included in the array returned by the map method. In this script, I transform each item in the array by concatenating the value with its index, producing the following results:


0: astor
1: daffodil
2: rose
3: peony
4: primula
5: snowdrop

You can use the map method to selectively project an array. There will be no corresponding item in the result if you don't return a value from the function for the item being processed. Listing 33-7 shows how you can selectively project from an array.

Listing 33-7. Selectively mapping an array

...
<script type="text/javascript">
    $(document).ready(function() {
        var flowerArray = ["astor", "daffodil", "rose", "peony", "primula", "snowdrop"];

        var result = $.map(flowerArray, function(elem, index) {
            if (elem != "rose") {
                return index + ": " + elem;
            }
        });
        
        for (var i = 0; i < result.length; i++) {
            console.log(result[i]);
        }     
    });     
</script>
...

Results are generated for all of the array values except rose, which gives rise to the following results:


0: astor
1: daffodil
3: peony
4: primula
5: snowdrop

Using the merge Method

The merge method concatenates two arrays, as demonstrated in Listing 33-8.

Listing 33-8. Using the merge method

...
<script type="text/javascript">
    $(document).ready(function() {
        
        var flowerArray = ["astor", "daffodil", "rose", "peony", "primula", "snowdrop"];
        var additionalFlowers = ["carnation", "lily", "orchid"];

        $.merge(flowerArray, additionalFlowers);
        
        for (var i = 0; i < flowerArray.length; i++) {
            console.log(flowerArray[i]);
        }
     });     
</script>
...

The items from the second array are appended to the first array, and the array specified by the first argument is modified by the merge process. The script in the example produces the following results:


astor
daffodil
rose
peony
primula
snowdrop
carnation
lily
orchid

Using the unique Method

The unique method sorts an array of HTMLElement objects into the order in which they appear in the document and removes any duplicate elements. Listing 33-9 shows how you can use this method.

Listing 33-9. Using the unique method

...
<script type="text/javascript">
    $(document).ready(function() {
        
        var selection = $('img[src*=rose], img[src*=primula]').get();
        $.merge(selection, $('img[src*=astor]'));
        $.merge(selection, $('img'));

        $.unique(selection);

        for (var i =0; i < selection.length; i++) {
            console.log("Elem: " + selection[i].src);
        }

    });     
</script>
...

The sorting process is done in-place, meaning that the array you pass as the argument to the unique method is modified. In this example, I created an array of HTMLElement objects that contain duplicates and that are not in document order, and then I applied the unique method.

Utility Methods for Types

jQuery provides a set of methods that are useful for determining the nature of a JavaScript object. These methods are described in Table 33-4.

Image

Most of these methods are very simple. You pass an object to the method, which returns true if the object is of the type that the method detects and false otherwise. As a simple demonstration, Listing 33-10 contains an example using the isFunction method.

Listing 33-10. Using the isFunction method

...
<script type="text/javascript">
    $(document).ready(function() {

        function myFunc() {
            console.log("Hello!");
        }

        console.log("IsFunction: " + $.isFunction(myFunc));
        console.log("IsFunction: " + $.isFunction("hello"));
    });     
</script>
...

In this example, I use the isFunction method to test two objects. The results are as follows:


IsFunction: true
IsFunction: false

Using the type Method

The type method is slightly different in that it returns the base JavaScript type of an object. The result will be one of the following strings:

  • boolean
  • number
  • string
  • function
  • array
  • date
  • regexp
  • object

Listing 33-11 shows the use of the type method.

Listing 33-11. Using the type method

...
<script type="text/javascript">
    $(document).ready(function() {

        function myFunc() {
            console.log("Hello!");
        }

        var jq = $('img'),
        var elem = document.getElementById("row1");

        console.log("Type: " + $.type(myFunc));
        console.log("Type: " + $.type(jq));
        console.log("Type: " + $.type(elem));
    });
</script>
...

In this script, I use the type method on a function, a jQuery object, and an HTMLElement object. The results are as follows:


Type: function
Type: object
Type: object

Utility Methods for Data

jQuery defines a number of utility methods that can be useful for working with various kinds of data. These methods are described in Table 33-5.

Image

Serializing Form Data

The serialize and serializeArray methods are convenient ways to extract the details from a set of form elements in a way that is useful for regular or Ajax form submissions. Listing 33-12 shows both methods in use.

Listing 33-12. Serializing form data

...
<script type="text/javascript">
    $(document).ready(function() {

       $("<button>Serialize</button>").appendTo("#buttonDiv").click(function(e) {

            var formArray = $('form').serializeArray();
            console.log("JSON: " + JSON.stringify(formArray))

            var formString = $('form').serialize();
            console.log("String: " + formString)

            e.preventDefault();        
        });              

    });     
</script>
...

In this example, I serialize the form elements in the document using both methods and write the results to the console. The serializeArray method returns a JavaScript array that contains one object for each form element in the document. These objects have two properties: the name property contains the value of the name attribute of the element, and the value property contains the element's value. Here is the output from the example document:


[{"name":"astor","value":"1"},{"name":"daffodil","value":"0"},
 {"name":"rose","value":"0"},{"name":"peony","value":"0"},
 {"name":"primula","value":"2"},{"name":"snowdrop","value":"0"}]

By contrast, the serialize method creates an encoded string, as follows:


astor=1&daffodil=0&rose=0&peony=0&primula=2&snowdrop=0

Parsing Data

The parseJSON and parseXML methods are especially useful when dealing with the results of Ajax requests. For most web applications, JSON has taken over as the data format of choice, for the reasons I outlined in Chapter 14. XML is still used, but I find myself using this XML data only when integrating new applications with legacy back-end systems. Listing 33-13 shows the parseJSON method in use.

Listing 33-13. Parsing JSON data

...
<script type="text/javascript">
    $(document).ready(function() {

       $("<button>Serialize</button>").appendTo("#buttonDiv").click(function(e) {

            var jsonData = '{"name": "Adam Freeman", "city": "London", "country": "UK"}'
                        
            var dataObject = $.parseJSON(jsonData)

            for (var prop in dataObject) {
                console.log("Property: " + prop + " Value: " + dataObject[prop])
            }

            e.preventDefault();        
        });              

    });     
</script>
...

In this example, I define a simple JSON string and use the parseJSON method to convert it into a JavaScript object. I then enumerate the properties in the object and their values to the console, producing the following output:


Property: name Value: Adam Freeman
Property: city Value: London
Property: country Value: UK

Trimming Strings

The trim method removes all of the whitespace from the start and end of string. This includes spaces, tabs, and newlines. This is a feature that most programming languages support as part of their core handling of character data, but which is missing from JavaScript for some reason. Listing 33-14 shows the trim method in use.

Listing 33-14. Using the trim method

...
<script type="text/javascript">
    $(document).ready(function() {

       $("<button>Serialize</button>").appendTo("#buttonDiv").click(function(e) {

            var sourceString = "   This string contains whitespace    ";
            console.log(">" + sourceString + "<")
                        
            var resultString = $.trim(sourceString);
            console.log(">" + resultString + "<")

            e.preventDefault();        
        });              

    });     
</script>
...

In this example, I use the trim method and write the original and trimmed strings to the console, producing the following results:


>
  This string contains whitespace    <
>This string contains whitespace<

Other Utility Methods

A number of jQuery methods don't neatly fit into another category, but they can still be very useful. These are described in Table 33-6.

Image

Checking Element Containment

The contains method lets you check to see if one element contains another. Both arguments are expressed as HTMLElement objects, and the method returns true if the element represented by the first argument contains the element represented by the second argument. Listing 33-15 provides a demonstration of the contains method.

Listing 33-15. Using the contains method

...
<script type="text/javascript">
    $(document).ready(function() {
        $('img').hover(function(e) {
            var elem = document.getElementById("row1");
            if ($.contains(elem, this)) {
                $(e.target).css("border", e.type == "mouseenter" ?
                                            "thick solid red" : "");
            }
        });         
    });     
</script>
...

In this script, I obtain an HTMLElement object using the DOM API and check to see that it contains the element passed to an event handler method. If it does, I set a border for the element that triggered the event.

Image Tip This method only works on HTMLElement objects. If you want to perform the same check on jQuery objects, consider using the find method, which I describe in Chapter 6.

Creating a Proxy Function

The proxy method allows you to create a function whose this variable is always an object that you specify. Listing 33-16 shows how the proxy method can be used.

Listing 33-16. Using the proxy method

...
<script type="text/javascript">
    $(document).ready(function() {
        $('img').hover($.proxy(handleMouse, $('img').eq(0)));

        function handleMouse(e) {
            $(this).css("border", e.type == "mouseenter" ? "thick solid red" : "");
        }
    });     
</script>
...

This example contains a function called handleMouse that sets the border on the element represented by the this variable in response to mouse events. I used the proxy function to create a wrapper around the handleMouse function, which ensures that the value of this is always set to the first img element in the document. The effect of using the proxy method is that regardless of which img element triggers the mouse event, the border is always applied to the first img element.

Image Tip This method is not widely used—not least because only the this variable is changed. As a consequence, the proxy method has no real effect if you are in the habit of using the Event.target property to find out which element triggered the event, for example.

Summary

In this chapter, I described the jQuery utility methods—an eclectic set of helpful functions that can be used to perform advanced operations on jQuery objects or that supplement the JavaScript language features to provide support that programmers commonly need. These are the kinds of methods you are glad exist when you need them, but you can safely forget about them for most web application projects.

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

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