LA.NET [EN]

JQueryArchive

Aug 19

JQuery: full control with the $.ajax function

Posted in JQuery       Comments Off on JQuery: full control with the $.ajax function

In the previous posts, we’ve met several helper methods which simplify the code needed to perform remote out-of-band requests. In this post, we’ll be introducing the all mighty $.ajax method. This method is used by all the other methods we’ve seen until now and gives you complete control over the request.

Currently, you’re supposed to use an anonymous object to pass all those definitions (which are really a lot!). To illustrate the use of this method, we’ll be consuming a ASP.NET web service which returns JSON. We’ll start with the service code (defined on the SayHiService.asmx(.cs) file):

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class SayHiService : System.Web.Services.WebService {
    [WebMethod]
    public User SayHello(String name) {
        return new User {
            Name = name,
            Date = DateTime.Now
        };
    }
}
public class User {
    public String Name { get; set; }
    public DateTime Date { get; set; }
}

We’ve created a simple User class that will return a user and the current time at which the request was received on the server. If you’re into ASP.NET AJAX, then you’ll know that it uses JavascriptSerializer to serialize the return value into JSON. In the client side, you’re expected to transform the returned JSON into an object by using the Sys.SerializationJavaScriptSerializer JS class.

If you’re consuming ASP.NET web services from client code, there are some aspects you should keep in mind:

  • the returned object is wrapped into  an anonymous object with a single property (called d). This means that you’ll always receive a JSON string which looks like “{ ‘d’: … }”;
  • DateTime fields are transformed into /Date(x)/, where x is the number of ms elapsed since Jan. 1, 1970 at midnight UTC. In practice, this means that you’ll have to recover x and transform it into a valid JS Date object;
  • don’t forget that the web service needs to receive a JSON payload too. This means that you need to set the content type and you do need to serialize (into JSON) the arguments you’re passing from the client. If the method doesn’t receive any parameters,you should send the ‘{}’ string or it won’t work;
  • by default,the web service will only respond to POST requests (if you want to open it up to GET requests, you need to use the ScriptMethodAttribute on the web service definition)

If you used the Sys.SerializationJavaScriptSerializer JS class, you don’t have to worry with these details. However, you might not want to load the MS AJAX file just to do the parsing of the returned JSON (btw, I’ve used this approach in an previous post about ASP.NET MVC and JSON). And that’s what we’ll do in this post: we’ll use JQuery and the JSON plugin (which you can download from here) to interact with the previous web service. Here’s the final code of this page:

