Friday, August 7, 2009

How to make a perfect Web 2.0 close button using Photoshop CS4

Background

In this tutorial I will explain how to create a Web 2.0 style close button with a perfect cross on it. We shall be creating this button using Adobe Photoshop CS4. Before we get started, this is how the end product will look like:

Note, all the transient images of sample are displayed in 300% zoom mode.

Step 1

The first step in creating the button is to create the cross image. For this purpose we shall create a new 128 pixel by 128 pixel Photoshop document having a resolution of 72 pixels per inch. You would ask why did we create 128 pixel by 128 pixel document? The answer is twofold. First, 128 x 128 pixel image is a standard icon size in many application (so is 16 x 16, 24 x 24, 48 x 48, 80 x 80, 256 x 256) hence by choosing these dimensions you would get the icon in the standard size. Secondly, in Photoshop the grid size is 8 pixels side square. Hence if you are indulging in creating a high precision image using pens, it is easier to snap points to grid.

 

Step 2

A cross is really a plus sign rotated by an angle of 45 degrees. Hence we shall first create a plus sign. Rename the background layer as Vertical_Bar as this is the layer we shall be creating our vertical bar on. Select the pen tool and zoom the image to 300% for high precision path drawing. Now click the first pen path vertex one row down from top and at the end of sixth square from left. Click to create second vertex at the horizontal distance of 4 squares from the first vertex. Now click on third vertex vertically below the second one in the second last row. Lastly click on the first vertex to obtain a closed path in the shape of vertical bar.

