August 2009 - Posts

JQuery: full control with the $.ajax function
Wed, Aug 19 2009 15:17

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.

by luisabreu | 2 comment(s)
Filed under:
VS 2010: full view for a single file
Wed, Aug 19 2009 13:24

One of the things I’ve been enjoying in VS 2010 beta 1 is the option to undock a file and make it fill the screen. To do that, you need to undock the file by double clicking on its tab. Then you’ll only need to maximize the window.

vsundock

Docking it again is really simple: you only need to access the dropdown menu and choose dock:

vsdock

Nothing too fancy, but, as I said, I do enjoy this feature.

by luisabreu | with no comments
Filed under:
If you’re driving, focus on the road
Wed, Aug 19 2009 12:26

Impressive video that I’ve found through Alberto’s blog.

by luisabreu | with no comments
Filed under:
JQuery: deferred script loading
Wed, Aug 19 2009 12:18

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.

by luisabreu | 1 comment(s)
Filed under:
JQuery: the $.getJson method
Wed, Aug 19 2009 11:44

In the previous post, we’ve met the $.get and $.post methods. At the time, we’ve seen how we could easily load a JSON payload returned from the server. If you know that you’ll be getting JSON and that the request will be an HTTP GET, then you can use the $.getJson utility function instead of the $.get function.

To illustrate its use, we’re going to reuse the previous example and we’ll only be updating the client code of the page:

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

As you can see, the only difference is that the $.getJSON function receives only three parameters (when compared with the code we had to receive JSON with the $.get function). This isn’t surprising because this method reuses the $.get method internally for doing its work. Here’s its current implementation:

getJSON: function( url, data, callback ) {
    return jQuery.get(url, data, callback, "json");
}

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

by luisabreu | with no comments
Filed under:
JQuery: the $.get and $.post methods
Wed, Aug 19 2009 11:27

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.

by luisabreu | 2 comment(s)
Filed under:
JQuery: getting started with AJAX
Mon, Aug 17 2009 14:34

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.

by luisabreu | 5 comment(s)
Filed under:
Getting ready for ASP.NET 4.0
Fri, Aug 14 2009 15:32

This is a post for my Portuguese readers, so you might not want to waste your time with it if you can’t read portuguese:)

We’ve already got ASP.NET 4.0 beta 1 and I’ve (finally!) started looking at it. I’ve already read the white paper and I’ll be starting to write code on it real soon. As you probably know, I’ve written a couple of books on ASP.NET in the past and it’s time to start updating them.

Unfortunately, the previous releases are already huge. If I add more stuff to it, it will easily go over the 1000 pages mark and that means an increase in the final price of the book. So, I’m thinking that the best option is to work in a  new book which will present only stuff that is being released in the next version of ASP.NET (and probably some stuff which didn’t got mentioned in the previous editions). This means that I can try to achieve the 200-300 pages mark, making the book cheaper.

There are advantages and disadvantages. Besides the price, you’d end up with a book which *only* talks about stuff which isn’t mentioned in the previous editions. This is great if you’ve already bought a previous edition and you intend to buy a book with the new stuff. However, it’s not a good option if you want a complete reference or if you’re starting to look at ASP.NET (in that case, you’d need to buy the 3.5 version + the new book on ASP.NET 4.0).

Currently, I’m inclined to write a shorter book on ASP.NET 4.0 only, but I’d like to think on what you guys think (especially if you intend to buy a Portuguese book on ASP.NET). Thanks for the feedback.

by luisabreu | 1 comment(s)
Filed under:
JQuery: running custom animations
Fri, Aug 14 2009 14:45

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!

by luisabreu | 1 comment(s)
Filed under:
Scopes and contexts in Javascript
Fri, Aug 14 2009 10:16

[Update: thanks to Howard, I’ve updated the typo regarding global functions.]

In a previous post, we’ve talked about scopes. Today we’ll be talking about execution contexts. Every line of JS code you write runs in a certain execution context. If you’re coming to JS from an object oriented language, then you should recognize this concept. In Javascript, you can use the this keyword to access the current execution context. Even though it’s not the most precise way defining it, you can think of this as referencing the object that the code is currently inside of. In practice, this will always return a valid reference.

You probably recall our previous post on scopes. At the time, I’ve said that global scope variables end up being added to the window object. This happens because window represents the default execution context at that scope. We need an example to better understand execution contexts. Take a look at the following snippet:

