Showing posts with label jquery. Show all posts
Showing posts with label jquery. Show all posts

Monday, May 29, 2017

Learning jQuery, Fifth Edition

I'm pleased to announce the availability of Learning jQuery 3. This is the fifth edition of the book, and given its track record, I didn't want to diverge from what has worked so well over all these years.

Thursday, July 3, 2014

jQuery: Closest Is Better Than Parent

We know that jQuery is the de-facto DOM traversal tool on the web. Part of what makes this works so well with jQuery is it's chaining ability. You can chain just about everything you need to do as a single statement, without sacrificing readability. There are some scenarios where chaining these traversal operations doesn't work so well. Like when trying to traverse up through the DOM using parent().

Monday, June 30, 2014

Processing Form Data with jQuery and Lodash

I can get most of what I need for processing form data straight out of jQuery. I can listen for the submit event on the form, and I can prevent the form from actually getting submitted, allowing my own behaviour to run. jQuery also helps me collect the form data I need with the serializeArray() function. This function returns an array of form values. Lodash can help me transform this array into something more usable.

Tuesday, January 28, 2014

Using Lodash With jQuery

Both Lodash and jQuery are very powerful libraries that serve two very distinct purposes. Lodash is a utility library concerned with JavaScript data structures — arrays, abjects, and functions. On the other hand, jQuery is concerned with the DOM, Ajax, and event handling. There is, however, some overlap. For example, both libraries help the developer write less code. They're also complimentary to one another — where Lodash lacks in anything DOM or Ajax related, jQuery soars. Where we need fancy array queries and short-cuts, Lodash picks up the slack.

Wednesday, January 22, 2014

Preserving Chained Calls Using wrap()

Chained function calls are a staple of jQuery coding style. Rather than make one call, store the resulting jQuery object in a new variable, make another call, etc., we can chain the operations together. It doesn't even have to be the same element. For example, using end(), you can reach deep down into the DOM hierarchy, make a change, then continue along. All in the same call chain. So how does wrap() help us with call chains?

Friday, October 7, 2011

Printing Dynamic Content With jQuery

Formatting content from the web for printing can be a challenge.  Some websites have the preconceived notion of a printer-friendly format for their content.  This is makeshift version of what the user normally sees reading directly from the browser.  Online versions of content — the default version — contain elements that serve no purpose in a printed document.  Things like embedded links, navigational items, and so forth.  Typically, sites that offer printable content present the user with a print version button, leading them to another page.  This version has a different set of styles applied to it — probably hiding things that shouldn't be included in the printed copy.

This approach works fine for content assembled on the server — the web application generates the HTML markup in it's final form before sending it to the browser.  Likewise, when the user hits the print version button, they're either going to see the same exact page with different styles applied to it, or be redirected to another URI — /page/print/ for instance.  It's difficult, however, to make use of this approach when we've got dynamic content being pushed from the server onto the page.  How can we format the page for printing in a universal way when the content doesn't have a strict URI associated with it?

Dynamic content and URIs
When we're talking about dynamic content in web applications, we're not talking about the application server that fills in the empty template slots.  True, this is dynamic, but not from the user's perspective.  In this sense, the user is associating the content with a single URI — a one-to-one mapping.  The URI is the reader's key to fetching a chunk of content.

For written content, news sites and bogs for example, this approach works well because you can share URIs.  For applications, this is a little trickier — especially for applications that follow more of an Ajaxy paradigm and aren't necessarily URI bound.  In these types of environments, the user is is more concerned with generated output — tables and other forms of information that convey the state of the application.

But the application needs to get this data from somewhere — the Javascript Ajax calls need to follow some path to the application that'll return something of value for the user interface to display.  This is usually an API that returns JSON data that the user interface library, jQuery for example, knows how to parse and understand.  The data these URIs return are perfect for user interfaces, unfitting for user looking to print that data.

Although some — perhaps most — of this application-style content isn't suitable for printing.  But some of it probably is.  A grid would be a good example of this.  Grids take on a specific look and feel inside the web application user interface.  Suppose they want to take a look at it on the train ride home in dead-tree format.  Is the grid widget optimized for printing?

Building new documents
We could, to help solve the problem of printing this grid widget, implement functionality that'll take any dynamic data rows, and the grid as a whole, and adjust it for printing.  That's fine for this particular use-case.  But it also makes two assumptions that are at best sub-optimal.  First, if our application uses a grid that is populated dynamically via an API, chances are we're going to have other printable content.  So this means any printing strategy we employ is going to need to support more than just the grid.  Anything less is prohibitive in value.

