C H A P T E R  3

Common jQuery Features, Actions, and Methods

In this chapter, you will begin to see how you can use jQuery to work with HTML elements. You will start with what is arguably the most powerful of the features, and that is the jQuery selector. The selectors make working with elements in your application a cinch. You will also see the various ways you can create new elements and use the jQuery utilities. Finally, you will learn about the rich set of tools available to manipulate, transform, and handle events in your HTML.

Hello World

Creating an application page that has jQuery loaded will give you an excellent basis to begin learning what you can do using jQuery. In the first few examples, you will work with some of the main concepts, and the later examples will build upon the knowledge gained.

In the previous chapter, you explored the different ways you can make jQuery available to your environment and how to load jQuery to the SharePoint page. Apart from looking at the HTML of the page, there has been no real way to test that it has loaded correctly. Now that you have read about the basics of jQuery, it's time you wrote the obligatory “Hello World” example. You should already have deployed jQuery to your SharePoint environment and have it loading to a page using one of the methods discussed in the previous chapter.

To get started with the first “Hello World” example, open Visual Studio 2010 and use the Empty SharePoint Project template to create a project called MyjQueryApplicationPage, as shown in Figure 3-1.

images

Figure 3-1. Using the Empty SharePoint Project template to deploy the application page

In the SharePoint Customization Wizard, enter the URL you want to use to test the deployment of this application page, choose “Deploy as a farm solution,” and click Finish. The application page gets deployed to the Layouts folder, which is why you need to choose a farm solution.

Next, add a new Application Page item called jQueryBasics.aspx, and open the file once it's created. You should be able to see the different content placeholders available to you from the default master page. Because I have opted to use the Site Actions method of adding jQuery to the page, I do not need to put anything in the head section. However, if you wanted to have only jQuery available to this page, you could have used the “Adding script” reference from within an application page, as described inChapter 2.

Change the contents in the PageTitle content placeholder to jQuery Basics and the PageTitleInTitleArea to My jQuery Basics Page. I recommend deploying this page as it is just to make sure it loads correctly; there's nothing worse than wondering what's up with your jQuery code when it was just the page all along. If it's working fine, then you're good to add your first jQuery code. The solution has put the application page only on the file system (in the Layouts folder), so the only way you can get to it is to navigate to its URL directly:

http://sharepoint/_layouts/MyjQueryApplicationPage/jQueryBasics.aspx

You should see an empty page (how exciting), but it should have a title of My jQuery Basics Page, as shown in Figure 3-2.

images

Figure 3-2. Testing an application page to make sure it works

Close the browser or click the Stop button in Visual Studio to stop debugging the application page. Now you're ready to add the first lines of jQuery.

Within the Main content placeholder, add the following code, which shows an alert when the page is ready. If you refer to the previous chapter, this piece of functionality was used to show that jQuery has loaded; its exact functionality will be explained later in the chapter.

$(document).ready(function() {
    alert('Hello World!'),});

Deploy the solution again, and you should see the alert dialog once the page has loaded.

jQuery Basics

jQuery is most often used through its $ alias; in fact, you will see this symbol everywhere. The $ symbol is a shortcut for the jQuery() global function, and you will be writing it so much that you will be glad of the five characters it saves each time. But if you use the $ symbol in your own code or a third-party library, it could override the use of the symbol, causing your code not to work as expected. To make sure there are no conflicts when using the $, you can call jQuery.noConflict(), which will ensure that the jQuery function is the one being used.

The jQuery() Function

You can overload the jQuery() function (or $()) in four ways. It can be passed in a CSS selector; in a Document, Element, or Window object; in a string of HTML; or finally in a function. It also has a few utility functions that you will be learning about. Using CSS selectors is the most common, so you will be exploring them first.

jQuery(selector)

Using jQuery selectors makes working with elements on your page orders of magnitude easier than if you were just working with the JavaScript method of getObjectById(), as you will see in the later examples. jQuery allows you to select elements from the HTML document using the same selectors as available to you in CSS as well as a few more advanced selectors that will be covered later. By using just the selectors, all you're doing is returning those Document Object Model (DOM) elements, which does nothing on its own. In the next section, you'll add methods that will act on the group of elements you're returning from a query.

A few different selector types are available to help you select the elements that you want. It's worth noting at this point that in SharePoint there usually won't just be the HTML elements you have created on the page. The master page will be loading all of the standard SharePoint functionality. This is fantastic if you want to be able to select and work with the SharePoint elements, but if you're not selecting your own specific elements, then you may be interfering with SharePoint functionality. Selecting and editing the SharePoint UI may cause unforeseen issues and is not supported.

Basic Selectors

Table 3-1 lists the basic selectors.

images

Let's try these selectors straightaway to see them in action; open the MyjQueryApplicationPage project in Visual Studio and edit the jQueryBasics.aspx file. Remove the existing contents of the PlaceHolderMain and PageHolderAdditionalPageHead content placeholders and replace the contents so they look like the following:

<asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead"
runat="server">
    <script type="text/javascript">
        $(document).ready(function () {
            // All Elements
            $('*').css('background-color', '#ADD8E6'),
        });
    </script>
</asp:Content>

<asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
    <div id="myId">
        <p class="myClass">class is set to myClass</p>
        <p>Just a plain paragraph</p>
        <p class="myClass">class is also set to myClass</p>
    </div>
</asp:Content>

