Content by Category
.NET 1.x
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0
.NET Assemblies
.NET Framework
.NET Getting Started
Accessibility
ADO.NET
Advertorials
Agile Development
AJAX
Architecture
ASP.NET
ASP.NET MVC
ASP.NET WebForms
B2B (Business Integration)
BizTalk
Book Excerpts
Build and Deploy
C#
C++
Code Contracts
CODE on the Road!
COM+
Community
Conferences
Continuous Integration
Crystal Reports
CSLA.NET
CSS
Data
Design Patterns
Development Process
Display Technologies
Distributed Computing
DotNetNuke
DSL
Dynamic Programming
Editorials
Enterprise Services ("COM+")
Entity Framework
Events
Expression Blend
F#
Fox to Fox
Frameworks
Functional Programming
Graphics
Internet Explorer 8.0
Interviews
iPhone
Java
Java Script
jQuery
LINQ
Linux
Mac OS X
MDX
Microsoft Application Blocks
Microsoft Business Rules Framework
Microsoft Expression
Microsoft Office
Mobile Development
Mobile PC
Mono
Network
NHibernate
Object Oriented Development
Open Source
Opinion
Opinions
Oracle
ORM
Other Languages
Parallel Programming
Patterns
Podcasts
Post Mortem
PowerPoint
Print/Output
Product News
Product Reviews
Project Management
Python
Q&A
Reporting Services
REST
RIA Services
Ruby
Search
Security
Services
SharePoint
Silverlight
SOA
Social Networks
Software & Law
Software Business
Source Control
Speech-Enabled Applications
SQL Server
SQL Server 2000
SQL Server 2005
SQL Server 2008
SQL Server CE/AnyWhere/Mobile/Compact
Subversion
Sync Framework
Tablet PC
TDD
Team System
Techniques
Testing and Quality Control
Tips
UI Design
UML
User Groups
VB Script
VB.NET
VFP and .NET
VFP and SQL Server
Virtual Earth
Vista
Visual Basic
Visual Basic 6 (and older)
Visual FoxPro
Visual Studio .NET
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio Tools for Office
VSX
WCF
Web Development (general)
Web Services
WF
Whitepapers
Windows 7
Windows Azure
Windows Live
Windows Server
Windows Vista
WinForms
Workflow
WPF
XAML
XML
XNA
XSLT



INSTANTLY dtSearch® TERABYTES OF TEXT


 


State of .NET

Reader rating:
Click here to read 4 comments about this article.
Article source: CoDe (2009 Jan/Feb)


Article Pages: < Previous - 1 2 3 4  5 


An Introduction to jQuery, Part 1 (Cont.)

Another Simple Example Showing a Popup Window

jQuery can also help to create utilitarian UI features. Let’s add a pop-up window to the example, and allow dynamically typing selectors that select and highlight matched elements in the entire page. The end result is shown in Figure 4.

Click for a larger version of this image.

Figure 4: Displaying a dynamic pop-up window with some effects.

A user pops up the “dialog” by clicking the Show Query Dialog window, which “slides in” the dialog from the top of the page and displays it with a slightly transparent background on top of the page content. You can then type a jQuery selector in the text area and effectively apply it against the document. When you click the button, the selected elements are highlighted in dark red in the document and then removed after a few seconds.

The dialog is stored on the page as a simple <div> tag element that’s styled and looks like this in markup:

<div id="divjQueryDialog"    
     class="blackborder">
    <div class="gridheader">
       Enter a jQuery Expression</div>
    <div class="containercontent">  
        Expression:  
        <span id="lblExpressonMsg">
        </span><br />       
        <textarea id="txtExpression" 
        style="width300pxheight60px;">
        </textarea>
        <input type="button" value="Show"
               id="btnExpression" />    
    </div>
</div>

There’s also some styling for the dialog that makes it transparent, initially hidden, and absolutely positioned on the page:

#divjQueryDialog
{
   width380px;
   positionabsolute
   left100px
   top70px;
   displaynone;
}

The code that makes the panel visible, applies opacity, and handles the matching and selection is relatively simple too and shown in Listing 2.

The code initially makes the div visible and applies opacity. It then hooks up a click handler to the button and an anonymous function to handle the processing of the click. That code captures the input text and then uses jQuery to “evaluate” the selector applying a special class to the matched set. The code also sets up a timeout that removes the highlight class after 5 seconds.

I mentioned nesting anonymous functions earlier and the above code shows another example-the code above is quite asynchronous, yet it is written in a single block of code that keeps context. The inner click handler has access to the dialog without having to reselect it. This is due to the way JavaScript handles nested closures or function blocks, which can see private variables defined higher up in the function definition stack-even if the code is asynchronous. In this example this is trivial, but if the fade out code (or “class”) contained more state, it’s quite convenient to have the state passed to the handler merely by virtue of being declared inside of the parent closure. This type of coding can often be easier to read as it keeps relative logic together in one place.