//current execution context: window
var globalMsg = "Hello";
function sayHi() {
    //new scope: globalMsg is local
    //but this still points to global execution context
    var globalMsg = "Inside hello";
    alert(globalMsg + "-" + this.globalMsg);
}
var obj = {
    globalMsg: "Hallo!",
    sayHi: function() {
        //new scope
        //notice that execution context is the object
        //itself and not window
        alert(this.globalMsg);
    }
};
sayHi();
obj.sayHi();

The previous snippet “mixes” scopes and execution contexts. We start by declaring a global variable and we initialize it to “Hello”. We then create a global function (sayHi). As you know by now, functions introduce new scopes. However, they don’t influence the “current” execution context. This leads to two conclusions:

  • inside the global sayHi, the globalMsg identifier will always reference the “local” variable declared within the function body (because that function introduced a new scope and that means that “local” variables declarations hide global variables);
  • the this reference still references the default context, ie, this still references the global window object (notice that I’m assuming that we’re talking about an HTML page).

If you understand the previous observations, then you won’t be surprise to see that executing the global function sayHi results in showing an alert with the text “Inside Hello-Hello”.

obj is also a “global” variable which has been “added” to the window object. In the previous snippet, obj references an anonymous object which has a property and a function. The most important thing you should take from the code is that when you execute the obj.sayHi() call, you’re introducing a “new” execution context within the obj.sayHi function: in this case, this references the current object instead of the global window object. That’s why that function call will show an alert message with the “Hallo!”.

Javascript allows us to set up the execution context of a function (that is, JS allows us to change the value of the this reference that gets passed to the executing function). To do that, we need to use the apply or the call methods of the function object (the main difference between the two rely on the way we pass parameters to the function – I’ll probably be back to this topic in a future post)

Lets translate our knowledge on execution contexts to write a function that changes the background color of any element. We can reuse our knowledge of execution contexts to do that. Before we write the code, let’s add some HTML to the test page:

<p id="paragraph">This is a paragraph</p>
<div  id="div">This is a div</div>

And now, we can write the global function that changes the background color:

function changeColor(color) {
    this.style.backgroundColor = color;
}

Ok, now we’re only missing one thing: how to influence the execution context of the function and make it reference the adequate element. If we call the function, this will reference the window object (and you’ll end up with an error because window doesn’t have a style property). That’s why we need to use the function’s apply method. Here’s the code for changing the background color of the paragraph to red:

changeColor.apply(
    document.getElementById("paragraph"), //set this reference
    ["red"] //array of parameters 
    );

the first parameter establishes the execution context (ie, the this reference) inside the changeColor function. Notice that apply expects an array with the values that will be passed to the function during the “current” execution.

Understanding execution contexts and how to influence them is really important. This feature is heavily used by all JS platforms. For instance, JQuery uses it a lot in several places so that this points to the “current logic” element. And now you know how you can take advantage of this feature in your code too. Keep tuned for more on Javascript.

by luisabreu | 6 comment(s)
Filed under:
Javascript - understanding scope
Thu, Aug 13 2009 15:32

Since I’ve been digging into JQuery, I though that it would also be a good idea to write a little bit more about Javascript. In my (limited) experience, I’ve met many developers who say that they really know Javascript and that it’s a really simple language. The problem is that they have lots of trouble in understanding and explaining the basic concepts/feature of the language. I’m not really a Javascript expert, but I guess that sharing several of the gotchas I’ve tripped along the way won’t do any harm, right?

And that’s why I’ve decided to start a new series of posts which talks about several important concepts that you might find useful in your day to day use of JS. As you’ve probably guessed from the title, today we’ll be talking about scope.

Scopes might be tricky and, like Eric Lippert said, are sometimes confused with lifetime and declaration space. According to Eric, the scope of an entity is a region of program text in which it’s possible to refer to that entity by its unqualified name. To me, this is really good, clear and concise definition of scope.

In Javascript, scope is “defined” through functions (and not by blocks, like in C). Btw, variables defined outside a function are said to be defined on the global scope. Let’s start with a really simple example. What do you think will happen when you run the following code:

var globalMsg = "hello world!";
if (true) {
    var globalMsg = "yes, I'm updating the global";
    //is globalMsg redefined here? (1)
}
//and here? (2)

As I’ve said before, blocks don’t introduce scopes in Javascript. In practice, that means that the var declaration inside a block isn’t really introducing a new variable because there’s already a variable with that name in the current scope. Now, what would happened if we changed our code like this:

var globalMsg = "hello world!";
function sayHi() {
    if (true) {
        var globalMsg = "yes, I'm updating the global";
        //what's the value of globalMsg? (1)
    }
}
sayHi(); //and here? (2)

Since our if block is wrapped by a function and since function definitions do create a new scope in Javascript, then the globalMsg declared inside the block will indeed create a new variable which hides the global variable.  Notice that the use of the var keyword important! If we’d missed it, then we would end up defining a variable in the current global scope:

<script type="text/javascript">
function sayHi() {
    if (true) {
        globalMsg = "yes, I'm updating the global";
        //what's the value of globalMsg? (1)        
    }
}
sayHi();
//and here? (2)

If you run the previous snippet, you’ll notice that globalMsg is being defined in the global scope and that you can access it on line (2) (notice that its value was the one we’ve set up inside the function). If you run the previous code in a HTML page, then you’ve probably noticed a side effect of the global scope: global scope definitions are instantiated as fields of the window object (at least, on most modern browsers). If you don’t believe me, then run the next snippet:

var globalMsg = "Hello";
alert(window.globalMsg);

And I guess this covers the basic features of the language. In the next post of the series, we’ll wrap our discussion of scopes and we’ll talk about execution contexts. Keep tuned for more on Javascript.

by luisabreu | 6 comment(s)
Filed under:
JQuery: sliding
Thu, Aug 13 2009 9:59

In this post, we’ll take a look at the JQuery methods used for sliding animations. We’ve got 3 methods for executing sliding animations:

  • slideDown: shows all the hidden elements contained in the wrapped set of the JQuery object.
  • slideUp: hides all visible elements defined in the wrapped set.
  • slideToggle: toggles the elements between hidden and visible.

The methods expect the traditional speed (you can pass an integer or one of the “magic” strings we’ve met in the past) and (optional) callback function parameters. If you didn’t notice, these methods are really similar to the show/hide/toggle methods we’ve met in a previous post.

The slide methods affect several css properties. Besides changing the height, the latest version of JQuery (1.3 when I wrote this) will also animate the vertical padding and vertical margins of the elements in order to ensure a smoother  transition between visible and hidden (notice that element will also be removed from the display at the end of the animation). Here’s a small sample that shows how easy it is to add sliding to an element:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
    <style type="text/css">
        p{ 
            border: solid 1px red;
            height: 100px;
            margin:10px;
        }           
    </style>
    <script src="jquery-1.3.2.js" type="text/javascript"></script>
</head>
<body>
<p>This is a paragraph</p>
<p>This is a paragraph</p>
<p>This is a paragraph</p>
<input type="button" value="slide down/up" />
<script type="text/javascript">
    $(function() {
        $("input").click(
            function() { $("p").slideToggle(500); });
    });    
</script>
</body>
</html>

If you run the previous snippet, you’ll notice that clicking the button ends up sliding the p elements of the page (I’ve added a default height to all the paragraphs to make the transition more visible). If you’re interested in hiding the elements at page load, then you can simply set their CSS display property to none.

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

by luisabreu | 1 comment(s)
Filed under:
JQuery: fading elements
Wed, Aug 12 2009 11:29

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.

by luisabreu | 1 comment(s)
Filed under:
JQuery: getting started with effects
Tue, Aug 11 2009 11:00

JQuery offers support for basic effects, like showing, hiding, fading and sliding. Besides that, it also facilitates the construction of new animations by introducing some custom methods which you can reuse to produce some basic animations. Today we’ll be concentrating on two methods: show and hide. Both these methods have two “overloads”: one takes no parameters and the other expects a timeout and an optional callback method (notice that Javascript doesn’t really support the OO overload concept since there’s only a single method which runs some tests on the passed arguments).

Let’s start by looking at what happens when you call the methods and don’t pass any parameters. Calling hide is the same as setting the style’s display to none. Calling show results in setting the style’s display to the default element's style or in recovering the previous default style (more about this in the next paragraphs). Take a look at the following snippet:

<span class="test">span 1</span>
<span>Another span</span>
<div class="test" id="div2">div 2</div> <input type="button" id="show" value="show" /> <script type="text/javascript"> $(function() { $("#show").toggle( function(){$(".test").hide();}, function(){$(".test").show();} ); }); </script>