As you can see the vertical path is symmetrically placed in the document. Now choose Layer->Vector Mask-> Current Path. This will create a vector path corresponding to the path we have drawn. Vector paths are important since in Photoshop all image manipulation by default are pixel based. If vector paths / masks are used then image can be enlarged, shrink, rotated without any loss of quality since in this case vector components of path are manipulated and no pixel interpolation / extrapolation is done. Now select a foreground color (I chose #e5dcdc) and selecting the layer choose Edit->Fill to fill the layer with foreground color. You will see since we have applied a vector mask, only the portion of image inside the closed path will be filled with the color leaving outside area transparent as before.

Create a new layer and name it Horizontal Path. Repeat the above creating a horizontal bar this time and proceed to create vector mask and fill the masked layer with the same color. Now you should obtain a plus sign.

Step 3

Click on Vertical_Bar layer and go to Paths tab. Click on the vertical path. This should draw a solid border around the vertical path. Go back and select Vertical_Bar layer mask. Now press Ctrl + T to enter the transformation mode. In the top transformation toolbar, enter 45 in the angle textbox to rotate the layer mask by 45 degrees. Now press enter key to exit the transformation mode. Repeat the same steps for Horizontal_Bar layer.

We are done with making a perfect cross icon and ready to proceed to create the button on which this icon will be overlaid. This cross can be reused in other UI elements as well so we will save this in cross.psd file for later reuse.

Step 4

To create a fancy Web 2.0 style background we shall reuse some Photoshop styles and gradients that can help us quickly set the effects we want. I recommend downloading these styles from http://myphotoshopbrushes.com/styles_and_gradients. I personally downloaded 42 Button Layer Styles and Ultimate Web 2.0 Styles from the parent link. Once you download the files, open the zip file and double click on .asl file. This will register the styles automatically with Photoshop.

Step 5

Now create a 144 pixel by 144 pixel image in Photoshop. Name the layer button. Click and hold mouse on rectangle tool in Photoshop toolbox. This will pop down all the shapes from the toolbox. Select rounded rectangle from the dropdown. Ensure that path option is selected on the top toolbox. This will ensure that any shape that is drawn is considered a closed path. Select the radius to be 10px.

Now draw a rounded rectangle having one row border outside the rectangle. Again choose Layer->Vector Mask-> Current Path to create a vector mask on the layer. Now select the selection tool and select any style from the styles palette with layer selected(I selected Photobucket Join style for background).

Step 6

Now goto cross.psd and press Ctrl + D to select the entire image. Next, choose Edit->Copy Merged to copy the merged layer. Go back to the button document now and press Ctrl + V to paste the cross on top of the button layer. Now select this new layer and name it cross. With cross layer selected, select any style from the style palette to fill the cross with desired gradient (I selected Flixster Search style). There you go, now you have a trendy and crispy Web 2.0 style cross button.

Monday, July 20, 2009

Simple & Practical introduction to Asynchronous JavaScript And XML (AJAX)

Background

Asynchronous JavaScript and XML or AJAX has been the revolutionary technology that enabled rich user experience over the web, much like desktop rich user experience. In this series, I will describe my journey of learning AJAX and some simple steps that will get you started with this simple but powerful technology.

Introduction

AJAX enables web developers dynamically update a web page via background asynchronous posts to the server. Hence it removes the necessity of sending entire page back to the server and cause  global refresh in the browser. This results in following major benefits:

  1. Rich user experience – a web user doesn’t have to wait until the entire page is loaded. Nor is he / she is distracted by visual information loss during the page reloads. AJAX also can be used to display progress information while a sub-portion of the page is being updated / loaded from the server.
  2. Server scalability – Since only minimal information is exchanged between the client and the server, hence server can serve more clients in turn with the same amount of resources (memory, CPU). This helps in increasing server scalability.
  3. Client efficiency – The client browser only needs to update a sub-portion of already loaded web page as opposed to parsing and displaying the entire page all over again.

Figure 1 – Classic Web Application Model

Figure 2 – AJAX Web Application Model

The solid lines depict synchronous operations whereas the gray lines depict asynchronous operations.

Building Blocks of AJAX

AJAX is not a technology by itself. It is an outcome of several collaborating technologies that fit their respective roles in the overall end to end asynchronous HTTP request / response process. The major building blocks involved in AJAX web application model are as follows:

  • Standards based presentation using XHTML and CSS.
  • DHTML – Browser capabilities to manipulate XML Document Object Model (DOM) for the loaded web page.
  • JavaScript – Base language technology for performing all client side activities during AJAX operations. Client browser must have support for JavaScript in order to support AJAX operations. Many vendors have to support both AJAX style web pages (for desktop browsers) as well as traditional post-back web pages (for mobile device browsers) to capture the entire spectrum of users.
  • XMLHttpRequest object – A browser must support XMLHttpRequest JavaScript object for initiating asynchronous web requests. Different browsers have different ways to retrieve this object. There are many documented shims available that explain how to retrieve this object. Here is an example from wikipedia:

    // Provide the XMLHttpRequest class for IE 5.x-6.x:
    // Other browsers (including IE 7.x-8.x) ignore this
    // when XMLHttpRequest is predefined
    if (typeof(XMLHttpRequest) == "undefined") {
      XMLHttpRequest = function()   {
        try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
          catch(e) {}
        try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
          catch(e) {}
        try { return new ActiveXObject("Msxml2.XMLHTTP"); }
          catch(e) {}
        try { return new ActiveXObject("Microsoft.XMLHTTP"); }
          catch(e) {}
        throw new Error("This browser does not support XMLHttpRequest.");
      };
    }

This example  shows how to add a shim type of the same name XMLHttpRequest if the browser doesn’t support it out of the box. For a complete reference on XMLHttpRequest JavaScript class, refer to Mozilla Developer Center page.

I highly recommend reading a book that explains the above technologies in depth to get your basics right. I personally read Beginning Ajax with ASP.NET and found it a very good start for beginners. However later chapters in the book are outdated as technologies that they mention especially Microsoft Atlas have considerably changed since the book was released.

First AJAX Experience

In the beginning of this blog I promised you to present AJAX in a very approachable style. For years I had ignored learning this technology as I considered it to be very non-standard and hacky then. Now I differ in my opinion owing to the fact that there are many technologies in the AJAX web model that have been recognized as industry standards and are now W3C compliant. Anyways let’s now see things in action ! Create an ASP.NET web application in Visual Studio where you will test your first AJAX code. Then create an XML file note.xml in the project and overwrite its content with the following:

<?xml version="1.0" encoding="iso-8859-1"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

Next create a html document in the project ajax.htm with the following content:

<html>
<head><title>First AJAX Example</title></head>
<script type="text/javascript"> 
        var request;
        var READYSTATE_COMPLETE = 4;   // Indicates completion state of XMLHttpRequest object

           // Provide the XMLHttpRequest class for IE 5.x-6.x:
        // Other browsers (including IE 7.x-8.x) ignore this
       // when XMLHttpRequest is predefined
        if (typeof(XMLHttpRequest) == "undefined") {
          XMLHttpRequest = function()   {
          try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
          catch(e) {}
          try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
          catch(e) {}
          try { return new ActiveXObject("Msxml2.XMLHTTP"); }
          catch(e) {}
          try { return new ActiveXObject("Microsoft.XMLHTTP"); }
          catch(e) {}
          throw new Error("This browser does not support XMLHttpRequest.");
        }; 
    } 

    function ReadXmlFile() {
        // Create XMLHttpRequest object
        request = new XMLHttpRequest();

        // Open an XML file
        request.open('GET', 'note.xml', true);

        // Attach completion handler to the request
        request.onreadystatechange = DisplayXmlFile;

        // Send async request to the server with null context
        request.send(null);
    }

    function DisplayXmlFile() {
        // If request is complete, show the content of response in the xmlSpan span
        if (request.readyState == READYSTATE_COMPLETE) {
            xmlSpan.innerText = request.responseText;
        }
    }
</script>
<body>
    <span id="xmlSpan"></span><input type="button" onclick="ReadXmlFile();" value="ReadXml" />
</body>
</html>

Finally fire the app in the browser and open ajax.htm. You will see if you hit the ReadXml button, the xmlSpan span gets populated with the content of note.xml without refreshing the page as shown in Figure 3 below.

Figure 3 – Running the first AJAX example

Security Note

In order to ensure online security and prevent cross scripting attacks, the browsers limit the XMLHttpRequest object to only request resources from the same domain as the domain of the web application. You can verify this in the above example. Instead of requesting note.xml, try requesting http://www.w3schools.com/XML/note.xml which has the same content. Running the application will not allow the xml file to be fetched. Replace it again with note.xml and it will work again.

AJAX Frameworks

In recent years, the use of AJAX in major web portals have revolutionized online user experience. Although Microsoft was the first company to make use of AJAX, it was Google which truly captured the power of this technology and set a new standard for online user experience. Several frameworks have been built to increase developer productivity while developing AJAX based web applications. These frameworks can be categorized into following major categories:

  • Client side frameworks – JavaScript libraries/frameworks that help developers reuse/leverage client side JavaScript code.
  • Server side frameworks – Server side code generators/injectors combined with capabilities to extend client side AJAX JavaScript code to achieve extensibility and reusability in AJAX web application development.

Each of the following categories have their own benefits and drawbacks. The decision to pick one over the other depends in the nature of application being developed and platforms being used to develop those applications. A lot of time developers also pick a combination of tools belonging to different categories and integrate them together to achieve the desired end product. I will walk you through an example of each of the following categories in the upcoming sections.

Client Side Frameworks

Many efforts have been made to enhance JavaScript to support AJAX via reusable libraries. Quite possibly the biggest effort is the conception of jQuery – a lightweight library that emphasizes interaction between JavaScript and HTML.  Microsoft has already adopted this framework which is now shipping with ASP.NET MVC Framework and in the near future will be a part of upcoming Visual Studio 2010 release. Let us rewrite our previous example using jQuery. Again follow the previous example as is except this time your html page should have the following content:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>AJAX with jQuery</title>
</head>
<script src="Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function() {

        $("#ReadButton").click(function() {
            $.ajax({
                type: "GET",
                url: "note.xml",
                success: function(msg) {
                    $("#xmlSpan").attr("innerText", msg.xml);
                }
            });
        });
    });   