A couple of other things to highlight here: Notice the code to make the dialog transparent:

dialog.hide()
       .slideDown("slow")
       .css("opacity",.90);

jQuery is smart about how it handles certain CSS tags that browsers handle differently, such as opacity. Internet Explorer doesn’t support the opacity style (because it’s not officially part of the CSS 2.1 standard), but jQuery automatically does the right thing applying a filter style for Internet Explorer. jQuery applies similar rules for other CSS properties and certain functions. For example, .text() retrieves text consistently and .scrollLeft/Top retrieves scroll position safely. So jQuery acts as a normalizer between different browser implementations.

One last enhancement: If you want to make the window draggable so you can move it around the page, this is also easy to do using the draggable plug-in from jQuery UI. To use this plug-in, download jQuery UI and dump the library into your scripts folder (relevant portions provided in the sample). Then add:

<script src="scripts/ui.core.js
        type="text/javascript"></script>
<script src="scripts/ui.draggable.js
        type="text/javascript"></script>

To the page and simply add:

var dialog = $("#divjQueryDialog"); 
dialog.draggable();      

That’s it. You’ve just made your “window” a lot more window-like with a single line of code through use of the draggable plug-in. There are a number of options you can apply to draggable-for example to set the drag handle to the window’s header you can use:

dialog.draggable({ handle: 
         $("div.gridheader") });  

which makes only the header initiate a drag operation, which is more natural window behavior.

Plug-ins for Everything Else

Plug-ins are one of the main reasons that jQuery has become so popular. Part of the reason for this is that jQuery has a super simple API for plug-ins. There is a jQuery.fn property which hosts any operational functions that can operate on the matched set. By simply implementing a new function on jQuery.fn you effectively create a new matched set function that works like jQuery’s built-in functions. Here’s a very simple pulse plug-in that pulses an element by fading it out partially and then fading back to full visibility:

$.fn.pulse = function(time) 
{
    if (!time)
      time = 2000;
      
    // this == jQuery instance   
    this.fadeTo(time,0.30,
          function() { 
                $(this).fadeTo(time,1); 
          });
    
    return this; // return jQuery
}

You can now simply use a jQuery instance and the pulse function on it to pulse matched elements. For example, earlier you added a new item to the grid-you can pulse this item instead of fading it in:

row.insertBefore(
     "#gdEntries>tbody>tr:nth-child(2)")
        .css("background", "paleyellow")
        .pulse(2000);

This plug-in also works against many matched elements:

$("#gdEntries>tbody>tr")
  .filter(":even")
  .addClass("gridalternate");
  .pulse(1000);      

which pulses only the even rows.

A plug-in receives a this pointer that is the jQuery matched set. So you can apply further functionality to this matched set in the plug-in code. If the plug-in doesn’t have a distinct return value you should always pass the jQuery result set back as a return value so that the function is chainable for additional jQuery functions:

$("#gdEntries>tbody>tr")
   .filter(":even")
   .addClass("gridalternate");
   .pulse(1000)
   .addClass("small");      

This plug-in is overly simplistic. More commonly you need a little bit of set-up data as well some logic to loop and manipulate the matched elements individually. Listing 3 shows another slightly more realistic plug-in that centers any elements in the browser window or inside of another element.

This plug-in includes a couple of common patterns. First it has a set of option parameters that you can pass in as an object map (i.e., {container: "#divContainer"} ). Notice that opt is defined as a private variable and then extended with the option parameter object. $.extend() is a wonderful utility function that extends an object with the content of another object. This makes parameter processing easy for the user, by passing in only the parameters you are interested in. Most plug-ins accept options parameters in this fashion and it’s a good idea to implement options in your own plug-ins.

The next common plug-in pattern is to return this.each( function() {…}); which ensures the jQuery matched set is returned. The .each function iterates through each of the matched DOM elements individually and lets you operate against each of them one at a time. Inside of the .each() function handler, the this pointer is always the DOM element iterated over. You can use $(this) to get a jQuery instance for that element, which is typically what you want to manipulate the element.

Because it’s so easy to create plug-ins, I’ve ended up creating quite a few myself both for my own and shared use. The simple plug-in model is a genius concept: It allows for jQuery to stay small with only a core set of features while still exposing all of the functionality that the core library has to any extensions. It’s a model more API vendors should embrace and execute as nicely as jQuery has.

What's Not to Like?

If all of this sounds like a glowing commercial for a tool, you can be assured that I’m just a happy user who’s stumbled onto this library some time ago and fell in love with it the first time I used it. I tend to be very critical of the tools I use, but I have yet to have any serious complaints about jQuery. This library just works for me and it works the way I like to work.