The second problem, perhaps not so obvious as we're used to printing static web content, is how does the user return to where they were in the application after printing?  We could always apply some style changes that'll make the content printable in the current browser window.  This introduces more complexity, however, because we've now got to roll back those changes once the user has printed their document.

Another approach, one that I think behaves more intuitively, is to have the user interface identify printable regions in the interface when they click the print button.  These regions are then copied over to a new document before being formatted to print.  This is like following a print friendly URI for static content — it doesn't change the original browser window.

Here is some basic markup.  Let's pretend that the content div has been inserted into the document as a result of an Ajax call...

<html>
    <body>
        <div class='content'>
            Some <a href="#">content</a> with <a href="#">links</a> inside.
        </div>
        <button class='print'>Print</button>
    </body>
</html>

 We've also got a print button in our user interface.  Let's implement some example printing functionality for Ajax content...

$(document).ready(function(){
    
    function replace(){$(this).after($(this).text()).remove()}
    
    $('button.print').live('click', function(event){
        var print_window = window.open(),
            print_document = $('div.content').clone();
        
        print_document.find('a')
                      .each(replace);
        
        print_window.document.open();
        print_window.document.write(print_document.html());
        print_window.document.close();
        print_window.print();
        print_window.close();
    });
    
});

And that's it.  This is a simple example of how we can locate and modify information inserted by Ajax API calls and create a new document suitable for printing.

All this example does is replace a elements with their text.  But before doing so, the div.content element is cloned — so as not to disrupt the user interface.  Finally, we can copy the new modified element into a new browser window for printing.  We're automatically going to print this for the user, and close the new browser window to make the whole experience as unobtrusive as possible.

Wednesday, September 21, 2011

Idle Ajax Polling

Web applications like to fetch new data resources in the background.  Javascript toolkits — in conjunction with Ajax browser technologies — allow the user interface to refresh application data asynchronously.  There is no need to reload the page.  jQuery has a suite of useful Ajax utilities for fetching new data and parsing it.  This frees up the user interface to notify the application server when it needs more data — perhaps on a recurring basis — each request polling for fresh information.  But should this sequence use a fire and forget approach?

Seeking new data
Web application user interfaces are different from their more traditional desktop counterparts.  With a desktop user interface, it's easy to listen for changes in data — changes the user is interested in.  For instance, one pattern might be to have your widgets act as observers on particular pieces of application data.  When the data changes, the widget is notified and can thus make the appropriate visual changes.

There is no need for desktop user interface libraries to poll for changes in the underlying application code — the application can notify the user interface.  However, with user interfaces that run inside a web browser, data is often stored on the remote application server — so it needs to stay informed.  This is easy enough for the user — they simply need to hit the refresh button and voila — up-to-date information.

The emergence of Ajax in Javascript user interfaces revealed some inefficiencies with the refresh button.  First of all, hitting refresh is going to retrieve a new copy of the entire web page — this is wasteful as we've already got the user interface — desktop applications aren't going to rebuild the entire screen when changes in data occur.  Second, you'll seldom find refresh buttons inside desktop user interfaces — the data finds the user.  In other words — web user interfaces should be automatically populated with changes in data.

Since it's difficult to have the application server notify the user interface about these changes — the Javascript needs to poll for data changes in the background.  When new data is detected, the interface is updated accordingly.  One potential issue with implementing a polling loop is how do we ensure minimal resource usage?  After all, each poll needs to travel through the network.

Idle windows
One approach to saving on resources with a polling Javascript user interface is to detect when the browser window is idle.  An idle browser window is one that is open with the user interface loaded, but not in focus on the user's desktop.  For example, the user might switch tabs or switch to another desktop window entirely.  We can attempt to capture these events and modify our polling logic fittingly.

Here is a simplified demo using jQuery that shows how we might use the focus and blur events to start and stop our polling loop respectively.

var poller;
$(document).ready(function(){
    function poll(){
        $('body').append($('<p></p>')
                 .html('Polled.'));
        poller = setTimeout(poll, 3000);
    }
    $(window).focus(function(event){
        $('body').append($('<p></p>')
                 .html('Active.  Starting poll...'));
        poll();
    });
    $(window).blur(function(event){
        $('body').append($('<p></p>')
                 .html('Idle.  Stopping poll...'));
        clearTimeout(poller);
    });
});