</script>
<body>
    <span id="xmlSpan"></span><input type="button" id="ReadButton" value="ReadXml" />
</body>
</html>

The script to fetch note.xml this time is so much more concise! Also note that we didn’t need to do anything funky on the server side to make it work. We didn’t had to create XMLHttpRequest object and check for browser type while doing so. Also we didn’t had to declare constants to check states for XMLHttpRequest object. Just a precise subscription to success event got our callback going!

Ok you must be wondering well, the above works well but what if HTTP POST is required instead of a GET and how does one go about executing business logic on the backend while making asynchronous HTTP POST requests. Well the answer is simple. We can use POST version of jQuery AJAX call to achieve the same. We shall see this approach in the scenario below.

Consider that you want to call a method GetPerson on your backend ASP.NET page that gives you a custom Person object. Let’s assume that this Person object is to be processed on the client and displayed to the user. Let’s see how we can go about doing it.

In order to achieve the above scenario we must understand how serialization works between a backend .NET managed object and JavaScript objects. Any object in JavaScript can be serialized to JSON (JavaScript Object Notation) format. As well as any JSON object can be deserialized into a JavaScript object. JSON is really a format for structured data interchange between systems. The BNF for object denotation in JSON is as follows:

JSON Notation := { } | {KeyValuePair}
KeyValuePair   := Key : Value | KeyValuePair, Key : Value
Key                       := String
Value                   := String | Number | JSON Notation | Array | true | false | null
Array                  := [ ] | [Value] | [Value, Value]