If you run the previous snippet, you’ll notice that the hide method effectively hides all the elements. Calling show ends up setting the style’s display property to the default value of each of the wrapped set elements. As I said before, if you had an initial value applied to the display property when you called hide, that value will be preserved and remembered for a future show call. When that happens, that initial style will be applied again. Take a look at the next snippet:

<span class="test" style="display: block">span 1</span>
<span>Another span</span>
<div class="test" id="div2">div 2</div>
<input type="button" id="show" value="show" />
<script type="text/javascript">
    $(function() {
        $("#show").toggle(
                        function() { $(".test").show(); },
                        function() { $(".test").hide(); } );
    });    
</script>

As you can see, we’re using our old toggle event function helper to alternate between functions for the click event. If you run this sample, you’ll notice that invoking hide still removes the wrapped set elements from the view (by setting the display property to none) and that when you call show, the span retains its initial display value.

If you change the order of the calls (ie, if you change the order of the functions in the toggle method), you’ll end up loosing the initial display of the span. If you don’t believe me, then replace the previous script with the next:

<script type="text/javascript">
    $(function() {
        $("#show").toggle(
                        function() { $(".test").show(); },
                        function() { $(".test").hide(); } );
    });    
</script>

And now hiding/showing will always result in getting the default span’s display.

You’re probably wondering what’s going on with hide and show. It’s not that complicated…in fact, it’s really simple. When you call hide, you end up saving the current display value to a named data slot that is added to each of the wrapped set elements (by using the internal jQuery.data function – we’ll come back to this method in future posts).

Whenever the show method is invoked, it starts by trying to get the previously stored display value from that named slot. If it finds one, it will apply it to the style’s display property. If it can’t find it, then it will simply create a new element of that type (ie, with the same tag name) so that it can get its default style’s display value (notice that this means that you end up adding/removing a new element to the body element to get that information). This is the default behavior you get when you don’t pass any parameters to these methods.

If you decide to use the other “overloads” of these methods, you’ll really be adding animation effects. As I’ve said at the beginning of the post, the second “overload” of this method expects:

  • a mandatory speed parameter, which defines the total time that will be taken to show/hide the element in milliseconds;
  • an optional callback function which will be called when the animation ends.

Lets update the previous snippet so that it uses these overloads:

<span class="test">span 1</span>
<span>Another span</span>
<div class="test" id="div2">div 2</div>
<input type="button" id="show" value="show" />
<script type="text/javascript">
    $(function() {
        $("#show").toggle(
                        function() { $(".test").hide(500); },
                        function() { $(".test").show(500); } );
    });    
</script>

Running the previous code should result in an animation that changes the width, height, opacity, padding, margins and display of the element. This leads to a more graceful smoothing effect. Instead of specifying the speed in milliseconds, you can also use one of three predefined strings: slow, normal or fast.

If you want, you can also pass a callback function to both the hide and show methods. The function doesn’t receive any parameters and you can access the “animated” DOM element by using the this reference. You should also keep in mind that most of the previous references made about the show and hide methods that take no parameters still hold: the only exception is that calling show on a visible element with a predefined display value doesn’t override that value with the elements default style’s display value.

I know that I’ve said this post would only be about show and hide, but I guess there’s still time (and space) for introducing the toggle method. Take a look at the next snippet:

<span class="test" style="display: block">span 1</span>
<span>Another span</span>
<div class="test" id="div2">div 2</div>
<input type="button" id="show" value="show" />
<script type="text/javascript">
    $(function() {
        $("#show").click(function() { $(".test").toggle(); });
    });    
</script>

The previous snippet produces the same effect as our initial snippet. If you want, you can also pass values for speed and for a callback method:

<script type="text/javascript">
    $(function() {
        $("#show").click(function() { $(".test").toggle("300"); });
    });    
</script>

As you can see, toggle can be used as click helper or as an animation helper that hides and then shows the wrapped set elements. The passed arguments decide which version will be used (notice that passing two functions results in getting the event method).

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

by luisabreu | with no comments
Filed under:
JQuery: utility functions X – extending objects
Mon, Aug 10 2009 15:06

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.

by luisabreu | 1 comment(s)
Filed under:
JQuery: utility functions IX – transforming arrays
Mon, Aug 10 2009 14:51

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.

by luisabreu | 3 comment(s)
Filed under:
JQuery: utility functions VIII – creating arrays from other objects
Mon, Aug 10 2009 14:30

The utility function makeArray is a helper which is used internally by JQuery to transform collections of nodes into arrays. Even though this function is “public”, you’re not expected to use it much. Here’s its current internal implementation:

makeArray: function( array ) {
    var ret = [];
    if( array != null ){
        var i = array.length;
        // The window, strings (and functions) also have 'length'
        if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
            ret[0] = array;
        else
            while( i )
                ret[--i] = array[i ];
    }
    return ret;
}

As you can see, the code function starts by getting the length and checking the current type of the array parameter. If you’re passing a function (isFunction helper), a string, a window object or if the length doesn’t exist, you’ll end getting an array with a single element.

In the remaining scenarios, you’ll go through all the elements in the array and you’ll copy them to an array. Notice that in Javascript it’s possible to have an object which isn’t an array but that does behave like one. Let me present a simple example of this:

var arr = (function() {
return $.makeArray(arguments); })(1, 2, 3);

So, what I’m doing here? Simple: I’m creating and executing an anonymous function and saving the returned result on the arr variable. The anonymous function will pass arguments to the makeArray function and you’ll get back a “real” array. If you debug the previous code, you’ll see that arguments behaves like an array but it’s not an array:

debugarguments

As you can see, the arguments object has indexes and you even have a length property. However, things stop working if you try to use a method that exists on arrays. For instance, if you use the push method, you’ll end up getting an exception.

The node lists which you get back from the methods like getElementsByTagName behave like arrays but aren’t really arrays. In those cases, you can easily get an array by using this utility function. And that’s all for this post. Keep tuned for more on JQuery.

by luisabreu | 3 comment(s)
Filed under:
JQuery: utility functions VII – concatenating arrays
Mon, Aug 10 2009 11:23

In this post we’re going to take a look at the merge utility function. This function expects two arrays that will be merged. The method returns a reference to the first array augmented with the elements contained on the second (which remains unchanged). Here’s a small snippet that shows how to use this function:

var arr = [0, 1, 2];
var anotherArr = [-1, -2, -3];
var merged = $.merge(arr, anotherArr);

The important thing here is that you shouldn’t forget that merged points to arr and that arr now has the items contained by anotherArr. Notice also that this function doesn’t remove duplicates. If you need that you’ll need to use the $.unique method (though it only works with DOM nodes). Keep tuned for more on JQuery.

by luisabreu | 1 comment(s)
Filed under:
JQuery: utility functions VI – checking if an item is in an array
Mon, Aug 10 2009 10:34

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.

by luisabreu | 1 comment(s)
Filed under:
JQuery: utility functions V – finding elements in an array
Mon, Aug 10 2009 10:15

Today we’re going to talk about the grep utility function. You can use the grep function to get the elements of the array that match a specific custom filter. The grep function expects three parameters. The first two are mandatory: an array that is going to be enumerated and a callback function which is responsible for checking which items of the array comply with the custom filter (the function will be called for each item of the array and should return a boolean which indicates if the current item is compatible with the desired filter). Finally, you can also pass grep a third parameter for inverting the result of the filtering (more on this in the next paragraphs).

Lets start with a basic example: get all the positive numbers from an array. Here’s some simple code that performs this:

var arr = [0, -2, 4, 6, - 9];
var positives = $.grep(arr,
function(item) {
    return item > 0; 
});
alert(positives);

The function receives two parameters: a reference to the current value and the index of that value in the array. Since I was only interested in the value, I opted for declaring only one parameter in the anonymous function that filters the arr array.

As I mentioned before, the grep function has a third optional parameter: it’s called invert and you’re supposed to pass a boolean (that is, when you use it). If you pass true, you’ll be inverting your filter, ie, you’ll get the items which don’t comply to the filter you’ve defined in the anonymous function. So, if we wanted to get all the negative values, we could rewrite the anonymous function’s filter or we could pass true to the third parameter of grep, as you can see in the next snippet:

var arr = [0, -2, 4, 6, - 9];
var positives = $.grep(arr,
function(item) {
    return item > 0; 
},
true);
alert(positives);
And I guess there’s not much to say about grep. Keep tuned for more on JQuery.
More Posts « Previous page - Next page »

Search

This Blog

Tags

Community

Archives

Syndication

Email Notifications

News




  • View Luis Abreu's profile on LinkedIn


    Follow me at Twitter

    My books

    Silverlight 4.0: Curso Completo

    ASP.NET 4.0: Curso Completo

    Portuguese LINQ book cover

    Portuguese ASP.NET 3.5 book cover

    Portuguese ASP.NET AJAX book cover

    Portuguese ASP.NET AJAX book cover