Resources saved
In the example above, we're polling (not actually polling anything, but you can see where the real Ajax code would go) every three seconds.  When the window becomes idle, we stop polling.  This signifies that the user is no longer interested in receiving new data from the application server.

By not polling for new data, we're not consuming network bandwidth.  We're also not consuming CPU cycles on the client when new data arrives.  This is a win for both the client and the web application.

Thursday, June 3, 2010

jQueryUI Tab By ID

The jQueryUI tabs widget allows you to select a tab programmaticaly by using a 0-based index. This is handy because sometimes you want to direct a user to a tab without them having to click it. The select() method of the tabs widget allows us to do just that. However, having to keep track of the indexes for each tab doesn't really make sense and hard-coding the index value for a specific tab makes even less sense.

It would be nice if we could select a specific tab by ID. The following function does just that.
function select_tab_by_id(widget_id, tab_id){
jQuery(widget_id)
.tabs("select", jQuery(widget_id+" ul a")
.index(jQuery("[href="+tab_id+"]")));
}

select_tab_by_id("#my_tabs", "#tools");

Monday, May 31, 2010

jQuery String Contexts

The jQuery.each() iteration function is a powerful Javascript iteration utility. You supply a callback function that is executed for each element in the provided set. Additionally, the this object in the callback function is the current element. This can cause some subtle bugs in your code if your doing string comparisons.

Since this is an object and your callback wants to do a comparison as though this were a string, it will not always evaluate to true. Even when it should be. I found this rather annoying so I tried to make sure I was in fact comparing two strings. Sure enough, this.toString() fixed my problem. So, try using this if your strings aren't evaluating as expected inside jQuery.each() callbacks.

Friday, April 30, 2010

jQueryUI Hovering

The jQueryUI user interface library offers developers building interactive web applications not only a set of widgets to use, but also, a set of effects. An effect, in this context, can be thought of as a transition from one state to another by a user interface component. As an example, imagine you have a button element that is in a hidden state. Showing that button would be considered an effect, albeit, a very basic one. A jQueryUI effect adds some appeal to these transitions. In essence, jQueryUI effects can be thought of as user interface component state transitions that enhance the overall user experience.

Another nice feature in the jQueryUI repertoire is the CSS framework used for changing the look and feel of the widget set. This framework allows developers to choose an existing theme or to build their own. CSS classes within the framework are flexible enough that they aren't restricted to the jQueryUI widgets. Your user interface isn't going to be composed entirely of widgets. You can use these CSS classes to help give the non-widget elements of your application more of a theme.

An example use of applying the jQueryUI CSS framework to a non-widget element would be using the ui-state-hover class. Lets say we have a list of li elements. The idea is to add the ui-state-hover CSS class to each li element when the user hovers over it. This is fairly straightforward to do with the jQuery addClass() and removeClass() methods. You call these methods inside a hover in and a hover out callback respectively. Example callback functions are shown below.
function hoverin(element){
jQuery(element).addClass("ui-state-hover");
}

function hoverout(element){
jQuery(element).removeClass("ui-state-hover");
}
jQueryUI allows us to add an interaction to the addClass() and removeClass() methods. Typically, we would only want to add an effect to the addClass() for hover in events. Otherwise, the user interface tends to look too busy. Here is the same example modified to introduce an effect when adding the class. The the visual changes made to the element as a result of adding the class will take place over a duration of 150 milliseconds rather than instantaneously.
function hoverin(element){
jQuery(element).addClass("ui-state-hover", 150);
}

function hoverout(element){
jQuery(element).removeClass("ui-state-hover");
}
There is, however, one problem with this approach. There is a chance that the ui-state-hover class will not be removed from the element by hoverout(). This is because the user can, and most definitely will at some point, hover out of the element during the 150 millisecond effect duration. Keep in mind, the element doesn't actually have the ui-state-hover class until the 150 millisecond effect duration is up. When hoverout() is called during the effect, no class is removed because it hasn't been added yet. Below is a work-around for this issue that involves using a secondary state class.
function hoverin(element){
jQuery(element).addClass("app-state-hover");
jQuery(element).addClass("ui-state-hover", 150, function(){
if(!jQuery(element).hasClass("app-state-hover")){
jQuery(element).removeClass("ui-state-hover");
}
jQuery(query).removeClass("app-state-hover");
});
}