Hence if you have a person object storing FirstName and LastName then following can be a JSON representation of a Person instance:
{PersonInstance: {FirstName:John, LastName:Rambo}}
and an array of Person objects can be represented as :
{PersonList: [{FirstName:John, LastName:Rambo}, {FirstName:Austin, LastName:Powers}]}

The format of JSON closely matches how JavaScript interprets its objects, i.e. in the form of nested key value pairs. Yes, everything in JavaScript, properties, methods, events are just key value pairs of some sort and hence JavaScript objects are nothing but nested dictionaries! If you follow the persistence format of many other vendors this is usually a strikingly common way of representing objects (Apple also uses a similar plist format to store property lists in MacOS and also in iTunes ! For more information about plist, check out its wikipedia page).

Anyhow now back to our GetPerson example. We will create a simple ASP.NET page with the following code behind:

using System;
using System.Web.Services;

[Serializable]
public class Person
{
    public string FirstName {get;set;}
    public string LastName {get;set;}
}

public partial class Person_Page : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    { 
    }

    [WebMethod]
    public static Person GetPerson(Person person)
    {
        return new Person { FirstName = person.FirstName, LastName = person.LastName };
    }
}

There is one static web method called GetPerson that accepts a parameter of type Person. Person really contains the first name and the last name of a person. GetPerson then simply returns a new Person object with the same first and last name. One important thing to note is that Person object is marked with a Serializable attribute. In CLR if an object is marked with a Serializable attribute then it can be serialized into any given format / and or built from any format back as an object. Also note the public static visibility type and WebMethod attribute on GetPerson method. This is essential to expose a method to be called by client web requests. We shall see how we can call this method from the client code below.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Person_Page.aspx.cs" Inherits="Person_Page" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>jQuery POST Example</title>
</head>
<script src="Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<script type="text/javascript">

    $(document).ready(function() {
        $("#GetPerson").click(function() {

            var firstname = $("#txtFirstName").val();
            var lastname = $("#txtLastName").val();
            content = "{'person':{'FirstName':'" + firstname + "', 'LastName':'" + lastname + "'}}";

            $.ajax({
                type: "POST",
                url: "Person_Page.aspx/GetPerson",
                data: content,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function(msg) {
                    var fullName = msg.d.LastName + ", " + msg.d.FirstName;
                    $("#lblFullName").text(fullName);
                }
            });
        });
    });   
</script>
<body>
    <form id="form1" runat="server">
    <div>
    First Name: <input type="text" id="txtFirstName" />
    Last Name: <input type="text" id="txtLastName" />
    <br />
    <input type="button" id="GetPerson" value="GetPerson"></input>
    <span id = "lblFullName"></span>
    </div>
    </form>
</body>
</html>

We have two text fields here txtFirstName and txtLastName that capture first and the last name of the person respectively. Then we have a GetPerson button that makes the AJAX call to the code behind of the page and tries to call a web method GetPerson and passes in the constructed JSON from txtFirstName and txtLastName fields via content string variable. Once the response is received back from the server, the text of the span lblFullName is updated to show the full name in the format LastName, FirstName. Following is the screenshot while running the above code:

Figure 4 – jQuery POST Example in action

As can be seen when the CLR receives the POST requests, it queries the HTTP ContentType field value. Since it is specified as application / json, hence it deserializes the person object from JSON to actual Person instance and also serializes the resulting Person object from GetPerson back to JSON. Also notice the JSON string construction from client script in content string object. We specify the key of the object to be ‘person’ which is the same name as the formal parameter name of Person object in GetPerson web method. This allows for binding of parameters during the call so value can be passed correctly to the web method.