<input type="text" />
<input type="button" value="Server" />
<div></div>
<script type="text/javascript"> $(function() { $("input[type=button]").click( function(evt) { $.ajax({ url: "SayHiService.asmx/SayHello", type: "post", data: $.toJSON({ name: $("input[type=text]").val() }), contentType: "application/json; charset=utf-8", dataType: "json", success: function(data) { var user = data.d; //update date user.Date = new Date( parseInt(user.Date.match( /d+/ )[0] ) ); var html = "Nome: " + user.Name + "--- Date: " + user.Date; $("div").html(html); } }); }); }); </script>

Some observations about the previous code:

  • when calling the web service, you need to indicate the method that you want to invoke. That’s why we passed “SayHiService.asmx/SayHello” to the url property;
  • since I didn’t change the default server configuration, we need to ensure that the request will be made through a POST request (notice the type property);
  • we’re using the $.toJSON utility function to serialize an object which contains the information we want to send back to the server;
  • by passing json to the dataType, we’ll be getting a JS object in our success calback method;
  • the callback method starts by recovering the returned object (remember that we need to access the d property of an anonymous object). Then I used the most simple regular expression possible to recover the x from within the /Date(xxxx)/ string returned from the server side (as a side note, I’m betting that there are better ways of doing this, but regular expressions aren’t really my thing…);
  • you probably should pass a function to the error property so that you cna be notified about errors that have occurred during the request.

I guess there’s more to say about this method, but I think that the previous snippet covers what you’ll be using in 99% of the times. If you have the time, then do take a look at all the available options because there’s some interesting stuff going on there.

And that’s it. Keep tuned for more on JQuery.

Aug 19

Deferred script loading is a technique which can be used to reduce the initial loading time of any page. The idea is to load only the basic JavaScript code that is necessary for the initial loading operations of the page and then perform additional downloads for features that the user *might* use after initial rendering.

This is a fairly known and common technique and you’ll even find a pattern called On-demand JavaScript on the AJAX patterns web site. JQuery helps by introducing the utility $.getScript function. To illustrate its use, lets assume that we’ve got a button that won’t be *heavily* used and that relies on several JavaScript lines of code. This is a scenario where the user experience can be improved by using deferred script loading.

We’ll be simulating this by using a simple JS file (called hi.js) with the following code:

function sayHi(name) {
    alert(name);
}

Since we’re facing lots of JS lines (please imagine it:),,) and this code isn’t necessary for the initial load of the page, we’ve decided to run it only when needed, ie, only when someone clicks the say Hi button. Here’s the code we might ended up writing:

<input type="text" />
<input type="button" value="Server" />
<script type="text/javascript"> $(function() { $("input[type=button]").click( function(evt) { if( !window.sayHi ) { evt.target.disabled = "disabled"; $.getScript("hi.js", function() { sayHi($("input[type=text").val()); evt.target.disabled = ""; }); } else{ sayHi( $("input[type=text").val() ); } }); }); </script>


It might seem complicated, but it’s not. Since we’re loading an JS file, we need to make sure that we’ll only load it once (loading several times the same user file doesn’t really do much for improving the user experience, right?). The easiest way to do that is to check for the existence of the sayHi function (it will be defined after the successful load of the JS file). To ensure that the user won’t click the button twice before the file is loaded, we need to disable it and enable it when the JS code has been loaded and evaluated (which is perfect for the callback function we can pass to the $.getScript function).

And that’s it. Keep tuned for more on JQuery.

Aug 19

JQuery: the $.get and $.post methods

Posted in JQuery       Comments Off on JQuery: the $.get and $.post methods

In this post we’ll keep looking at JQuery’s helper methods for remote calls and we’ll see how we can use the get and post functions for performing HTTP GET and POST requests. Both functions (notice that these are utility functions and not JQuery object methods!) expect several parameters:

$.get( url, [data], [callback], [type] )
$.post( url, [data], [callback], [type] )

The first three parameters are the same as the ones we’ve met in a previous post when we looked at the load method. type is new and lets you indicate the type of response returned from the server. It’s important to set this if you’re getting non HTML/text content from the server side. Currently, it supports the values “xml", "html", "script", "json", "jsonp" and "text".

To show you how easy it is to use this utility function,we’ll start by creating a new handler which expects to retrieve a name from the request and returns an HTML snippet:

public class HowdyHandler : IHttpHandler {
    public void ProcessRequest(HttpContext context) {
        context.Response.ContentType = "text/html";
        context.Response.Write(
                String.Format("Hi <b>{0}</b>!",context.Request["name"]) );
    }
    public bool IsReusable { get { return false; } }
}

Nothing special here, right? Now, take a look at the following HTML snippet:

<body>
    <input type="text" />
    <input type="button" value="Server" />
    <div></div>
</body>
<script type="text/javascript">
    $(function() {
        $("input[type=button]").click(
            function(){
                $.get("HowdyHandler.ashx",
                      { name: $("input[type=text]").val()},
                      function(data){
                        $("div").html(data);
                     });
            });

    });
</script>

We’ve got a textbox and a button which will fire the AJAX request. If you run the previous snippet, you’ll see that you’ll end up doing an HTTP GET request and that you’ll get the “Hi name” message in the div.

Even though getting HTML from the server is handy, it’s not something that I’d do in a typical web app. In my opinion, the server side should only return info  and the HTML formatting should be done by client side code (ie, code running in the browser). In these scenarios, I’ll probably tend to use JSON for the response. Lets update our handler to do that:

public void ProcessRequest(HttpContext context) {
    context.Response.ContentType = "application/json";
    context.Response.Write(
            String.Format("{{ ''name'': ''{0}'' }}", context.Request["name"]) );
}

And now, we need to update our $.get call so that it knows that the response will be in JSON:

<script type="text/javascript">
    $(function() {
        $("input[type=button]").click(
            function(){
                $.get("HowdyHandler.ashx",
                      { name: $("input[type=text]").val()},
                      function(data){
                        $("div").html("Hi <b>" + data.name + "</b>" );
                     },
                     "json");
            });

    });
</script>

With this approach, we build the HTML in the client side. Since we’ve said that the response will be in JSON (notice that last parameter of the $.get function), data will now reference a JS object built from the JSON that is returned from the server.

The $.post utility function is really similar to the $.get function. The main difference is that you end up doing an HTTP POST request instead of a GET. And that’s it for this post. Keep tuned for more on JQuery.

Aug 17

Today marks the beginning of using JQuery for handling AJAX requests. This is going to be a short post and we’ll be talking about the load method. The load method is able to perform get or post requests to replace the contents of the elements contained in the wrapped set with the response returned from the server side. As you’ve probably guessed, this method will only be usable in certain (few!) scenarios, where you’ll be writing the returned contents directly into one or more HTML elements (in my opinion, returning HTML from the server is a bad practice and you should avoid it at all costs).

To illustrate the use of the load method, we’ll start by creating a new ASP.NET handler (which I’ll be appropriately calling DumbHandler) which returns the current server time:

public class DumbHandler : IHttpHandler {
    public void ProcessRequest(HttpContext context) {
        context.Response.ContentType = "text/html";
        context.Response.Write(
String.Format("<p><span>{0}</span></p>", DateTime.Now)); } public bool IsReusable { get { return false; } } }

Now that we’ve got the handler, we can concentrate on the client code. The load method expects until three parameters:

  • the url of the “page” that will be requested;
  • an optional data parameter that might contain an anonymous object with name/value pairs (results in a post request) or a string of name/value pairs (means you’ll be using a get request);
  • an optional callback method which will be fired when the AJAX request ends and each of the wrapped elements is updated with the returned content. Notice that this will also be called when you get an error in the request.

With this info, lets get started and build our first client AJAX script:

<p id="main">This is a paragraph</p>
<p>This is another paragraph</p>
<input type="button" value="Replace content" id="bt" />
<script type="text/javascript">
    $(function() {
        $("input[type=button]").click(function() {
            var url = "DumbHandler.ashx";
            $("#main").load(url);
        });
    });
</script>

The idea is simple: we handle the click event by performing a remote request through the load method. Since we’re only passing the url, this means that we’ll be performing a GET request and that the returned contents will be “written” inside our p#main paragraph.

Lets suppose that I need to pass additional info to the server. If we want the info to be sent through GET, then we need to pass that information through the data parameter as a string. Here’s how we’d do that:

$("input").click(function() {
    var url = "DumbHandler.ashx";
    $("#main").load(url, "user=Luis");
});

Really simple, right? Ok,but what if we needed to get that info form form fields? In that case,the serialize method is the way to go. To illustrate this method, let’s start by adding a form to our HTML page:

<form>
    <label for="name">Name:</label>
    <input type="text" name="name" />
    <br />
    <label for="age">Age:</label>
    <select name="age">
        <option value="1">10-20</option>
        <option value="2">21-30</option>
        <option value="3">31-40</option>
        <option value="4">41+</option>
    </select>
    <br />
</form>
<p id="main">This is a paragraph</p>
<p>This is another paragraph</p>
<input type="button" value="Replace content" id="bt" />

And here’s the changes we need to make to get the serialized info from our form fields:

$("input").click(function() {
    var url = "DumbHandler.ashx";
    $("#main").load(url, $("form").serialize());
});

If you want, you can only load a subset of the returned HTML. To do that, you need to filter the returned HTML by using a special selector delimited by SPACE on the url string. To show how this works, lets update our handler so that it returns the info that is sent through the AJAX request:

public void ProcessRequest(HttpContext context) {
    context.Response.ContentType = "text/html";
    var name = context.Request["name"];
    var age = context.Request["age"];
    context.Response.Write(
            String.Format("<p>Name:<span>{0}</span> at {1} </p>", 
name, age)); }

As you can see, we return an html snippet which looks like <p>Name: <span>XXXX</span> at YYY<p>. Lets assume that we’re only interested in showing the span element. That can be easily achieved by using the following url:

var url = "DumbHandler.ashx span";

Notice the space delimiting the url from the selector…

As I’ve said, you can also pass a callback method. This method will receive three parameters:

  • the response text returned from the current request;
  • the text status (success is passed when everything runs ok);
  • a reference to the current XMLHttpRequest object that was responsible for executing the server side call (this lets you get more info about possible errors).

As you’ve probably guessed, the this reference will point to the “current” updated element of the wrapped set (don’t forget that the method ends up being called after each element of the wrapped set has been updated with the info returned from the server).

And I guess this concludes this first query on JQuery and AJAX. Stay tuned for more.

Aug 14

In the previous posts, we’ve met several methods which run some predefined animations. Instead of trying to add methods for all possible animations, JQuery has decided to introduce a helper function which you can reuse for animating several css properties (notice that you can only animate properties which expect numeric values).

Currently, there are two “overloads” of the animate method:

animate(props, duration, easing, callback)
animate(props, options)

As you can see, there are a lot of things going on here:

  • props is an anonymous object which indicate the css properties that should be animated and their final values. It’s possible to use em or % as units and you can even use relative animations by passing –= or += to decrement or increment the current value of the specified css property;
  • duration is used for defining the duration of the animation. It’s an optional parameter and, in 1.3, if you set it to 0, JQuery will synchronously set the elements to their end state. Before you ask,the answer is yes,you can also use the magic strings we’ve met in the past (slow, normal and fast);
  • easing indicates the name of a previously registered function for performing the easing. According to the docs, there are two predefined easing functions: “linear” and “swing”;
  • callback references a callback function which will be called for each of the elements when the animation ends;
  • options is used on the second “overload” and it expects an anonymous object for setting the animation. Currently, you can define values for duration, easing, complete, step (method reference which will be called for each step of the animation) and queue (boolean value which indicates if the animation should be queued or started immediately).

There are some properties which probably deserve additional info. Easing influences the processing of frames and relies on mathematical calculations. I’m not really into this stuff, so I’ll leave further investigation of it to you 🙂

If you use the “overload” which uses the options object, then you’ll also be able to decide if animations should be run in parallel. By default, animations are run synchronously, that is, if you call animate several times, one animation will only start after the other has finished (don’t confuse calling animate several times with animating several properties at once in a single animate call). If you’d like to run an animation at the time of invocation, then you’ll need to set the options’ queue property to false.

I’m sorry, but I’m not really into design and effects, so I guess that the sample code for this post we’ll have to be even dumber than the ones I’ve presented in the  past. Take a look at the following code which animates an existing paragraph:

<p id="paragraph">This is a paragraph</p>
<input type="button" value="Move and grow" id="bt" />
<script type="text/javascript">
    $(function() {
        $("input").click(function() {
            $("p").css("position", "relative")
                  .css("backgroundColor", "green")
                  .animate( {left:100,
                                    width: "-=20%",
                                    height: 300
                                    },
                                    200);
                });
    });
</script>

Clicking the button kicks off a series of custom animations. We start by moving the P element so that it stays 100px left of the original position. Then, we decrease its current height by 20% and set its height in 300px. The whole thing should run in 200 ms.

I’ll change the previous example slightly in order to show you how you could kick several. Take a look at the following code:

<script type="text/javascript">
    $(function() {
        $("input").click(function() {
            $("p").css("position", "relative")
                  .css("backgroundColor", "green")
            //.animate({ left: 100 }, 100)
                  .animate({
                      left: 100,
                      width: 300
                  },
                    5000)
                .animate({
                        height: 100
                    },
                    {
                        duration: 5000,
                        queue: false
                    });
        });
    });
</script>

Try changing the value of queue property and see what happens. Since I’ve set the animation to 5 seconds, it should be enough for understanding what’s going on.

And that’s it! Keep tuned for more on JQuery!

Aug 13

Protected: JQuery: sliding

Posted in JQuery       Enter your password to view comments.

This content is password protected. To view it please enter your password below:

Aug 12

JQuery: fading elements

Posted in JQuery       Comments Off on JQuery: fading elements

In this post we’ll keep looking at the animations and we’ll see how to add fading effects to an element. Unlike showing and hiding, which affect several css properties of the element, fading will only affect the opacity (alpha filters if you’re running IE) and display of an element. Currently, JQuery offers 3 methods: fadeIn, fadeOut and fadeTo.

Here’s a small sample that shows how you can use the fadeIn and fadeOut methods:

<p id="div2">div 2</p>
<input type="button" value="fade in/out" />
<script type="text/javascript">
    $(function() {
        $("input").toggle(
                    function() { $("p").fadeOut(300); },
                    function() { $("p").fadeIn(300); }
                    );
    });
</script>

If you run the previous snippet, you’ll see that odd clicks change the element’s opacity in 300 ms and then it will be “removed” from the view (ie, its display will be set to none at the end of the animation). Fading in performs the opposite operation, changing the opacity from 0 to 1. Both methods can receive two parameters:

  • the first indicates the speed  to run the animation. You can specify it in milliseconds (like we did in the previous snippet) or you can use one of the “magic” strings: slow, fast or def (stands for default). Notice that passing anything different from slow or fast is the same as passing def;
  • the second identifies a callback function which will be fired when the animation ends. You can use the this reference inside the function to get a reference to the DOM element that was animated.

If you’ve set an initial opacity to the element by applying a style, then that value will be retained by these methods and fading in will always recover the element’s initial opacity.

If you’ve run the previous sample, you’ve probably noticed that fading in and out result in setting the opacity to 1 and 0 respectively. In other words,those methods will always show or hide an element. If you need to go half way (ex.: change the opacity to 0.5),then you should use the fadeTo method. Let’s update the previous sample so that it fades an element between 0.2 and 0.8:

<script type="text/javascript">
    $(function() {
        $("input").toggle(
                    function() { $("p").fadeTo(300, 0.2); },
                    function() { $("p").fadeTo(300, 0.8); }
                    );
    });
</script>

The fadeTo method expects until 3 parameters:

  • the first indicates the speed (it’s used in the same way as the speed parameter used in the fadeIn and fadeOut methods. Notice that you can also use the same “magic” strings we’ve mentioned above);
  • the second indicates the final value of the opacity and should have a value between 0 and 1;
  • finally, you can pass an (optional) callback method which will be fired when the animation completes.

There’s a really important difference between fadeTo and the previous fade methods: fadeTo won’t do anything to the css display property of the element that is being animated.

And that’s it. In the next post we’ll take a look at sliding. Keep tuned for more on JQuery.

Aug 10

JQuery: utility functions X – extending objects

Posted in JQuery       Comments Off on JQuery: utility functions X – extending objects

This is the last post of the day on JQuery and we’re going to talk about extending objects with the extend utility function. The idea is simple: how can you add properties from an object to another and get a new object? For instance, suppose you’ve got these two anonymous objects:

var student = { name: "Luis", age: 20 };
var address = { street: "some street", civilParish: "somewhere"};

And now you’d like to add the address’ properties to the student object. You can do that by using the extend function:

var extendedStudent = $.extend(student, address);

If you’re using a debugger, you’ll notice that student has been “expanded” with the two properties defined on address:

extend

Notice that this method expects more parameters that the ones that we used in the previous snippet. If you pass several objects, you’ll end up adding the properties of all those objects to the first object. If some of the copied objects have properties with the same name, then the values of the last objects will override the initially copied values of the previous ones.

There’s also a first optional boolean parameter which you can use to indicate if you’re doing a deep or a shallow copy of the properties of the objects. This parameter is optional and you’ll end up with a shallow copy when you don’t specify a value.

And that it’s for today. I guess we’ve covered most of the current utility functions and now we’re ready to look at animations. Keep tuned for more on JQuery.

Aug 10

The map utility function can be used to translate all the elements contained in the array into other set of items. You’ll find this method useful when you need to transform a collection of items A into items. The function expects two parameters:

  • an array of items that is going to be translated;
  • a callback function which will be called for each item and is responsible for transforming the existing item into a new item.

Here’s a simple example which doubles all the integers contained on an array named arr:

var arr = [1, 2, 3, 4];
var doubled = $.map(arr, function(item) { return item * 2; });
alert(doubled);

You might be thinking that this is so simple that you could do it by using a simple for. Fair enough…and if I told you that I’d like to receive only the double of elements which aren’t divisible by four? Here’s how you’d do that:

var arr = [1, 2, 3, 4];
var doubled = $.map(arr, function(item) { if( item % 4 === 0 ) return null; return item * 2; });
alert(doubled);

Returning null removes an item from the final array. Ok, I can hear you thinking! Yes, this is still doable with a simple for and using continue for the cases that don’t matter…And what if I told you that I want the first three multiples of all numbers which aren’t divisible by four? (and I’m talking about a flat array, not an array of arrays). Here’s how you’d do it with this utility method:

var arr = [1,2,3, 4];
var doubled = $.map(arr,
function(item) {
    var items = [];
    var i = 0;
    while (i++ < 3) {
        items[i ] = item * i;
    }
    return items;
});

Simple and easy, right? For the sake of completeness, I’d like to point out that the callback function receives two arguments: the first (which was used in all the previous samples) references the current item of the array that is being enumerated; the second returns the current position within the array. Keep tuned for more on JQuery.

Aug 10

Protected: JQuery: utility functions VII – concatenating arrays

Posted in JQuery       Comments Off on Protected: JQuery: utility functions VII – concatenating arrays

This content is password protected. To view it please enter your password below:

Aug 10

JQuery: utility functions VI – checking if an item is in an array

Posted in JQuery       Comments Off on JQuery: utility functions VI – checking if an item is in an array

In the last post we’ve seen how to get all the items that comply with a specific filter. In this post, we’re going to see how to see if an item is in an array. The easiest way to do that is to use the inArray function. Take a look at the following snippet:

var arr = [0, -2, 4, 6, - 9];
var positives = $.inArray(4,arr);

The inArray method expects two parameters: the item that is going to be checked and the array that is going to be enumerated. Internally, the utility function relies on the the === operator for seeing if any of the array’s items matches the first parameter.

Notice that inArray returns an integer. It will return  non negative integer that represents the position of the passed item. If it doesn’t find a matching item, it will simply return –1. And that’s it. Keep tuned for more on JQuery.

Aug 07

JQuery: utility functions IV – interacting through arrays

Posted in JQuery       Comments Off on JQuery: utility functions IV – interacting through arrays

In this post, we’re going to look at the each utility function. This function expects two parameters: an object which is going to be enumerated and a callback function reference which is going to be called for each item in the enumerated set. It’s important to understand that this is different from the each jQuery method (which is used for interacting over each element of the wrapped set).

Traditionally, you use indexes for going through all the items in an array. There are also some times where you need to enumerate all the properties of an object. In those cases, you’ll generally use the for in loop. If you want, you can reduce the code needed by using the each method. When you’re using an array, you’ll be writing a function that receives one parameter:

var arr = [1, 2, 3];
$.each(arr, function(val) { alert(val); });

On the other hand, if you’re enumerating properties, then you’ll need (at least) two parameters: one for the property name and another for the value:

var obj = { name: "John", age: 12 };
$.each(obj,function(prop,val) { alert(prop + ":" + val) });

You probably won’t find much value in using the functionality of this method, but  you’ll notice that it does reduce the amount of required typing. Before ending, there’s still time for saying that returning false from the method results in stopping the enumeration of the existing items.

And that’s it. Keep tuned for more on JQuery.

Aug 07

Protected: JQuery: utility functions – testing helpers

Posted in JQuery       Comments Off on Protected: JQuery: utility functions – testing helpers

This content is password protected. To view it please enter your password below:

Aug 07

Today we’re going to start looking at the JQuery utilities function. The utilities function include several low level helper methods used on JQuery’s core. The good news is that you can also reuse them in your own code. In this post we’re going to take a look at the browser detection helper functions.

Before v1.3, JQuery had several helper objects for getting info about the the browser where your pages were loaded. These objects were called browser, boxModel and styleFloat and they can (still) be accessed through properties on the jquery object ($.browser, $.boxModel and $.styleFloat). With v1.3, these old objects have been deprecated by a new property called support which contains most of the information you had in the previous properties. The advantage of the new support object is that it relies on feature detection instead of browser sniffering.

Here is a quick preview of the properties you’ll find in the support object:

  • boxModel: returns true if the page renders the box model according to the W3C Spec;
  • cssFloat: true if style.cssFloat gives you access to the current CSS float value of an element;
  • hrefNormalized: returns true when the browsed does not normalize href attribute values;
  • htmlSerialize: true when the browser serializes link elements when innerHTML is used;
  • leadingWhitespace: true if the browser preserves leading whitespace when innerHTML is used;
  • noCloneEvent: true if the browser does not clone event handlers when elements are cloned;
  • objectAll: equal to true when getElementsByTagName(“*”) returns all descendants;
  • opacity: true if a browser can properly interpret the opacity style property (IE still relies on alpha filters);
  • scriptEval: true when appendChild or createTextNode executes injected inline scripts;
  • style: returns true only when getAttribute(“style”) returns the inline style specified on an element;
  • tbody: true when browsers allow tables without tbody elements (IE adds the tbody element if you don’t explicitly add one to your HTML).

As you can see, many of these features won’t be used on day to day programming. However, if you’re a plug-in writer or if you intend to write Javascript code that isn’t browser specific, then these methods might help you in a couple of more uncommon scenarios.

I guess that one of things that might have bitten you in the past is the box model. Currently, you can resume the problem to IE being able to render HTML element’s boxes in a standard way or in the quirks mode way (so that it is compatible with previous versions of the browser). With the W3C box model, the width/height defines the width/height of the content while IE’s quirk mode uses the width/height values for defining the total size of the element’s box.

You’ll see no difference on sizes until you start using padding, margins or border widths. When you do that, you’ll notice that the in quirks mode the box will be fixed to the initial size specified through the width and height values,,). If you want to do your own calculations regarding the correct width and height and you need to make it work across several browsers, you can rely on this property for using the correct values.

cssFloat might also be useful when you need to know how to get to the float style of a specific element. Take a look at the next example:

<div>
    <div id="left">left</div>
    <div id="right">right</div>
</div>
<input type="button" id="change" value="Swap" />
<script type="text/javascript">
    $(function() {
        $("#change").click(function(evt) {
            var lft = $("#left")[0];
            var rgt = $("#right")[0];
            if ($.support.cssFloat) {
                lft.style.cssFloat = "right";
                rgt.style.cssFloat = "left";
            }
            else {
                lft.style.styleFloat = "right";
                rgt.style.styleFloat = "left";
            }
        });
    });
</script>

The code shows how you can use the cssFloat property to change the initial floating applied to the element. Notice that I’m doing this only for demonstrating purposes because if this was a real app, I’d really use the css method (it would reduce the number of lines of code needed, which is always a good thing, right?).

Getting the href url is generally done through the href property. However, we’ve already seen in a previous post that most properties get their values from an attribute bag. In most cases, properties can be seen as a shortcut. However, that’s not the case of the href property. When you access the href property, you’ll  always get the complete url. That might not happen if you access the value through the attribute bag. Take a look at the following snippet:

<a href="another.html">Another page</a>
<input type="button" id="show" value="show" />
<script type="text/javascript">
    $(function() {
        $("#show").click(function(evt) {
            var a = $("a")[0];
            alert($.support.hrefNormalized + " - " + a.getAttribute("href"));
        });
    });
</script>

If you run this code in a IE 7 or below, you’ll notice that the browser normalizes the url you’ve passed to the href attribute. That doesn’t happen when you’re using IE8 or any of the other main browsers (I haven’t tested it in safari).

leadingWhitespace still produces different results when you compare IE with the other browsers. What this means is that IE8 still doesn’t respect leading whitespaces when you add content through the innerHTML property. Object cloning is also different in IE. The noCloneEvent property shows us that IE will clone event handlers when you clone an element (in other words, it returns false). That doesn’t happen in most of the other browsers. And the same thing happens for most of the remaining properties presented on the previous list (and that’s why I won’t go into details on all those properties).

At the beginning of this post I said that the great advantage of the support object was that it relied on feature detection. In practice, this means that the code won’t use the traditional navigator object for getting information about the browser. If you look at JQuery’s code, you’ll notice that it creates several dumb elements in order to initialize the properties of the support object. This is great because the results returned from this detection process are way more accurate than the ones you’ll get with the navigator object (just remember that most browsers allow you to set a custom user agent string!). If you’re interested in seeing how it’s done,then you’ll have to scroll until line 3114 of the JQuery’s JS file.

And that’s it for today. Keep tuned for more on JQuery.

Aug 05

There are certain scenarios where you handle events in “pairs”. For instance, I guess we’ve all written JavaScript code for handling mouse over and mouse out events (which, btw, is also commonly known as hovering). Take a look at the following snippet:

<div>
Mouse over turns green! Mouse out turns black...
</div>
<script type="text/javascript">
    $(function() {
        $("div").bind("mouseover", function() {
           $(this).css("color", "green");
        });
        $("div").bind("mouseout", function() {
           $(this).css("color", "black");
        });
});
</script>

If you run the previous sample, you’ll see that putting the mouse cursor over will result in changing the div’s text color to green and removing it will turn it back to black. JQuery simplifies the code we need to write in these scenarios by introducing the hover method. Here’s how the code would look if we used that method:

<script type="text/javascript">
    $(function() {
        $("div").hover(
        function() { $(this).css("color", "green"); },
        function() { $(this).css("color", "black");});
});
</script>

The hover method expects two parameters: the first function will be invoked when the mouse enters the target and the second will be called when the cursor leaves that target.

Besides this helper,there’s also the toggle method. This method receives two or more functions and will call each function one at a time for each click done over any of the container’s wrapped set elements. The next snippet keeps changing the text color of all divs for each click:

$(function() {
    $("div").toggle(
    function() { $(this).css("color","green"); },
    function() { $(this).css("color", "red"); },
    function() { $(this).css("color", "blue"); },
    function() { $(this).css("color", "black");});
});    

Notice that there are no restrictions to the number of functions you can pass to the toggle method (and you’ll typically pass at least two when using this method.

And that’s all for now. Keep tuned for more on JQuery.

Aug 05

JQuery: more on the triggerHandler method

Posted in JQuery       Comments Off on JQuery: more on the triggerHandler method

In the previous post I’ve shown you some code on how to use the triggerHandler method. At the time, I said that events would bubble even though the docs say that they won’t. I based my conclusions on a small simple test I’ve written. ingmar added more information on a comment saying that if you have a more complex tree, you won’t get the “correct” bubbling. For instance, with the following structure:

<div>
    <p>This is some hidden content</p>
    <p>And more hidden content</p>
</div>

you’ll get the following bubbling: P->BODY->HTML. So, what’s happening here? Well, it’s simple: I was wrong. The fact is that the bubbling I was seeing was coming from my button’s click event and not from the triggered element. Let’s take another peek at the script code I’ve written:

<script type="text/javascript">
    $(function() {
        $("*").not("input").click(function(evt) {
            alert(evt.currentTarget.tagName + " clicked");
            return "hi";
        });
        $("#trigger").click(function() {
            $("p").trigger("click");
        });
        $("#triggerHandler").click(function() {
            alert($("p").triggerHandler("click"));
        });
    });
</script>

As you can see, we’re hooking up all the elements’ click event (excluding inputs) with an anonymous function that displays an alert message with the tagName of the current target element. Now, when I wrote the small sample, I concentrated on the P’s click event and this was what I saw:

P->BODY->HTML

Since my initial markup looked like this:

<p>This is some hidden content</p>
<p>And more hidden content</p>

I completely forgot that the click event of the button would also propagate through the tree until it reaches the top element. Notice that when you dispatch an event from within an existing handler, that handler will be “suspended” until that “new” event is completely dispatched. When that happens, the “previous” event that was in “stand by” wakes up and goes through its normal lifecycle. So, if I had written this code:

$("#triggerHandler").click(function(evt) {
    alert($("p").triggerHandler("click"));
    evt.stopPropagation();
});

it would have been obvious that there was no bubbling coming from the P’s click event that has been dispatched through that anonymous function. I guess that the moral of the story is that I should pay more attention to the samples I’m writing during my JQuery tests. Thanks go to ingmar for putting me in the right track. Keep tuned for more on JQuery.

Aug 03

JQuery: DOM level event model support

Posted in JQuery       Comments Off on JQuery: DOM level event model support

In the previous posts, we’ve taken a peek at the several DOM levels that exist. In this post, we’ll see how JQuery supports these levels. Well, as you might expect, JQuery supports most of this stuff. The only thing that is not supported is the capture phase. In other words, you’ll only get bubbling events if you’re using JQuery.

To be honest, I still haven’t used any capture events until today. Probably that’s because IE doesn’t support it and since I need to write code that runs in IE, I never really explored its use. I guess that what I’m saying is that you’ll probably live without the capture phase, right?

Most of the other features presented on the DOM 3 level event model (if not all) are covered by JQuery. For instance, it hides IEs discrepancies on the Event object from you and, as we’ve seen, it ensures that handlers will always receive an Event object as its first parameter. And there’s not much to say about JQuery’s compatibility with the DOM level model. I guess there’s still a couple of things to talk about regarding events,but we’ll leave them for future posts.

Aug 03

JQuery: DOM 3 level event model

Posted in JQuery       Comments Off on JQuery: DOM 3 level event model

Today we’re going to talk (briefly) about the last DOM event level which isn’t still supported by all browsers. DOM 3 level event builds on level 2 and adds some new features. Most of the things we’ve mentioned in the previous post still hold. For instance, the propagation model we’ve discussed is still there, as you can see from the following picture (which I’ve found in the DOM 3 level spec):

eventflow

The DOM 3 level clarified several principles introduced by DOM 2 level spec and added some new event types. Besides that, it also updated several interfaces and it  has event added a new interface for custom events: I’m talking about the CustomEvent interface.

With custom events introduced, you can focus on the behavior you’d like to have instead of the markup that you use for implementing that piece of functionality. For instance, suppose you’ve got a collapsible panel. In that case, I’d say that the expected events would be collapse and expand, right? Since JQuery is (sort of – more about this in the next post) compatible with the DOM 3 level model, then I guess this is a good time to show a quick sample of how this might work. Take a look at the following HTML:

<h3>Custom events</h3>
<div>
 <p>This is some hidden content</p>
 <p>And more hidden content</p>
</div>
<input type="button" id="expand" value="Expand" />
<input type="button" id="collapse" value="Collapse" />

The idea is to click one of the buttons and get the desired behavior (ie, expand and hide the contents of the div). Now, take a look at the code of the buttons:

$("#expand").click(function() {
  $("div").trigger("expand");
});
$("#collapse").click(function() {
  $("div").trigger("collapse");
});

I guess that this is new, right? Clicking the expand button will trigger the expand event on existing divs. As you know,there really isn’t  any DOM expand event,so this is  a custom event. Since we’re using JQuery, we don’t have to worry with every detail associated with the creation of the custom event nor with firing the event (yes, it does involve some javascript code, but I’ll leave that exercise to you). Notice that we just call trigger and pass it a method. And that’s it. Btw, we could even simplify the triggering by using something like this:

$("*").trigger("expand");

The advantage of doing this is that we would be firing the expand event on all existing elements.

Handling the event is also simple: we can simply rely on our old friend, the bind method. Take a look at the code that hooks up the custom event:

$("div").bind("expand", function(data) {
  $("div").show("slow");
});
$("div").bind("collapse", function(data) {
  $("div").hide("slow");
});

Don’t worry with the show and hide methods for now (we’ll talk about them in the future, when we look at animations!). Hooking up a handler is really simple too: we start by getting a reference to the div (since we have only one, we use the div selector) and then use the bind to hook up the anonymous function with the custom event.

By now you must be thinking that you didn’t really get much from using custom events. If you think in terms of LOC, then you’re right. However, since we’re concentrating in custom events, we end up building a new model based on *behavior*. With this model, we get independence from the markup and form the traditional events. 

And I guess that’s all for now. Since we’ve already looked at the existing DOM levels, I guess we can go back to JQuery and see how compatible it is with the existing DOM level standards. Keep tuned for more on JQuery.

Jul 30

Today we’re going to start talking about JQuery event’s propagation. Before delving into JQuery’s behavior, I guess that we need to make a small detour and talk about JAvascript and DOM events levels compatibility. By now, most of us have already heard the terms DOM level 0 event compatible or DOM level 2 event compatible. But what does this mean? The first thing you should keep in mind is that there are several levels and that each level specifies several features that should be implemented by all compatible browsers.

The first level is know as DOM Level 0 and was based on the event model introduced by the first browsers (notice that there really isn’t a DOM level 0 standard). Currently, this level is supported by all existing browsers. Level 0 gives you two options for handling events. You can hook up an event and a function by using an attribute on the form onXXX, where XXX is the event you want to handle. Take a look at the following snippet:

<input type="button" value="Say hi!" id="bt" onclick="sayHi()" />
<script type="text/javascript">
 function sayHi(evt) {
  alert("hi!");
 }
</script>

I guess that we’ve all written this code in the past, right? Not really good quality code, but hey, it works in all browsers, right? The second option for this level relies on the mappings that exist between HTML attributes and properties on JS objects that represent HTML elements (we’ve already talked about this in a previous post). The next snippet is equivalent to the previous one, but relies on JS code:

<input type="button" value="Say hi!" id="bt" />
<script type="text/javascript">
 $("#bt")[0].onclick =  function(evt) {
                          alert("hi!");
                         }
</script>

Now, even though this option is better than the previous one (notice that we removed the JS code from the markup), there are still some problems. For instance,if anyone else hooks an event that has been previously set,it will end up removing the previous handler.

Even at this level, there are still some differences between browsers. For instance, if you look at the previous examples, you’ll notice that the function receives an evt parameter. That parameter should automatically references the event object that contains information about the current event. Unfortunately, IE doesn’t comply with this and you’ll find a reference to the current event object on the window’s event property.

Now, level 0 event introduced another very interesting feature: event bubbling. Whenever an event is generated at an element, it will propagate until it reaches the top level element. That’s why it’s called bubbling: it goes in a bottom-up direction. Take a look at the following example:

<div id="top">
    <div id="inner">
        <p id="paragraph">Just some text</p>
    </div>
</div>
<script type="text/javascript">
    $("*").each(function() {
        this.onclick = function(evt) { alert(this.id); };
    });
</script>

The previous example will use DOM 0 level code for setting up the click event of all existing DOM nodes. If you run the code, you’ll see that you’ll get an alert starting and the p element and then the event will propagate until it reaches the top HTML element (to see this you’ll probably need to replace the this.id with this.tagName expression in the alert invocation).

Now, this is really cool because it means you can handle a specific event by hooking up that event at a top level. Cancelling the default bubbling is possible: just call the event’s stopPropagation method.

function(evt) { alert(this.id); evt.stopPropagation();  };

Notice that this really isn’t a level 0 feature (in fact, it’s a level 2 feature). As you might expect by now, IE uses a different method for cancelling propagation: the event’s cancelBubble property must be set to true (don’t forget that in IE you need to use window.event to get to the event object).

There’s still one more thing you need to know before we call it a day: some events have predefined default actions assigned to them. I guess that the most known example is submitting a form. Form submission generates a submit event which, by default, ends up sending the form’s data through a post or get request. Notice that this will happen even if you set up an event handler:

<form method="post" id="frm">
    ´<input type="submit" value="submit form" />
</form>
<script type="text/javascript">
    $("#frm")[0].onsubmit = function(evt) {
        alert("submitting");
        //how to cancel default action?
    };
</script>

If you run the previous code, you’ll always get a post request. The question is: how can I cancel that form submission? In these cases, most people will simply return false from this method. By doing that, you’re saying that you’re not interesting in getting the default behavior associated with that event. DOM 2 level introduces a preventDefault method you can use to signal the cancellation of the default action associated with an event. Notice that this method won’t cancel event bubbling. I guess that we’re already starting to go into DOM level 2 event land, so we’ll stop here. On the next post we’ll look at what DOM level 2 introduced so that we can finally take a look at how JQuery protects us from knowing all this stuff. Keep tuned!

Jul 14

JQuery: more on selectors

Posted in JQuery       Comments Off on JQuery: more on selectors

On the previous post, we’ve started looking at selectors. In this post, we’ll close our study of selectors and we’ll talk about the remaining selectors. Let’s get started with child selectors. Before going on, we need an HTML tree. The one we used in the last post will do it:

<h1 class="title">Getting started with selectors</h1>
<p>There are several kind of selectors. Here are some of the most use:</p>
<ul>
  <li>you can select by tag</li>
  <li id="selectByID">you can select by ID</li>
  <li class="something">you can select by class name</li>
  <li>you can select by by attribute</li>
  <li>you can select by attribute with value</li>
</ul>
<div>
  <p>This is a paragraph inside a div</p>
</div>

Now, we can proceed. There will be times where you’re interested in getting the child of an element. For instance, the following snippet gets the direct children of div elements:

$("div > p")

Notice that the previous form will only return the direct children, instead of all descendants (you get all descendants by using the expression $(“div p”)). JQuery lets you pick elements that contain other elements too. For instance, what do you think will happen with the following snippet:

$(“div:has(p)”)

If you say that it will return the div element which contains a paragraph, you’re absolutely correct! Notice that this is not the same as $(“div p”) (this last example returns all paragraphs contained on a div!). The only gotcha of this selector is that it only allows you to go one level down, ie, the following example won’t work:

$(“div:has(p:has(span))”)

Btw, getting all elements preceded by another is easily accomplished too. For instance,the  expression $(“ul+div”) returns all div elements immediately preceded by ul (in the previous snippet,we had one that fits this selector). In this case, you can also get the same result from the expression $(“ul~div”). Notice that the ~ char will return all div siblings (whether they‘re immediately  placed after the ul or not – for instance, if we had ul-p-div, then the last expression that used ~ would return a valid result, but the one that used the + form wouldn’t wrap any valid DOM node).

JQuery also supports selecting by position. Here are a couple of examples:

  • you can wrap the first child in a JQuery object by using the :first selector. For instance, the expression $(“li:first”) returns the first li child defined on the page;
  • you can get the last child by using the :last selector. Calling $(“li:last”) returns the last li element of the page;
  • You can also get first and last children of items by using the :first-child and :last-child selectors. Besides getting the first and last child elements, you can also get a child at a specific position by using the :nth-child(pos) selector – where pos is the position of the element;
  • there’s also a variation of previous form that consists on using the words odd or even to specify all odd and even children of a specific type (ex.: getting all the odd li elements can be achieved through the $(“li:nth-child(odd) expression). There’s even a more advanced pattern for getting positioned elements. For instance, suppose you want to get every 4th li element. Easily doable with something like $(“li:nth-child(4n)). Or probably you want every li item after each 4th element: $(“li:nth-child(4n+1)). Notice that the :nth-child selector starts its count in 1 (and not in 0);
  • Still on positioning, there’s a couple of selectors you can use. the :eq(pos) selector returns the element positioned at position pos; :gt(pos) and :lt(pos) return all elements defined after pos (: gt selector) or all elements  positioned before pos (:lt selector).

Notice that if you have several li elements on different lists, then some of the previous selectors might end up returning li elements from different lists (unless, of course, you use a combination of selectors which end up limiting the returned elements).

There’s still a couple of selectors that we need to cover before we wrap up the selector portion of the tutorial, but we’ll leave them for future posts. Keep tuned for more on JQuery.

Jul 13

JQuery: getting started with selectors

Posted in JQuery       Comments Off on JQuery: getting started with selectors

In the last posts, we’ve started introducing JQuery. As we’ve seen, we start by getting a valid reference to a “JQuery object” that wraps one or more of the existing DOM nodes and then we can invoke one of several methods for interacting with those nodes.

This  means that the first thing you need to understand in order to use JQuery is how to get a reference to one or more existing DOM nodes (in future  posts, we’ll see that we can also create new DOM methods through the jQuery method). JQuery is extremely flexible and allows you to select elements through its selector syntax, which is based on the well known CSS selector.

In practice, this  means that you can use any of the known CSS selectors to get a JQuery object that wraps the matching DOM elements. The most interesting characteristic of this feature is that it doesn’t depend on the browser. In other words, even though the browser might not recognize a specific CSS selector, if it’s supported by the CSS standard, then JQuery will be able to understand it! Pretty cool, right?

Today, we’re going to start with the basic selectors and leave the more advanced ones for future posts. Take a look at the following HTML (we’ll be using it for showing how to use the basic selectors):

<h1 class=”title”>Getting started with selectors</h1>
<p>There are several kind of selectors. Here are some of the most use:</p>
<ul>
  <li>you can select by tag</li>
  <li id="selectByID">you can select by ID</li>
  <li class="something">you can select by class name</li>
  <li>you can select by by attribute</li>
  <li>you can select by attribute with value</li>
</ul>
<div> <p>This is a paragraph inside a div</p> </div>

Now, let’s suppose we want to select and hide all li elements defined on this page. How can we do that? It’s really simple with JQuery:

$(”li”).hide(500).show(200);

The previous snippet returns a JQuery object which wraps all li elements defined on the page.And how can we select all elements that have the something class applied to them? Again,really easy with JQuery:

$(”.something”)

The returned JQuery object will only wrap a single li (because that’s the only element which has that class applied to it). And what about getting all li elements with the class something? Yes,like CSS selectors, JQuery selectors let you specify a more specific rule:

$(”li.something”)

And how about getting all paragraphs placed inside a div. Yes, that’s also really easy with JQuery:

$(”div p”)

Really easy, right? Notice that you can mix selectors until you’re happy with the final result ( for instance, what do you think this selector does: div p.test span).

Another interesting thing you can do is getting elements which have attributes applied to them. For instance, suppose you want to wrap all the elements that have a class applied to them. Here’s how you can do that:

$(”[class]”)

In this case, you’ll end up with a JQuery object that wraps the h1 and li elements which have the class defined. Oh, and you can also wrap elements that:

  • have an attribute that start with a specific value.  For instance, a[href^=http://] is a good way of getting all HTTP links ;
  • have an attribute that end with a specific value. The syntax is  similar to the previous example, but you use the $ instead of the ^ symbol;
  • have an attribute which contains a specific text.  Once again, really similar to the previous example, but in this case, you’ll use the * character (ex.: get all inputs that have the string hi can be achieved through the selector input[value*=hi]);
  • have an attribute with a specific value. I guess that the simplest example of this is getting all text inputs from a page: input[type=text].

And I guess we’ve talked about enough selectors for one day 🙂 We’ll keep looking at selectors in the next posts. Keep tuned for more.

Jul 13

JQuery: chaining

Posted in JQuery       1 Comment »

[Updated: thanks to nyx for detecting that the button ID wasn”t correct]

As I’ve said in the last post, JQuery is all about writing simple and elegant code. One of its most interesting features is chaining. After getting a reference to the custom “JQuery object”, we can invoke several methods exposed by that object. What we didn’t mentioned yet is that many of those objects return a “JQuery object”. In practice, this means that we can invoke another “JQuery method” over the returned instance. Here’s a practical example that hides and shows the button that has been clicked:

<input type="button" value="my button" id="bt" />
<!-- more HTML code--> <
script type="text/javascript"> $( function() { $("#bt").click(function() { $(this).hide(500).show(200); }) }); </script>

As you can see, we’re hiding and then showing the button through the hide and show methods (don’t worry too much about the methods now because we’ll return to them in the future; for now, keep focused on the way you can chain method calls!).

Chaining is a really handy feature , specially if you recall that a JQuery object might wrap several HTML nodes! Suppose that the selector we’ve used ended up wrapping several DOM nodes… If that happened, then you’d end up hiding and then showing all the wrapper DOM nodes. Isn’t that cool? How many lines of  JS code would you need to write if you didn’t had JQuery? Not sure about you, but I don’t even want to think about that scenario…

Jul 11

JQuery: understanding the jQuery function

Posted in JQuery       Comments Off on JQuery: understanding the jQuery function

Yesterday we’ve started looking at JQuery. One of the most important things we’ve seen yesterday was that there’s an important JQuery object which has lots of methods and events we can interact with. Today, we’re going to take a more detailed look at the code we’ve written yesterday and we’re going to start looking at JQuery’s internals. Here’s yesterday’s code:

<input type="button"value="click me"id="bt" />  
<
script src="jquery-1.3.2.js" type="text/javascript"></script>
<
script type="text/javascript">
  jQuery(document).ready(
                 
function() {
                    $(
"#bt").click(
                             
function( evt ){
                                alert(
"hello JQuery");
                              })
                  });
</
script>
</
html>

The first important thing you should notice in this code is that we’re passing an anonymous function to the ready method. What does this method do? As I’ve said yesterday, this method will be fired whenever the DOM is ready to be used from scripting blocks. For Mozilla and Opera browsers, this means handling the DOMContentLoaded event. If you’re stuck with IE, then the platform will be calling document.attachEvent for handling the onreadystatechange event. As you can see, this means that you’ll be able to start interacting with the DOM before everything has been loaded (this is great for those cases where you’ve got huge images; without this event, you’d have to wait for those downloads before starting interacting with the DOM)

Notice that all this is done internally by the platform; you only need to pass a valid function to the ready event and that method will be called whenever one of those events are fired by the browser. Before going on, I’d also like to make a small improvement to the previous code:

<script type="text/javascript"> 
  $(
function() {
                    $(
"#bt").click(
                             
function( evt ){
                                alert(
"hello JQuery");
                              })
                  });
</
script>

The previous snippet presents a shortcut for the ready event: whenever you pass a function to the $() function, you’re actually hooking up the ready event! This is a nice shortcut and shows what JQuery is all about: simple and elegant code!

Btw, and since I’m still on vacations, I’ll wrap this up by showing you the current mappings of the jQuery method:

jQuery = window.jQuery = window.$ = function( selector, context ) {
        // The jQuery object is actually just the init constructor ''enhanced''
        return new jQuery.fn.init( selector,context );
    },

As you can see, jQuery, window.jQuery and window.$ all point to the same anonymous function which is responsible for creating the JQuery object. In the next post, we’ll keep digging into this fantastic framework. Keep tuned!

Jul 10

It’s official: I’m on vacations :,,) while I was enjoying the sun on the beach today (I did managed to get there in time after leaving work), I though that it would be a good idea to write about JQuery. Why is this a good idea? First, because my experiences with it have shown me that it’s really a great framework! Second, because my JS is a little rusty and needs some training. Finally, because this is my blog and I want to do this 🙂

So, without further ado, lets gets started, right? The first thing we’ll need is getting the necessary JS files. You can get the latest JQuery JS file from its homepage. Notice that there are several files for download. If you’re trying to understand the code, then you should download the development file. Don’t forget to use the production file when you deploy your apps.

Whenever you’re working with JQuery, you’ll end up using the JQuery wrapper object. The JQuery wrapper is a custom JS object which has several interesting properties/methods that makes working with the DOM a breeze. Since this is an intro post and I want to go back to the bar to enjoy a cool drink, I’ll wrap this post with a really simple example which will let me present some important features introduced by JQuery. The next snippet intercepts any click that is done over a button and shows an alert when that happens:

<input type="button"value="click me"id="bt" />  

<
script src="jquery-1.3.2.js" type="text/javascript"></script>
<
script type="text/javascript">
  jQuery(document).ready(
                 
function() {
                    $(
"#bt").click(
                             
function( evt ){
                                alert(
"hello JQuery");
                              })
                  });
</
script>
</
html>

This snippet shows several interesting things:…

the jQuery method returns a JS object with several interesting methods (more about this in future posts) and events. in this case, we’re passing an anonymous function that should be fired whenever the wrapped element(s) is(are) ready for being manipulated (in this case, the anonymous function will be load when the HTML document is loaded – notice that we’re wrapping the document instance).

The anonymous function uses the $ alias (it’s the same as calling jQuery) for getting a reference to the bt element (notice the use of the ID CSS selector). At this time, you should understand that the jQuery function (or its $ alias) return a reference  to the  JQuery wrapper object (not to an instance of the DOM,, though you can get it from this custom object if you wish). This object may contain one or more DOM references (we’ll see how in future posts), ie, you can create a JQuery object which wraps several HTML elements of your page. This is a powerful feature which will really lead to less code.

After getting a reference to the button, we end up creating a new anonymous function which will be executed when someone clicks the button. And that’s it. We’ve just written our first JQuery snippet. Things will get interesting in the next posts. Keep tuned.

Mar 03

The MVC framework: returning JSON

Posted in ASP.NET, JQuery, MVC       Comments Off on The MVC framework: returning JSON

After a few days without talking about ASP.NET MVC, it’s time to resume my study of the platform. Today we’re going to look at a special ActionResult type: the JsonResult class. You can use this specific ActionResult type for returning JSON from a controller’s action method. This class offers three public properties:

  • ContentEncoding: as you can suspect, you can pass an Encoding object that should be used for encoding the response returned from the server;
  • ContentType: used for specifying the content type of the current response (btw, you’ll get application/json as you might expect);
  • Data: user for passing the object that should be serialized and returned back to the client.

There’s really an important *internal* detail you should know when  you use this action result type: internally, it uses the JavaScriptSerializer class to serialize the object passed to the Data property of the class. This is important (especially if you’re returning dates from the server,as you’ll see in the example I’ll be presenting at the end of the post) and might force you to use the client Sys.Serialization.JavaScriptSerializer class for recovering the object that was serialized on the server side.

Lets take a look at a quick and simple example that shows how to use this action result type. We’re going to start by building an action method that returns the current time from the server. I’ve chosen this simple example so that I could point out some caveats regarding the use of this specific action result type. Here’s how the GetTime method looks like:

public ActionResult GetTime() {
   return Json( DateTime.Now );
}

Nothing could be simpler, right? Now, in order to get this from our view, we’re going to perform a GET call and we’re going to use JQuery to simplify the code we need to write in order to interact with the server (do keep in mind that you could use several approaches to invoke this controller method from the client side). We’ll start by adding the necessary JS files:

<script type="text/javascript" src=”<%= Url.Content( "~/Scripts/jquery-1.2.6.js"  ) %>”>
</script>
<script type="text/javascript" src=”<%= Url.Content( "~/Scripts/MicrosoftAjax.debug.js"  ) %>”>
</script>

We’re using the Url.Content method to get the correct url for the scripts based on the context of the current request. I’m also adding the MS ajax client file and you’ll see why in a minute (btw, do notice that I’m using the debug versions of these files. In a real world app, you’d really would want to use the minified versions of these files). Now, I’ll just add an anchor and some JS code for hooking up the click event: when a user clicks on the link,I’m going to perform my AJAX call and get the JSON with the current date from the server. Here’s that code:

<a href="#" id="loader">Get time</a>
<script type="text/javascript">
        $(function() {
          $("#loader").click(function() {
            $.get(
                  ”<%= Url.Action( "GetTime","Home" ) %>”,
                  null,
                  function(time) { alert(time); var t = Sys.Serialization.JavaScriptSerializer.deserialize(time); alert(t); }, "");
          });
        });
</script>

Some interesting observations:

I’m using the Url.Action to get the url for the controller’s method I want to invoke;

I’m using the JQuery get method to perform the ajax call. There were other options here…for instance, you might be tempted to use the getJSON method. Unfortunately, the getJSON method won’t work because it automatically tries to deserialize the returned data (which then gets passed to the callback method) and that won’t work here (due to the fact that there isn’t a standard way to represent dates in JSON). Btw, Rick Strahl has a several good post on JQuery. Here’s a good one that presents all the methods you can use for AJAX calls (and some of their caveats). In order to get the correct date in the client, we’re really forced to use the JavaScriptSerializer class. In fact, if you run the previous sample, you’ll see that time is really a string with the custom format used by the MS server platform for dates.

Before ending, there’s still time to mention the Json method that your controller inherits from the Controller class. There are several overloads of this method which let you specify all the available the properties of the JsonResult class.

Jan 14

JQuery 1.3 released

Posted in JQuery       Comments Off on JQuery 1.3 released

Hurray!!!

Sep 28

JQuery shipping with VS

Posted in ASP.NET, JQuery       Comments Off on JQuery shipping with VS

I”ve just read on Scott”s blog that JQuery is going to be shipped with VS. This is simply fantastic! I”ve been a fan of JQuery for some time now. It”s impossible not like its amazing flexibility and simplicity…and now we”ll have intellisense on VS and it looks like the future client side controls of ASP.NET AJAX (including the AJAX toolkit) will be written over it.

This is just great and I think that it”s a good move by MS (reusing instead of trying to build something when there”s a great product out there) that should also be followed with other similar projects…