function hoverout(element){
jQuery(element).removeClass("ui-state-hover app-state-hover");
}
Here we introduce a new class called app-hover-state. This class will be used to track the hover state of the element since we are now using an effect. The hoverin() function will now add this class to the element before starting the visual effect. The hoverout() function will now remove both the ui-state-hover and the app-state-hover classes. This is important because even if the effect hasn't yet finished when the user hovers out of the element, the app-state-hover class will be removed from the element. The visual effect in hoverin() now has a callback function that is executed when the duration of the effect has completed. This callback will remove the ui-state-hover class if the app-state-hover class has been removed. In this case, if app-state-hover has been removed can only mean one thing; a hoverout() call was made during the duration of the effect and the ui-state-hover class should also be removed.

Thursday, April 1, 2010

jQueryUI Dev Tool

The jQueryUI library is a themable user interface library. As such, all themes are CSS based and can be interchanged within the same application. The jQueryUI dev tool is a simple bookmark you can use to develop your own themes or to see how your application will look with an already existing theme. There are plenty to choose from. What makes this to interesting is that this tool works well even for production systems.

Wednesday, March 31, 2010

jQuery Proxy

The jQuery.proxy() method allows event handlers to use the this object as something other than the event object itself. That is, you can change the context of a specified function. Some view this technique as somewhat dangerous. This is probably true if not treated with care.

If you're a developer coming from another object-oriented programming language, you're probably used to the this object referring to the current object or self. The whole purpose of the jQuery.proxy() method is to change that meaning.

It can be quite powerful in certain situations where the event doesn't provide all the data required by the event handler. Or maybe the original event object provides nothing of value at all and it is beneficial to use jQuery.proxy() everywhere. In this case you would only be updating some application model instead of reading the event properties. All you would care about is that the event occurred. Either way, useful feature to have available.

Friday, March 26, 2010

jQueryUI UML

The jQueryUI Javascript user interface library has some interactions that would be well-suited for a UML canvas. For instance, the draggable interaction is essential for moving modeling elements around. Same with the selectable and resizable interactions. The main challenge would be creating the widgets that represent the UML modeling elements.

Thursday, March 25, 2010

jQueryUI 1.8

jQueryUI 1.8 is now available, complete with a new button and auto-complete widget. The button widget is flexible enough to use different HTML elements as the basis for the widget. Auto-complete looks like a really nice widget as well. I'm looking forward to the combo-box widget becoming part of the stable jQueryUI distribution.

Thursday, March 18, 2010

jQuery API Attributes

jQuery is an excellent Javascript toolkit for interacting with server APIs. Especially for RESTful, resource-oriented APIs. Each resource returned from such an API generally has a unique ID associated with it. This could be a database primary key or a UUID. Regardless, it is used to uniquely identify the resource so it may be referred to as a URI such as /resource/3495/.

jQuery web applications often build lists of user interface elements from resource lists. For example, /resource/list/ might return a list of resources in the for of (id, name). Once the jQuery callback has this list of id-name pairs, it can build an HTML list. The question is, how should the resource ID be stored in the user interface so that it can be used again as part of a resource URI if the user clicks a list element?

One solution is to store the ID directly in the DOM element when it is created. The benefit here is that the URI can be constructed from the click event. The event object itself has a currentTarget attribute which is our list element. Lets say we stored a uuid attribute as part of the list element. Inside the click event handler, we could do something like jQuery(event.currentTarget).attr("uuid"). This is all we need to build a URI for this specific resource.

Wednesday, March 3, 2010

jQuery UI Select Menu

jQuery UI 1.8 is now at release candidate 3 and is looking like a 1.8 final release will be available any time now. After looking at the button demos, I haven't yet decided if I'm going to replace my existing custom buttons with these new widgets.

The auto-complete widget does look very promising, especially for large data sets. However, I have several instances where I have only a small data set and using an auto-complete widget would be overkill.

The select-menu widget looks perfect and I'm looking forward to a stable version in jQuery UI. It will be nice to replace the standard select elements, which look really out of place in a jQuery UI theme.

Friday, November 20, 2009

Open Source Closure

Google has recently open-sourced it's javascript tools called Closure. It is this suite of tools that Google uses in every web application that it hosts. They claim to have made it available for download so that developers of other web applications have an opportunity to make the web faster as a whole. That sounds a bit to me like "hey, if you drop the javascript toolkit you are currently using and use ours, your application will be faster. yay!"