Server Side Frameworks

Server side frameworks dynamically generate and inject AJAX JavaScript snippets into server processed forms, so developers are not bothered writing JavaScript every time they desire AJAX style functionality in their web applications. We already have seen above that JSON and JavaScript correspond quite well to each other and one can be projected to another and vice versa. Armed with this fact, server side frameworks generate proxy JavaScript objects on the fly that correspond with backend data structures. They also inject code that call backend methods asynchronously and pass proxies to and from client browser.

There are many popular sever side AJAX frameworks such as Microsoft ASP.NET AJAX, AjaxPro, ComfortASP.NET and MagicAjax.NET. In addition, Microsoft has started a community effort to build more server side controls to bring web experience closer to desktop experience via a community project called ASP.NET AJAX Control Toolkit (although last time I checked there were quite a few bugs in this toolkit and some controls such as AutoComplete were completely broken). I must also mention that Microsoft ASP.NET AJAX server framework also contain a client side JavaScript library called Microsoft AJAX library (talk about confusing names) that closely mimics much of OO features present in managed languages such as inheritance, interfaces etc. Microsoft AJAX library can be downloaded from http://www.asp.net/ajax/downloads/.

However one must realize serious implications of using various server side frameworks in code. Most of the time these limitations are not very well documented. One common limitation is the use of conflicting HTTP handlers and HTTP modules in ASP.NET projects. HTTP modules and handlers are HTTP request handlers that get executed way before ASP.NET gets to the requests in the application pipeline. Server side frameworks usually utilize these components to inject code into HTML response via JavaScript tags. However if there are more than one server frameworks used (maybe for different purposes than AJAX) than they might conflict and suppress functionality offered by other frameworks by ‘stealing’ the HTTP requests first.

Another major limitation of server side frameworks is the way they perform asynchronous HTTP requests. ASP.NET AJAX framework for example relies heavily on ASP.NET ViewState object. Hence it is impossible to issue requests from web user controls (commonly known as partial views or *.ascx) using this framework. It is also not compatible with ASP.NET MVC framework. Hence it is important to perform background study of a framework and ensure that it is compatible with existing frameworks being used in your web applications.

Let us see an example of using server side framework. For the purpose of this example I will use AjaxPro framework. You can download AjaxPro framework for free from its website. To use this framework, create an ASP.NET web application and simply reference the downloaded assembly (AjaxPro.dll or AjaxPro2.dll depending on the version you download from the website) from your project.

Next add the following lines in web.config (note: if you already have a httpHandlers section just add the ‘add’ tag from below)

<httpHandlers>
      <add verb="POST,GET" path="ajaxpro/*.ashx" type="AjaxPro.AjaxHandlerFactory,AjaxPro.2"/>
</httpHandlers>

The code above implies that whatever request POST/GET is received for a resource with extension ashx within the ajaxpro folder must be forwarded to AjaxPro.AjaxHandlerFactory http handler defined in AjaxPro.2.dll assembly.

Next, we will add a new ASP.NET page named AjaxPro_Page to the project. The first thing we need to do in order to hook up this page to AjaxPro http handler is to register it with AjaxPro. We do this via AjaxPro.Utility.RegisterTypeForAjax call from within page’s Page_Load method as follows:

protected void Page_Load(object sender, EventArgs e)
{
    AjaxPro.Utility.RegisterTypeForAjax(typeof(AjaxPro_Page));
}

The next step is to define method(s) on this page that will be called from within this page by the client code. For the purpose of this example we shall define a GetTime method that will return server time to the client. It is important to mark this method with AjaxMethod attribute so a “proxy” code for this method can be generated by the AjaxPro framework. Following is the definition of GetTime method:

[AjaxMethod]
public DateTime GetTime()
{
    return DateTime.Now;
}

At this time the server part of the code is complete. The complete class should look like as follows:

using System;
using AjaxPro;

public partial class AjaxPro_Page : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        AjaxPro.Utility.RegisterTypeForAjax(typeof(AjaxPro_Page));
    }
    [AjaxMethod]
    public DateTime GetTime()
    {
        return DateTime.Now;
    }
}