In this code, you are still using the document ready functionality. This time, however, when the DOM has loaded, it will execute the selector and set the CSS of the elements returned to a blue color. Once you have made the change to the code, recompile it and deploy to your SharePoint environment. You will notice that everything is blue; this is because the selector used in this first example is selecting all the elements on the page and setting their backgrounds to blue.

Now try the second example for Table 3.1, replacing $('*') with $('#myId'). This will change just the background of the <div id='myId'> to blue. Compile the code again and deploy the solution. This time, you will see that just the div has been selected by the jQuery query and the css() method has set its color, as shown in Figure 3-3.

images

Figure 3-3. Setting the CSS of elements using the Id selector

Next, try to select just the elements with the myClass class by using $('.myClass'). You should see that just the elements with the class set are highlighted in the blue, as shown in Figure 3-4.

images

Figure 3-4. Selecting and setting CSS using the class selector

By now you should be beginning to see some of the potential of selectors. Once you begin to combine the selectors with the other functionality of jQuery such as manipulation, events, and visual effects, you will really see why jQuery is a tremendously powerful tool for developers.

The selectors that you have seen so far are the most basic available. You will use them the most throughout your applications, but sometimes you need to be able to create more powerful queries. The following sections will show you how you can further refine the queries to make sure you can easily and succinctly get the elements you need to work with.

Combining or Using Multiple Selectors

It is possible to combine selectors or use multiple selectors in order for you to have a more precise selection. For instance, if you wanted to select just the elements with the class of myClass within the myId div, then you can combine the id selector and the element selector as follows:

$('#myId .myClass')

This will ensure that only elements inside the myId element are selected. As mentioned, this precision can make sure that your jQuery code does not affect any elements on the page, which it should not.

Using multiple selectors allows you to combine the results of two queries into one result set. For example, if you want to select all paragraph elements with the class myClass and all the paragraph elements with the myOtherClass too, you can use the following syntax:

$('p.myClass, p .myOtherClass)
Hierarchy

HTML is mostly made up of nested elements, and the hierarchy selector allows for easy traversal of the DOM (see Table 3-2).

images

Using the same Visual Studio project as before, add the following div just below the one that already exists to enable you to see the hierarchy selectors in action.

    <div id="myDiv1">
        <p>
            Paragraph before List</p>
        <ul id="people">
            <li>Phill</li>
            <li>Pip</li>
            <li>Les</li>
            <li>Denise</li>
            <li>Martin</li>
            <li>Helen</li>
            <li></li>
        </ul>
        <p>
            Paragraph after List</p>
        <div>
            <p>
                Paragraph inside another div</p>
        </div>
    </div>

This time, change the jQuery method from the existing one to this one; you should know from Table 3-2 that this will select all li elements from the unordered list with the id attribute of people.

        $(document).ready(function () {
            $('ul#people > li').css('background-color', '#ADD8E6'),
        });

The result of this query and CSS method call will produce the page shown in Figure 3-5.

images

Figure 3-5. Selecting nested list items from an unordered list

Try working through the other examples from Tables 3.1 and 3.2 to see which elements get highlighted.

The next two sections introduce a way of filtering the elements that are queried by applying certain conditions on them.

Basic Filter

Filtering the selections allows for precise selection of the elements. Luckily, the jQuery filters are very comprehensive, and there are lots of different ways to make sure you can get only the elements needed as succinctly as possible. Another key benefit of using filters is that you can filter on their position in the DOM, state, or other variables without necessarily needing to know the element's type, ID, or class. Table 3-3 lists the filtering selectors.

images

Content Filter

As the name suggests, content filters allow you to select the elements based on their content, or lack thereof. The filter is not just restricted to the text in an element; it can also traverse to the parent element too. Table 3-4 lists the content filters.

images

Child Filter

A key point to remember with child filters is that unlike most of the index-based selectors, it starts its indexing at one and not zero.

If you have the following unordered list on your page:

         <ul id="people">
            <li>Phill</li>
            <li>Pip</li>
            <li>Les</li>
            <li>Denise</li>
            <li>Martin</li>
            <li>Helen</li>
            <li></li>
        </ul>

and you have the following code being executed in your application:

$('ul#people li:eq(2)').css({ background: "yellow" });

$('ul#people li:nth-child(2)').css({ background: "orange" });

you will see that the zero-based :eq(index) has selected Les and nth-child(index) has selected Pip, as shown in Figure 3-6.

images

Figure 3-6. Showing how the difference in index base affects the selection

Table 3-5 lists the child selectors.

images

Visibility Filter

This pair of filters is very handy when you want only certain elements of your DOM to be seen or hidden depending on the state of the application (see Table 3-6).

images

Attributes

Using attributes is a useful way to select elements. By being able to read any attribute, it makes it easy to select the elements that you want (see Table 3-7).

images

images

Form

More often than not, one of the requirements of an application is to capture data of some form or another, and having a specific set of filters to work with forms is brilliant. Let's add some more HTML to the existing application page to see how these filters behave and ideally gain an understanding of why they will be useful.

Add the following HTML after the last /div in the PlaceHolderMain content placeholder:

    <form action="#">
    <input type="button" value="Input Button" />
    <input type="checkbox" />
    <input type="file" />
    <input type="hidden" />
    <input type="image" />
    <input type="password" />
    <input type="radio" />
    <input type="reset" />
    <input type="submit" />
    <input type="text" />
    <select>
        <option>Option</option>
    </select>
    <textarea cols="10" rows="2">Text area</textarea>
    <button>
        Button</button>
    </form>

Table 3-8 lists the form selectors.

images

As with the other selectors you have seen, you are selecting only the elements. Try changing the existing jQuery code to set the border of these form elements using the examples in Table 3-8 (see Figure 3-7):

        $(document).ready(function () {
            $('input:button').css({ border: "3px blue solid" });
        });
images

Figure 3-7. Highlighting the button element using form selector

Setting the Selector Context

It is also possible to supply a context to the selector to limit its search scope to just elements within it, that is, jQuery(selector, [context]):

$('div.myClass').click(function() {
  $('p', this).Hide();
})

This code will hide all of the paragraphs, p, within the div with class myClass. If you did not supply the context, it would hide all of the p elements on the page.

Passing in a Document, Element, or Window to jQuery()

It is possible to pass in a Document, Element, or Window to the jQuery wrapper to enable it to use the jQuery methods you have at your disposal. Wrapping the document object and using the ready() method is a common way to put jQuery code into your script and wait until the DOM is available before executing the function. This technique is usually employed when wiring up your events to elements on the page because it needs to have the HTML elements to bind to.

The following code, which we will revisit later, gives an example of wrapping the document object and using the ready() method to add a click() event handler to a button.

$(document).ready(function() {
        $('#myButton').click(function())
               {
                 // Do something;
               };
});
Passing in a String of HTML to jQuery(html)

The other methods that you have seen so far have been querying and selecting elements, which already exist in the DOM. By passing in HTML, you are able to create and insert new elements into the DOM on the fly. This method is particularly useful when you are working with data returned from a web service, because you can use the data to create new elements on the page easily.

var myData = GetMeData();
$.each(myData, function(index, value) {
    $('<li>' + value + '</li>').appendTo('#myDataList'),
 });

In this example, we are getting our data and using the $.each() utility. We are iterating through each item and creating a new list item, li, and appending it to our list with the id attribute of myDataList. You will notice that you need to include the full HTML tag with the angle brackets; this is to ensure that jQuery does not try to interpret it as a CSS selection.

Let's take a look at creating a little example to see how you can update the DOM on the fly. This code will use the HTML already written in this chapter.

        $(document).ready(function () {
            
            // Create an array of the new people to add
            var newPeople = ["Sam", "Zoe", "Graeme", "Gemma"];

            // Use the each method to iterate through array
            $.each(newPeople, function (index, value) {
                
                // Create new List Item and append it to the people unordered list
                $('<li>' + value + '</li>').appendTo('ul#people'),
            });

        });

The list of people that contains Phill, Pip, Les, Denise, Martin, and Helen now has four more values: Sam, Zoe, Graeme, and Gemma, as shown in Figure 3-8.

images

Figure 3-8. List item elements being dynamically added to a list

This functionality of being able to write HTML is something that you will be doing in the full examples later in the book.

jQuery(callback)

You can use jQuery(function) or $(function) to call a function when the DOM is ready. This behaves in the same way that $(document).ready() does and can be used to call other $() functions on the page that require the DOM to have been loaded.

jQuery Utilities

jQuery also comes with a handy selection of utilities; you have seen one already, the each function. The utilities make working on the client side a lot easier for the developer. The following are some of the utilities you will likely be using:

  • $.each(function(index,Element)): A generic iterator function that can be used to iterate over objects and arrays
  • $.support: A collection of properties that represent the presence of different browser features or bugs
  • $.parseJSON: Takes a well-formed JSON string and returns the resulting JavaScript object.

Common jQuery Actions and Methods

By now you should begin to understand what jQuery can do in terms of querying the DOM and see how this allows you to easily select the elements on the page. It's time to move on and see how jQuery can work with the elements on the page.

First you'll learn how to manipulate the elements on the page. jQuery has a large array of tools at your disposal that you can use to manipulate the DOM. When you are creating your applications or SharePoint customizations, it is important to be able to update the user interface either to show the user that they need to perform a certain action, to highlight a value in a table, or to manipulate another part of the page to change its look and feel. This is where the DOM manipulation comes into play. jQuery allows the developer to easily manipulate the properties and attributes of the elements on the page, whether that is to change a CSS class or update the text to a new value.

Let's start by taking a look at a simple HTML element that can work as our base for testing the jQuery manipulation:

<p id="ManipulationTest">My Test Text</p>

In the previous chapter, you learned that in order to highlight the elements that were being selected by the queries, you use a jQuery method called css(). Let's take another look at that code and break down what it is doing:

$('p#ManipulationTest').css("background-color", "yellow");

The element on the page was initially being rendered in the same way as it was written on the application page, as the jQuery method was loaded. However, the element's attributes were updated with the new changes applied from jQuery:

<p id="ManipulationTest" style="background-color: yellow;">My Test Text</p>

You should notice that the style attribute has been added with the css style as its value. It is the manipulation of these name-value pairs that allows the developer to manipulate the elements on the page.

Attributes

This section covers the different ways you can manipulate the attributes of an element using jQuery. Table 3-9 summarizes how to work with attributes.

images

.attr()

The attr() method gives you the ability to get, set, or remove attributes on the element. If there is just the one argument passed to the method, then the value of the attribute will be returned. If the second argument is there, then the named attribute will be set to the value of the second parameter.

If you consider the following link, which you want to get the link for:

        <a href="http://NotSharePoint" id="myLink">Link</a>

the following code within the document function will show you the link destination:

        $(document).ready(function () {
            var linkLocation = $('a#myLink').attr('href'),
            alert(linkLocation);
        });

If you want to change the destination for the link, you can use the set attribute method to change its value. In this example, you will change the value and show what it used to be, keep the link on the page, but replace the script with the following:

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

        function ChangeLink() {
            // Read the href attribute
            var originalLinkLocation = $('a#myLink').attr('href'),
            
            // Set the href
            $('a#myLink').attr('href', "http://SharePoint");


            // Read the href attribute again
            var newLinkLocation = $('a#myLink').attr('href'),
            
            alert('Link was to ' + originalLinkLocation + ' now it is ' + newLinkLocation);
        }
        
    </script>

Figure 3-9 shows the result.

images

Figure 3-9. Alert showing the href attribute of the link

If you look at the HTML on the page, you can see that the link now points to the new location (seeFigure 3-10).

images

Figure 3-10. Viewing the updated source of the link

.prop()

The property method works in a similar way to the attr() method, but it will get, set, and remove properties from the element.

Class

The class methods allow for a simple way of working with the classes applied to an element (see Table 3-10).

images

Being able to dynamically change the classes on elements makes it easy to highlight areas or controls on the page as required. For instance, if you want to change a normal paragraph, p, to reflect a warning, you can add the SharePoint CSS warning class (.ms-warning).

addClass()

Add the following paragraph to your application page with a real-world warning:

<p id="myWarning">Caution, I am a developer</p>

Next you need to update the ready function again to apply the styling to the element after the DOM is ready:

        $(document).ready(function () {
            // Add the warning class to the myWarning paragraph
            $('p#myWarning').addClass('ms-warning'),
        });

The paragraph that contained no styling in the declarative HTML document now has the class applied (see Figure 3-11).

images

Figure 3-11. A stark warning with the .ms-warning class applied

If you take a look at the HTML, you can see it has a class of ms-warning, as shown in Figure 3-12.

images

Figure 3-12. You can see that the class is applied, which was not in the original HTML.

hasClass()

The hasClass() method can be used to check whether a class exists on a selected element and then returns either true or false.

HTML and Text

These two sets of methods have been combined because their purpose is a similar one, but there is one key distinction that changes how they are used. Both methods allow you to either read the value or set the value. However, with the html() method, you are getting or setting the inner HTML of the element, and the text() method is working with the content (see Table 3-11).

images

To show how these methods work and the difference between them, add the following HTML to your application page. These two divs will have their content dynamically set when the page loads:

    <div id="htmlDiv">
    </div>
    <div id="textDiv">
    </div>

Within the script tags on your page, update the code to update the two divs, specifically, the first htmlDiv using the html(htmlString) method and the textDiv using the text(textString) method:

        $(document).ready(function () {
            // Using the html method to set the innerHtml
            $("#htmlDiv").html('<a href="http://SharePoint">Link</a> - <b>HTML</b>'),
            
            // Using the text method to set the element content
            $("#textDiv").text('<a href="http://SharePoint">Link</a> - <b>TEXT</b>'),
        });

If you take a look at the results (see Figure 3-13), you will see that there is something quite different going on between the two methods.

images

Figure 3-13. Viewing the different output of HTML vs. text methods

Basically, the HTML version (the top line) is treating the string as HTML and renders it appropriately, whereas the text version (the second line) escapes the HTML in order to render it as plain text. Both methods have their uses, but it's important to realize what will happen when you are choosing which one to use.

Value

The value method is used mostly with form elements as a way of getting values entered by the user; it also has a set method that could be used to prepopulate some data into the element (see Table 3-12).

images

Using the following HTML, you can see how to work with the val methods:

    <input type="text" id="textOne" />
    <input type="text" id="textTwo" />

The following jQuery will get the value of the first text box and write it to the second text box as the user types in. Events have not yet been introduced in the book; all you need to know at this stage is that the code is getting the value from the first text box using $(this).val() and is setting the value in the second with $('input#textTwo').val(textOneValue). The this keyword is being used to get the object on which the event is running. In this example, it is the textOne input.

        $(document).ready(function () {
            // Add event to run on Key Up of the textOne input text box
            $('input#textOne').keyup(function () {
                // Get value from the textOne input text box
                var textOneValue = $(this).val();
                // Set value of the second text box to that of the first
                $('input#textTwo').val(textOneValue);
            });
        });

Deploy the solution and enter text into the first box; you will see it copied to the second box as the key is lifted up.

CSS

Table 3-13 lists the CSS functions.

images

.css()

In the first examples on selectors, the code was using the CSS method to set the background color of the elements.

For instance, if you wanted to set the following paragraph to have a yellow background color, you can set it using the following method:

<p id="myParagraph">I am stylish</p>

$('p#myParagraph').css("background-color", '"yellow");

It is also possible to set multiple CSS values at the same time using property-value pairs. If you look at the same paragraph but want to set the font weight at the same time, you can do it like this:

$(document).ready(function () {
    $('p#myParagraph').css({ 'background-color': 'yellow', 'font-weight': 'bold' });
});

The result will show that the plain paragraph now has a yellow background and its font weight is bold (see Figure 3-14).

images

Figure 3-14. Styled element using the CSS functions

Using css('parameterName), you can also retrieve individual CSS values; a difference worth noting is that it will bring back the units as well. For example, if you want to get the width of an element and use css(parameterName), you will get a result such as 300px. If you use just the width() method, then it excludes the unit. Using just the width() method is the jQuery recommendation if you are using the width value to perform a calculation.

Width and Height

You can use jQuery in different ways to get the dimension of your element, and the results vary because of what exactly they're measuring. Figure 3-15 shows the three different ways that the height can be obtained: height, innerHeight, and outerHeight.

images

Figure 3-15. Showing the different properties of an element. Copyright © 2011 W3C® (MIT, ERCIM, Keio), All Rights Reserved. http://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231

  • height(): Returns computed height of the content.
  • innerHeight(): Returns computed height including the padding but not the border.
  • outerHeight(true/false): Returns computed including padding and border. If you set the optional parameter to true, then you can include the margin in the result too.

The same applies to the width methods.

Offset

The offset() method can be used to find the coordinates of the element relative to the document as well as setting the value. The get method will return an object with left and top properties to allow you to retrieve the coordinates.

Place any element on the HTML page, and using the ID selector, get the element and use the offset() method on it. Here's an example:

HTML

  <p id="myParagraph">Where am I?</p>

jQuery Code

      $(document).ready(function () {
            var myOffset = $('p#myParagraph').offset();
            alert("Left offset: " + myOffset.left + " Top offset: " + myOffset.top);
        });

Running this code will show an alert with the coordinates of the element, as shown in Figure 3-16.

images

Figure 3-16. Using Position to find the offset of the element

Traversing

Traversing in jQuery gives the developer a way to walk the DOM by finding how elements are related to each other. Being able to select an element using jQuery is very easy to achieve, and the traversing methods takes the pain out of then refining the selection or simply exploring the HTML structure.

Filtering

Table 3-14 lists the filtering selection.

images

Tree Traversal

The tree traversal selectors make it easy to walk up or down the Document Object Model (DOM) tree to discover neighboring, parent, or child elements (see Table 3-15).

images

Miscellaneous

Table 3-16 lists the rest of the selectors.

images

The add method is really useful for adding extra elements to the collection, and the andself method allows you to add elements and make sure that the result from the first query is included too.

Events

For browser-based applications to have any kind of interaction, you need to be able to handle events that occur; these could be browser events or user events, such as a mouse click, browser ready, or page close.

If you're creating an application that is requiring the users to enter lots of details, the last thing you want them to do halfway through is accidentally click a link or the back button and lose five minutes of data entry. By handling events effectively, you can give the user a rich experience and ensure that the code executes appropriately when it is required.

Document Loading

There are three main types of document-loading event:

  • Load
  • Ready
  • Unload

Load: load(handler(eventObject))

The load() method binds an event handler to the load() JavaScript event, allowing code to be executed when the page has been loaded

.load(handler(eventObject)) takes a function handler(eventObject) to execute when the event is triggered. The load method can be called using .load([eventData], handler(eventObject)) to allow the developer to pass in a map of data to in turn be passed onto the event handler.

Ready: .ready(handler)

The ready() method is used to bind an event handler to execute as soon as the DOM has been loaded. This is important if you want to use the elements on the page, because they are not available until the DOM is ready. The ready function is commonly used to house the entire jQuery script:

$(document).ready(function(){
    // jQuery code here
});

I prefer to use the ready function to wire up all events to the required elements and put other JavaScript functions outside of this block.

To ensure that the jQuery alias works as it should, it is possible to pass in a parameter to the ready method to use as the alias for the jQuery() function. You can pass in the normal $ to ensure the alias will work, or you could even pass in your own alias, and it will still do as you would expect:

        jQuery(document).ready(function (CleverStuff) {
            CleverStuff("#myParagraph").text("I work when called CleverStuff!");
        });
Unload: unload(handler(eventObject))

The unload() method adds an event handler to handle events as the unload JavaScript event is called. The unload event is called when the user navigates away from the page. There are many different scenarios that can cause this event to fire:

  • Link has been clicked
  • New address has been typed into the address bar
  • Forward/back button has been clicked
  • Browser has been closed
  • Page has been refreshed

Because there are differences of how browsers handle the unload event, it is worth thoroughly testing on all supported browsers to check the exact behavior.

Handling Event Attachment

With a keyboard and mouse at hand or even a touchscreen, there are lots of ways that a user can raise an event within the browser. Whether it's selecting a choice from a drop-down menu, typing in their username, or double-clicking an icon, jQuery has really simplified handling these events, and in this section you will learn how to attach events and handle the interactions of your beloved users.

The first step to look at is binding and unbinding events. What is needed to handle an event successfully is to wire up the element with the event to fire upon. It's also possible for an element to have multiple events attached to it, such as a text box you can raise an event for when it gets the focus as well as when it is clicked, for example.

Bind()

Binding allows you to attach event handlers to elements to handle their events; this is a key tool for building interactive user interfaces.

.bind( eventType, [eventData], handler(eventObject) )

Take a look at the following example, which is using the bind method to attach the click event to all paragraphs (don't do this in your live SharePoint environment and blame me!). It will then call the function (see Figure 3-17).

        $(document).ready(function () {
            $('p').bind('click', function() {
                var pValue = $(this).text();
                alert(pValue);
            });
        });
images

Figure 3-17. Clicking the text will cause the alert the show.

Sometimes when an event is fired, you need to pass in additional information to the handling function to enable it to perform further functionality. There is an optional parameter on the bind method, which allows you to pass in a JSON-formatted object to the handling function. The data object is available within the handling function in the event.data object. It is worth mentioning that the jQuery documentation (http://api.jquery.com/bind/) says, “The event object is often unnecessary and the parameter omitted, as sufficient context is usually available when the handler is bound to know exactly what needs to be done when the handler is triggered.” However, I thought I would include it just to make you aware of its existence.

        $(document).ready(function () {

            var importantData = "My Event Data";

            $('p').bind('click', { i: importantData }, function (event) {
                alert(event.data.i);
            });
        });

As mentioned, the first parameter can take one or more events or custom events to allow multiple events to be handled. For example, click mouseover would perform the same function on both a click event and a mouseover event. If you want to perform different functions on different events but for the same element, you can do so using the following syntax:

        $(document).ready(function () {
            $('p').bind({
                'click': function () {
                    alert('Click Event'),
                },
                'mouseover': function () {
                    alert('Mouse Over Event'),
                }
            });
        });

In the previous example, we are passing in a map of type and value pairs into the method to allow it to bind to multiple events.

As well as using the bind method to add event handlers, you can also use a shortcut version to bind the handler to the element. The following two lines behave in the same way; both will perform the myClickFunction when clicked.

$('p').bind('click',  myClickFunction);
$('p').click(myClickFunction);

The shortcut events are displayed in the following tables.

Mouse Events

Table 3-17 lists mouse events.

images

As you can see, with most of the mouse events, it's a simple case of calling the method with the function to handle the event, just like the previous click example. The only exception is the hover event, which has an In handler and an Out handler, which are used, for instance, if you want to put a border around an image when the mouse hovers over it. When the mouse leaves, it will call the Out function to remove the border.

Mouse events can apply to any HTML element, making them very useful for providing mouse-based interactions with your user interface.

Form Events

Next up are the form events; these events, as the name suggests, are for handling form-based events (see Table 3-18).

images

Most of the events are fairly self-explanatory and do as the name suggests. The one worth explaining a bit further is the blur event. The blur event is essentially the opposite of the focus event; it's when the element loses focus that the event is fired.

Keyboard Events

Table 3-19 lists the keyboard events.

images

Even though the keyboard events can be bound to any element, they will apply only to the element with focus. More often than not, the keyboard events are used with form elements.

With the event binding so far, we have been using a jQuery selector to get the elements to apply the binding to and then adding the required binding method. With this method of wiring up the element to events, you need to really know all the elements are there at the beginning because any new elements added to the DOM will not have the event handler attached to them. Let's take a look at another example and see this behavior in action.

The HTML is just a simple div with two paragraphs that have the myParagraph class:

    <div id="myDiv">
        <p class="myParagraph">
            Click me!</p>
        <p class="myParagraph">
            Click me!</p>
    </div>

The jQuery uses the class selector to select the two paragraphs and attaches the click handler. The code also creates a new identical paragraph element and appends it to the parent div.

        $(document).ready(function () {
            // Bind click handler to the paragraph elements with the myParagraph class
            $('p.myParagraph').bind("click", function () { alert("You clicked me"); });
            // Create new paragraph with the class and appends it to the 'myDiv' DIV element
            $('<p class="myParagraph">Click me too!</p>').appendTo('#myDiv'),
        });

Running this code will allow you to click the paragraph elements, and an alert will show. However, you will notice that when you click the paragraph “Click me too!” that the alert does not show even though it has the correct class. This makes sense because it wasn't part of the query selection where you added the event. If you swapped the two methods around, then it would work, but there is another way that allows you to say “Bind these elements and all future elements that match this selector.” This method is called the live() method; its opposite is the die() method.

Live(eventType,eventData,handler): Deprecated as of Version 1.7; See On()

To add an event to an element and to all future elements that match, you can create the query using the live() method. Working from the previous example, it is only a small change to allow you to handle all new elements you add.

        $(document).ready(function () {
            // Bind click handler to the paragraph elements with the myParagraph class using Live
            $('p.myParagraph').live("click", function () { alert("You clicked me"); });
            // Create new paragraph with the class and appends it to the 'myDiv' DIV element
            $('<p class="myParagraph">Click me too!</p>').appendTo('#myDiv'),
        });

The difference is slight, but it makes a big impact. Now if you deploy the solution again, you will be able to click the new item, and the event will fire.

Die(): Deprecated as of Version 1.7; See Off()

Similar to the unbind method, the die() method allows you to unhook events attached using the live() method. As with the unbind(), you can remove all bindings with the parameterless constructor, you can remove an event type by passing in its name, and you can remove a specific event by event type and function.

$('p').die()
$('p').die('click')
$('p').die('click', myClickFunction)

For .die() to function correctly, the selector used with it must match exactly the selector initially used with .live().

On(): jQuery 1.7+ Only

The on method works in a similar fashion to the live() method where the element is selected and the action can be bound for all existing and all future elements matching the selector. The event can be unbound using the off() method.

$('.myClass').on('click', function(event){
        alert("Element with myClass has been clicked");
});

Off(): jQuery 1.7+ Only

Die will detach the event from the elements; the selector must match the one used for on(). In this example, it is removing the event that was enabled from the earlier on() example:

$("#myDiv").off('click', '.myClass'),

Why Is This Useful?

The live() and on() methods are especially useful if you want to work with elements that are outside of your control or if you are dynamically generating the HTML. If, for example, you wanted to keep a log of all links clicked within a page, you could use live() to bind to the links and all others that may come afterward. When using a web service, as long as you make sure the new elements you are creating will meet the query conditions, you can ensure they have the same event handling behaviors as existing elements.

Unbind()

If a binding is no longer required, then it is possible to unbind it from the element. There are three ways to remove the bindings from an element: delete all bindings, delete bindings by type, or delete a specific binding by type and function.

To remove all bindings, the unbind method is called without any parameters:

$('p').unbind();

Removing the event is simply done by passing in the type; this will remove all bindings of that type:

$('p').unbind('click'),

Or, if a specific function was bound to an element, it could be unbound like so:

        $(document).ready(function () {

            var clickFunctionOne = function() {
                alert('Click Function One'),
            };
            
            var clickFunctionTwo = function() {
                alert('Click Function Two'),
            };

            $('p').bind('click', clickFunctionOne); // Bind clickFunctionOne to click event
            $('p').bind('click', clickFunctionTwo); // Bind clickFunctionTwo to click event
            $('p').trigger('click'), // Fire click event - Will show the two alerts
            $('p').unbind('click', clickFunctionTwo); // Remove clickFunctionTwo from click
event
            
            // Click on a p now and only the first function will fire
        });

In this code, we are creating two variables, clickFunctionOne and clickFunctionTwo, for the functions to be called on the click event. The two functions will behave the same way as if we had passed in the function like in the first binding example. By using variables, we can pass the variable we want to remove (clickFunctionTwo) to the unbind method to remove only that method.

Trigger

The last few sections have covered how to bind events to the HTML elements on the page. What happens if you want to trigger one of the events without the user? Well, luckily most of the methods also support a parameterless call that will trigger the event:

$('#myElement').dblclick();

The previous code will fire the double-click event for the element.

You should now have an idea of how to attach event handling to the HTML elements on your page. It's also important to know how to detach the event handling; this is where the unbind method comes into play.

Manipulation

In this section, you will learn how to manipulate the DOM. You have seen some of the methods that do some manipulation already such as attr() to modify attributes and css() to alter the CSS.

There are three main types of DOM insertion that jQuery offers: inside, outside, and around. Inside is used to insert content inside an existing element. Outside lets you insert content outside an element, such as before or after it. Finally, there is around, which allows you to wrap or unwrap existing elements, such as adding a div around a collection of paragraphs.

DOM Insertion Inside

Table 3-20 lists the functions for inserting elements inside an element.

images

The append() and prepend() methods behave in a similar way; the only difference is that the prepend will insert the element at the beginning, and append will insert it at the end. Both methods can take HTML content as their parameter; in this example, I have found the class of the list in the navigation page and will add two extra items:

        $(document).ready(function () {
            $('.s4-specialNavLinkList').append('<li>I have been appended</li>'),
            $('.s4-specialNavLinkList').prepend('<li>I have been prepended</li>'),
        });

The results, although not the prettiest, show how you can add elements to existing SharePoint elements, or even elements that you have created yourself, as shown in Figure 3-18.

images

Figure 3-18. Elements inserted into the SharePoint 2010 navigation menu

With the two methods so far, the syntax is the elements you want to append or prepend the new elements to. With PrependTo() and AppendTo(), it works the other way around; you specify the content and then say where you want it to go.

This example of AppendTo() is moving the Site Actions element and appending to the same menu as before:

   $(document).ready(function () {
        $('#zz9_SiteActionsMenu_t').appendTo('.s4-specialNavLinkList'),
   });

'#zz9_SiteActionsMenu_t is the site action element ID, and we are appending this element to the nav list. As before, because we used append(), it's at the end of the list, as shown in Figure 3-19.

images

Figure 3-19. Adding an existing element to another location

DOM Insertion Outside

Table 3-21 lists the functions for inserting an element outside an existing element.

images

Rather than just the locations of the beginning and end like append() and prepend() give you, the outside methods give you greater control on where to place the elements you are manipulating.

Look at the following HTML:

    <div id="myDiv">
        <p class="myParagraph" id="firstParagraph">I am the first paragraph</p>
        <p class="myParagraph" id="secondParagraph">I am the second paragraph</p>
    </div>

What you want to do is add a new paragraph in the middle of these two; luckily, they have an ID each so you can choose to insert after the first paragraph:

        $(document).ready(function () {
            // Using a variable to hold the new element
            var newParagraphVariable = $('<p>I am a new paragraph</p>'),
            $('#firstParagraph').after(newParagraphVariable);
        });

The result of this after method is shown in Figure 3-20.

images

Figure 3-20. New element added after the first paragraph

As you would expect, the before method will insert the element before the specified element. The InsertBefore() and InsertAfter() methods perform the same function as the before and after methods; it's just that the syntax is different. As with appendTo() and prependTo(), the element to insert comes before the destination.

The following two lines do exactly the same thing, the first using InsertAfter:

            $('<p>I am a new paragraph</p>').insertBefore('#secondParagraph'),
            $('#secondParagraph').before('<p>I am a new paragraph</p>'),
DOM Insertion Around

Table 3-22 lists the functions for inserting elements around an existing element.

images

As mentioned previously, the around set of methods is used to wrap existing elements with new elements, essentially putting them into a container.

In the following example, you will be using the toggle() method to wrap and unwrap a set of images. The example is using the following style that has been placed in the head ContentPlaceHolder of the page:

    <style type="text/css">
        .myInnerDiv
        {
            margin: 10px;
            border: 2px solid black;
            display: inline-block;
        }
    </style>

The HTML containing the images is as follows:

    <div id="myOuterDiv">
        <button id="myButton">
            UnwrapWrap</button>
        <img alt="Apple" src="apple.png" class="myFruit" />
        <img alt="Lemon" src="lemon.png" class="myFruit" />
    </div>

The images I am using have been placed in the same folder in the Layouts directory as the ASPX page, as shown in Figure 3-21.

images

Figure 3-21. Images have been added to the project, so they will be deployed.

Finally, here is the jQuery code:

        $(document).ready(function () {
            $("#myButton").toggle(function () {
                $(".myFruit").wrap("<div class='myInnerDiv'></div>");
            }, function () {
                $(".myFruit").unwrap();
            });
        });

The toggle() method alternates between the two functions provided, so on the first click, it will wrap the elements with the myFruit class using the myInnerDiv div, and when the button is clicked for a second time, it will unwrap the same elements.

Unwrapped Page and the Underlying HTML

Figure 3-22 shows the original img elements without wrapping.

images

Figure 3-22. Original img elements without wrapping

Now once the button is clicked, it will wrap the elements. To help visualize this, the div, which is being wrapped, has been styled with a trendy border, as shown in Figure 3-23.

images

Figure 3-23. Images now show the border coming from the wrapping div

If you refresh the view in the Internet Explorer Developer Tools, you will notice that the two fruit elements are now wrapped in the innerDiv div, as shown in Figure 3-24.

images

Figure 3-24. The HTML shows how the img tags are now wrapped by the div.

You have seen in the previous example that when the elements have been wrapped, they were wrapped individually. The class selector that was used brought back the two fruits, and each of them was wrapped with the div. If you want to wrap the elements returned from the selection as a group, you can use the .wrapAll() method.

Changing the jQuery code to the following will wrap both elements into the same div; this code will do it on page load rather than requiring the button click:

        $(document).ready(function () {
            $(".myFruit").wrapAll("<div class='myInnerDiv'></div>");
        });

The result is shown in Figure 3-25.

images

Figure 3-25. Both images are now wrapped in a single div.

The final method to look at is the wrapInner() method, which allows you to wrap the inner elements of the selector with the provided element. For instance, say you have the following HTML where instead of having images of fruit, you just have the names in paragraphs:

    <div id="myFruits">
        <p class="myFruit">Apple</p>
        <p class="myFruit">Lemon</p>
    </div>

If you want to wrap the contents, that is, Apple and Lemon inside a b tag to make it bold, then you can use the following jQuery:

        $(document).ready(function () {
            $(".myFruit").wrapInner("<b></b>");
        });

The result will be that each element matching the query will have its inner content wrapped with the tag, as shown in Figure 3-26.

images

Figure 3-26. p tags are now wrapped in the b tag.

DOM Replacing

Table 3-23 lists the DOM replacing methods.

images

As well as being able to insert new elements, you can also replace existing elements. In this example, you will look at replacing the page logo.

Using the developer toolbar, you can find out that the image to replace is nested underneath the anchor element with an ID of ctl00_onetidProjectPropertyTitleGraphic, so using the direct descendent selector, you can get the image to replace:

        $(document).ready(function () {
            $("#ctl00_onetidProjectPropertyTitleGraphic>img").replaceWith("<img
src='apple.png' border='0' alt='Fruit' />");
        });

Running this code returns the logo shown in Figure 3-27,

images

Figure 3-27. Standard Team Site logo that will be replaced

which becomes the logo shown in Figure 3-28.

images

Figure 3-28. Replacing an element is easy with the replaceWith method.

Although this example is a good one to show what you can achieve with jQuery, always be aware that just because you can do something with jQuery doesn't mean it's the best way. If you wanted to change this icon, you should do it through the Site Settings images Title, Description, and Icon page.

replaceAll() is the same as replaceWith(), but the source and target are reversed.

DOM Removing

Table 3-24 shows DOM removing elements.

images

You've inserted and replaced, and now you will see how to remove. There are some clever features of the remove methods, which will allow you to detach something from the DOM but keep it to be attached or inserted elsewhere.

Working through a couple of demonstrations will help here. Using these two lists with some sample content, you will see how the remove operations behave:

<h2>List One</h2>    
<ol id="myListOne">
        <li>Item One</li>
        <li>Item Two</li>
        <li>Item Three</li>
    </ol>
<h2>List Two</h2>
    <ol id="myListTwo">
        <li>Other Item One</li>
        <li>Other Item Two</li>
        <li>Other Item Three</li>
    </ol>

Deploying just this so far would display two lists, each containing three list items (see Figure 3-29).

images

Figure 3-29. Orginal elements with two unordered lists with three list items

If you use the following jQuery script, you will see that it is using each of the removal methods. The first removes all items from the second list. The detach method is removing the Item Two element from the first list and storing it into a variable. The next method is removing Item Three, and finally the element being stored in the variable is being appended to the second list.

        $(document).ready(function () {
            // Remove all items from List Two
            $('#myListTwo').empty();
            
            // Detach the second item from List one (Item Two)
            var itemTwo = $('#myListOne>li:nth-child(2)').detach();
            
            // Remove new second item (Item Three as Item Two has been detached)
            $('#myListOne>li:nth-child(2)').remove();
            
            // Append the detached item to the second list
            $('#myListTwo').append(itemTwo);
        });

The result is shown in Figure 3-30.

images

Figure 3-30. The child elements have been detached and reattached to a different parent element.

Summary

In this chapter, you saw a great deal of the arsenal that jQuery offers. When you are building your jQuery applications in SharePoint, you will find that selectors are an invaluable tool, and knowing the different ways you can select the elements you want will make this task that much easier. You should also understand the different events available, from the $(document).ready() function, which is used in pretty much every jQuery application I have written, to the events that you will seldom use but that are worth knowing about. Being able to create HTML code on the fly is such a useful function to have, and you will see later in the book how this can be applied when retrieving data from various sources to populate elements on a page.

Because of the interactive nature of jQuery and the speed in which you can knock out a small test application, I strongly advise you to create a few more test pages with various elements and different IDs, class names, and attributes to learn more about how you can interact with them. When it comes to writing your solutions, being able to draw on this experience will help you in the long run.

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

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