I don't necessarily buy it if that is the case. Sure, Google has nice, well-performing web applications that would certainly impress your customers if you could offer something similar. But this market is already flooded with good quality javasctipt toolkits. jQuery is tough to compete with for most intents and purposes.

One area that Closure has an advantage in is the fact that it is shipped with a javascript compiler, an area relatively unexplored. At most, the javascript of many application might be slightly compressed before it is served up to clients.

If you aren't already heavily invested in another javascript toolkit, closure may be worth looking at. If that, or any other kit for that matter, is the one you choose, stick with it. Don't mix and match javascript toolkits. You'll just be asking for trouble.

Monday, October 19, 2009

jQuery Array Deletion

The jQuery javascript toolkit provides several useful utility functions for working with arrays. One wouldn't think that this functionality would be necessary but in the world of javascript, this is often the case because of different browser implementations. The array utility functionality offered by jQuery includes basic array manipulation and searching.

One such searching function is the jQuery.inArray() function. As the name suggests, the function will determine if a specified element exists in a specified array. This utility is indispensable for javascript developers simply because of the amount of code it reduces.

Searching for elements in a javascript array often involves some kind of looping construct. In each iteration, we check if the current element is the desired element. In the case of array element deletion, we do something like this. The example below illustrates how the jQuery.inArray() function compliments the primitive splicing functionality of javascript arrays.
//Example; jQuery array deletion.

//Make the array.
var my_array=jQuery.makeArray(["A", "B", "C"])
console.log(my_array);

//Find an element to delete.
var my_pos=jQuery.inArray("B", my_array);
console.log(my_pos);

//Delete the element only if it exists.
my_pos < 0 || my_array.splice(my_pos, 1);
console.log(my_array);
In this example, we use the jQuery.makeArray() function because it returns a true array. It isn't needed but is a good practice regardless. Next, we find the position of the element we want to delete. Finally, if the my_pos value is less than 0, the element wasn't found and nothing happens. Otherwise, we splice the element out of the array. With the help of jQuery, we are able to seek and destroy array elements with two lines of code.

Tuesday, October 13, 2009

jQuery Custom Events

One of the more powerful features of the jQuery javascript toolkit is the ability to create custom event types. In addition to the built-in events that are triggered by standard DOM elements, developers have the ability to create custom events. These events that are defined by developers using jQuery are not all that different from the standard DOM events. The main difference being that the developers can have control over the event data and when they are triggered.

The custom jQuery events can be created using the jQuery.Event() function. The one required parameter of this function is the event name. The instance of the custom event is returned. Another parameter that might be passed to the function is an object that contains the event data. However, an event instance created by jQuery.Event() can also have attributes set on it directly. Either way, these values will be passed along with the event once it has been triggered.

Event driven programming is a very useful model. Especially when the application is user interface centric. Here, the application consists almost exclusively of events. The user does something, some event is fired and some handler acts accordingly. With javascript applications, there is also the prospect of triggering events when data arrives from some API request. In fact, without an event to notify the application that the data has arrived, the application would be considered synchronous and would not respond well to user interaction.

Custom javascript events created by developers can be broadcast across the entire application or sent as a signal to a specific DOM element. The more useful method is to broadcast the event because it allows any application component to subscribe to the event. This offers flexibility and reduces the amount of code needed to accomplish a specific task.

Tuesday, September 8, 2009

jQuery CSS

The user interfaces of web applications these days are filled to the brim with rich user interactions that were confined only to desktop applications no long ago. This high level of user interactivity is made possible by javascript toolkits such as jQuery. The features seen in nice web application user interfaces are possible using javascript without a toolkit, but this is a bad programming practice. In this case all the developer is doing is simply re-inventing the wheel.

These javascript toolkits allow for easy manipulation of the DOM tree. This means that elements of the page can be added, removed, or manipulated in controlled ways based on the user input. Without this ability, the user generally needs to wait for a response from the server which really takes away from the responsiveness of the GUI.

Aside from adding and removing page elements in response to user actions, page elements can change form in response to user actions. jQuery has the ability to add in-line styles to page elements. This is a useful feature for altering the appearance of page elements. Again, this is bad programming practice. If using the in-line CSS style attribute in the HTML markup is bad practice, this is synonymous. It is generally a good idea to keep the styles of various elements in the CSS definitions rather than add them using the jQuery functionality. Rather than add a style attribute, add a CSS class with jQuery. This is a much cleaner approach and makes the life of both the CSS designer and the javascript developer easier.