Let us run this page in browser and see what gets generated on the client side. Run this page in browser and view the source for this page. You will find following three script tags that were injected by AjaxPro.AjaxHandlerFactory http handler that we registered in web.config before:

<script type="text/javascript" src="/blogtest/ajaxpro/prototype.ashx"></script>
<script type="text/javascript" src="/blogtest/ajaxpro/core.ashx"></script>
<script type="text/javascript" src="/blogtest/ajaxpro/converter.ashx"></script>
<script type="text/javascript" src="/blogtest/ajaxpro/AjaxPro_Page,App_Web_hghu6cj1.ashx"></script>

The first script is basically the code that enables OO concepts such as inheritance and virtual functions used within the code generated by AjaxPro in later stages. Hence it defines the base prototype from which all the AjaxPro client code inherits from. The second script generates core related to IFrame, request queues and general request / response logic. Third script is basically the JSON serializer / deserializer for complex .NET types such as System.Collections.Specialized.NameValueCollection, System.Data.DataSet, System.Data.DataTableDataTable, ProfileBaseConverter and IDictionaryConverter. This enables you to use this complex data types as return types for your .NET methods and use them seamlessly from AjaxPro generated proxy code.

The last script corresponds to the proxy generated for your code behind. Note that the exact ending of the App_Web_*.ashx handler is random and may not end with hghu6cj1 as in my case. If you navigate to that url and view the source for the code, you will find something similar to the code below:

AjaxPro_Page_class = function() {};
Object.extend(AjaxPro_Page_class.prototype, Object.extend(new AjaxPro.AjaxClass(), {
    GetTime: function() {
        return this.invoke("GetTime", {}, this.GetTime.getArguments().slice(0));
    },
    url: '/blogtest/ajaxpro/AjaxPro_Page,App_Web_hghu6cj1.ashx'
}));
AjaxPro_Page = new AjaxPro_Page_class();

Here we can clearly see that AjaxPro generates a JavaScript class named AjaxPro_Page_class and defines invoke code for GetTime method. What it does exactly is define a class AjaxPro_Page_class as an empty class and then add GetTime method to its prototype. This way any instance of this class or its subclass will have access to the GetTime method via prototype chaining. Finally it declares an instance of AjaxPro_Page_class named AjaxPro_Page (same name as our server code behind class) so it can be used from our scripts to invoke methods on the code behind.

Now we need to hook up the client code to call this GetTime method from AjaxPro_Page. Well its simple. Just replace the code in your AjaxPro_Page.aspx with the following:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="AjaxPro_Page.aspx.cs" Inherits="AjaxPro_Page" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>AjaxPro Example</title>
</head>
<script src="Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $("#cmdServerTime").click(function() {
            AjaxPro_Page.GetTime(function(result) {
                $("#lblServerTime").text(result.value.toString());
            });
        });
    });
</script>
<body>
    <form id="form1" runat="server">
    <div>
        Server Time: <span id="lblServerTime"></span>
        <input type="button" id="cmdServerTime" value="GetServerTime" />
    </div>
    </form>
</body>
</html>

This code basically declares a span with id lblServerTime and a button with id cmdServerTime. In the page load jQuery, it hooks up the click event of cmdServerTime to call AjaxPro_Page.GetTime method, which in turn is hooked up to the anonymous method that replaces the text for the span with the server returned time value from GetTime method. Run it and you shall see the results similar to below screenshot:

Figure 5 – AjaxPro example in action

Handling conflicting http handlers

As I mentioned before sometimes multiple http handlers on server may conflict and your application may not work as desired. Hence proper resolution may be required to enable all the handlers perform in harmony. As an example, if you try to use AjaxPro framework with ASP.NET MVC application your application will not work out of the box since MVC framework has a powerful url routing engine that captures all the incoming requests (note that in MVC framework, views are also non-existing resources) including all the resource requests for the non-existing resources the ajaxpro/ non existing folder (refer to web.config above). Hence we need an exclusion for this rule in the ASP.NET MVC url routing engine. The following code in the Global.asax.cs will achieve this:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("ajaxpro/{resource}.ashx");
    :
}

Debugging support