The library is not “the perfect tool” and doesn’t solve every JavaScript and DOM problem for you; however, in my time of over a year with jQuery I haven’t run into a showstopper problem. You may still need a set of a few helper functions to help with non-DOM related functionality. For example, I still use my old JavaScript library for a number of UI and JavaScript utility functionality like date and number formatting, providing windowing support, and a host of other features. This is unlikely to ever go away. But I can simply toss out large parts of my old library because jQuery replaces functionality-in most cases much more elegantly than my own code did.

To be honest I’m grasping to find fault with jQuery for balance here because my editor mentioned I should mention the downsides. Sorry-you’ll have to dig up your own dirt. Good luck with that. A quick search around the Web seems to confirm my feelings-there’s not a lot of negative content that digs up dirt on jQuery. But you can judge for yourself by trying it out. My bet is you’ll dig it because it’s quick to pick up, highly intuitive to use, and so practical that it will quickly feel criminal to work on JavaScript without it.

AJAX and ASP.NET Server Side Next Time

In this article I’ve introduced jQuery’s core functionality for DOM manipulation and JavaScript extensions. I’ve focused on the client-side functionality without any thought given to the server side because ultimately this is what jQuery excels at most.

One big area I left out is AJAX and server-side integration with ASP.NET and that’ll be the focus of the next installment. I’ll look at jQuery’s AJAX functionality and how you can use ASP.NET as a back end to receive these AJAX calls in a variety of ways from plain Page callbacks, to REST calls, to using WCF. I’ll also look at integration on how to create ASP.NET controls that use jQuery or jQuery plug-ins in combination with server-side components and how to manage jQuery scripts in general in your ASP.NET applications.

Until then check out jQuery for yourself and get excited about the possibilities it offers for improving your client-side Web development. You won’t be disappointed.

Rick Strahl

&


Resources

Code Download

www.west-wind.com/files/conferences/jQuery.zip

Web Sites

jQuery Web Site: www.jquery.com

jQuery.UI Web site: ui.jQuery.com

Cheat Sheets

Color Charge Color Cheat Sheet http://tinyurl.com/yw7p2c

jQuery Cheat Sheet

Books

jQuery in Action

jQuery Reference Guide

Learning jQuery



Listing 2: Code to pop up a jQuery Selector test window
function showQueryDialog()
{
    var dialog = $("#divjQueryDialog"); 
    dialog.hide()
          .slideDown("slow")
          .css("opacity",.90);
    
    $("#btnExpression").bind("click", function(event) 
    {
        // Grab the selector entered as text
        var exp = $("#txtExpression").val();
        
        // Execute the selector through jQuery
        var matches = $(exp);

        // *** check result
        var len = matches.length;
        if ( len 1)
        {
            $("#lblExpressionMsg")
                   .text("No matching elements");
            showStatus("No matches",3000,true);
            return;
        }                
        showStatus( len.toString() + " matches",3000,true);
        
        // No errors clear error message
        $("#lblExpressionMsg").text("");
                                        
        // Highlight all matches
        matches.addClass("selectionhighlight");

        // Set up timer to remove the highlight 
        setTimeout(function() 
            { 
                $(exp).removeClass("selectionhighlight"); 
            },5000);
        
        // Unbind event and hide dialog
        $("#btnExpression").unbind("click");
        dialog.slideUp(); 
    });



Listing 3: A jQuery centerInClient Plug-in that centers content in the window
$.fn.centerInClient = function(options) {
    var opt = { 
        container: window,    
        completed: null
    };
    $.extend(opt, options);

    return this.each(function(i) {
        var el = $(this);
        var jWin = $(opt.container);
        var isWin = opt.container == window;

        // have to make absolute
        el.css("position", "absolute");

        // height is off a bit so fudge it
        var hFudge = 2.2;

        var x = (isWin ? jWin.width() : 
                jWin.outerWidth()) / 2 - el.outerWidth() / 2;
        var y = (isWin ? jWin.height() : 
                 jWin.outerHeight()) / hFudge - 
                 el.outerHeight() / 2;

        el.css({ left: x + jWin.scrollLeft(), 
                 top: y + jWin.scrollTop() });

        var zi = el.css("zIndex");
        if (!zi || zi == "auto")
            el.css("zIndex", 1);

        // if specified make callback and pass element
        if (opt.completed)
            opt.completed(this);
    });
}


Article Pages: < Previous - 1 2 3 4  5 

Page 1: An Introduction to jQuery, Part 1
Page 2: Getting a Feel for jQuery
Page 3: The jQuery()/$() Object
Page 4: Function Chaining
Page 5: Another Simple Example Showing a Popup Window

How would you rate the quality of this article?
1 2 3 4 5
Poor      Outstanding

Tell us why you rated the content this way. (optional)

Average rating:
4.9 out of 5

14 people have rated this article.

      Tower 48

 

TOWER 48