As with any application development, debugging support is a must to trace execution points within the code. I test and debug my web applications both in Internet Explorer as well as in Mozilla Firefox. To enable debugging support in IE, you can follow the instructions in Jonathan Boutelle’s blog. Good thing about IE debugging (I personally use Firefox for all other purposes) is that one can leverage Visual Studio debugger rather than downloading and learning another debugger to debug JavaScript. For Mozilla Firefox, I use Venkman JavaScript Debugger and strongly recommend it as well.

Conclusion

I hope that I was able to provide a good insight into AJAX web development from a beginner’s point of view. There are many tools available which are not covered here but the most important thing is to play around with them and find the best combination that works for your needs. And of course if you learn some, share some ! Happy coding !

Sunday, May 31, 2009

WPF Tips And Facts

  • Do you know that there is no way (at least from my research and experiments) to hide the control box of a dialog. I tried several ways including using Native GetWindowLong and SetWindowLong to set the border style as fixed dialog but in vein.

  • One of the hardest things in WPF is to prevent re-size of a column in ListView. One way is to completely templatize ColumnHeader and comment out the thumb gripper. This approach is listed here: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/fa97b3a3-c5ca-4643-8e95-c2c23032de2c. I like the other approach listed in the article where one can attach a handler like:

    MyListView.AddHandler(Thumb.DragDeltaEvent,
    new DragDeltaEventHandler(this.OnHeaderResize),
    true);

    And handle it:

    private void OnHeaderResize(object sender, DragDeltaEventArgs e)
    {
    Thumb SenderAsThumb = e.OriginalSource as Thumb;
    GridViewColumnHeader header = SenderAsThumb.TemplatedParent as GridViewColumnHeader;

    if (header == null)
    {
    return;
    }

    GridView view = (MyListView.View as GridView);

    // If user tries to resize checkbox column, reset the width to fixed
    if (view.Columns[0] == header.Column)
    {
    header.Column.Width = FixedWidth;
    e.Handled = true;
    }
    }

  • ListView and CheckBox - Following is a method to add a checkbox both to the header and to the column rows in the ListView:

    <ListView Height="200" x:Name="MyListView">
    <ListView.View>
    <GridView>
    <GridViewColumn>
    <GridViewColumn.HeaderTemplate>
    <DataTemplate>
    <CheckBox Checked="AllSelectionChanged" Unchecked="AllSelectionChanged"/>
    </DataTemplate>
    </GridViewColumn.HeaderTemplate>
    <GridViewColumn.CellTemplate>
    <DataTemplate>
    <CheckBox IsChecked="{Binding Selected}"/>
    </DataTemplate>
    </GridViewColumn.CellTemplate>
    </GridViewColumn>
    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
    <GridViewColumn Header="Version" DisplayMemberBinding="{Binding Version}"/>
    <GridViewColumn Header="Path" DisplayMemberBinding="{Binding Path}"/>
    </GridView>
    </ListView.View>
    </ListView>


    You can then handle global check / uncheck like:

    private void AllSelectionChanged(object sender, RoutedEventArgs e)
    {
    CheckBox chkBox = sender as CheckBox;
    if (chkBox != null)
    {
    bool check = chkBox.IsChecked.Value;

    foreach ([YourBoundType] selection in MyListView.Items)
    {
    selection.Selected = check;
    }
    }
    }

Sunday, April 19, 2009

Expression Blend cannot open your custom control in designer ?

Sometimes especially working with off-designer you may end up in situations where Expression Blend can no longer open your user controls. You may get some error like:

Cannot create an instance of [User Control class]

A lot of times even attaching a debugger to Blend/VS and putting breakpoints in your constructor / breaking on error would not yield any benefits. Why?

The reason is Expression Blend and Visual Studio designer(s) have stringent conditions that a user control has to follow in order for its type to be even declared compatible for loading. So if any of these conditions are violated, type will be declared unfit and designer won't even bother locating / invoking the constructor of your user control. I have identified two such conditions (there may be more):

1. In no path of your inheritance hiararchy can there be an abstract class - So if you have a control that is derived from an abstract control class you are out of luck. Even though your end control is concrete it won't work !

2. You need a public default constructor at each level of inheritance hierarchy - That means even if you have a default constructor in your most derived user control class, it is not sufficient. All base classes must also have public default constructors (even if none of the base classes call it) ! Good news is you can assert if these constructors are called in designer only mode by the following code:
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
throw new InvalidOperationException("Constructor is only meant to be used by designer");
}