DotNetSlackers: ASP.NET News for lazy Developers

Wednesday, August 3, 2011

In this article I'll show you how to build a simple, yet powerful and extensible jQuery form validation plugin
<form>
    <fieldset>
        <legend>Legend Name</legend>
        <div>
            <label for="name">Name</label>
            <input type="text" id="name" name="name">
        </div>
    </fieldset>
</form>
This is how I markup my forms. Trying to keep it as simple and semantic as possible, but adding the div to make styling easier.

Specifying input validation

In HTML4 there is no obvious way attach validation rules to an input. A few developers have been somewhat orthodox and added their own “validation” attribute.
<input type="text" id="name" name="name" validation=required email>
This is not valid HTML, but it works in all browsers, and maybe it’s better than using a valid attribute for the wrong reasons. It's up to you, but this is how I do it.

The validation object

The base validation object contains a set of methods and properties that only needs be stored in one place, but can be accessed globally. In object oriented terminology this is commonly referred to as a Singleton.
// Wrap code in an self-executing anonymous function and 
// pass jQuery into it so we can use the "$" shortcut without 
// causing potential conflicts with already existing functions.
(function($) {

    var validation = function() {

        var rules = {  // Private object

            email : {
               check: function(value) {

                   if(value) {
                       return testPattern(value,"[a-z0-9!#$%&'*+/=?^_`{|}~-]+
                                                   (?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)
                                                   *@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])
?\                                                 .)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])");
                   }
                   return true;
               },
               msg : "Enter a valid e-mail address."
            },
            required : {

               check: function(value) {

                   if(value) {
                       return true;
                   }
                   else {
                       return false;
                   }
               },
               msg : "This field is required."
            }
        }
        var testPattern = function(value, pattern) {   // Private Method

            var regExp = new RegExp(pattern,"");
            return regExp.test(value);
        }
        return { // Public methods

            addRule : function(name, rule) {

                rules[name] = rule;
            },
            getRule : function(name) {

                return rules[name];
            }
        }
    }
    //A new instance of our object in the jQuery namespace.
    $.validation = new validation();
})(jQuery); 
// Again, we're passing jQuery into the function 
// so we can use $ without potential conflicts.
The object contains a set of rules, each with a function and a message. There's also a function called "testPattern". Being defined with the var keyword makes them private and inaccessible outside the object itself.
NOTE: I've simplified the regular expressions above to make the example readable. I suggest you take a look at the expressions from the official jQuery valide plugin for the real deal.
NOTE2: Never rely on JavaScript validation alone if your sending data to a server, you'll have to do server side validation too.
Adding the object to the jQuery $ namespace is useful because now we can access it like any other jQuery object, hence, it'll be helpful later on in our plugin code.

Public methods

Instead of hard coding lots of rules, we keep it down to a minimum. We defined a method called "addRule" and made it public by wrapping it in a return statement. The concept of returning methods and properties to make them public is commonly referred to as the module pattern.

Adding additional validation rules

People can now use our method to quickly add new custom validation rules without having to modify our code.
$.validation.addRule("test",{
    check: function(value) {
        if(value != "test") {
            return false;
        }
        return true;
    },
    msg : "Must equal to the word test."
});
We’ve now added a custom validation rule called “test”, maybe not so useful, but consider the next example. We add a rule to check whether a username is taken or not, with an imaginary AJAX request.
$.validation.addRule("xhr-test", {
    check: function(value) {
        $.get("/url-to-username-check", { username: value }, function(data) {
            if(data.isValid) {
                return true;
            }
            return false;
        });
    },
    msg : "Username already exists."
});
/*
Obviously, you’d want to improve the above 
example to handle possible AJAX failures.
*/
Some people will by now probably point out that the addRule method is essentially the same as making the object public and letting people add stuff to it themselves. Yes, that's true, but this a VERY simple abstraction. Should the code get any more advanced an abstraction like this could be helpful for anyone using your code.

Take a look inside

Lets take a look at our object in the firebug console.
console.log($.validation);
It should simply print out "object". If you click it you'll see the public methods we added earlier on. Let's see what the getRule method produces.
console.log($.validation.getRule("xhr-test"));
As you'll see, it returns the rule we added earlier. In OOP terminology we've now implemented getters and setters. Instead of allowing direct access to an objects private properties. It's better to have public methods that make these changes. It produces a cleaner API to the end user and it gives us more flexibility in case something else needs to run when modifying a property.

But someone told me the module pattern sucks...

Although I prefer this style of coding, it should be said that some developers neglect the idea of hiding properties and methods (a.k.a data encapsulation) in JavaScript. I think there are some very legitimate arguments linked to that statement. I leave it up to you to make up your own mind, nevertheless it's good to have knowledge of different design patterns even if you don't use them.

The form object

The form object will represent an instance of a form in the DOM.
var Form = function(form) {

    var fields = [];
    // Get all input elements in form
    $(form[0].elements).each(function() {
        var field = $(this);
        // We're only interested in fields with a validation attribute
        if(field.attr('validation') !== undefined) {
            fields.push(new Field(field));
        }
    });
    this.fields = fields;
}
A form has a number of fields belonging to it. We iterate over all the inputs and textareas that has a validation attribute using the jQuery each method. For each field there is, we create a new instance of the Field object which looks like this:
var Field = function(field) {
    this.field = field;
    this.valid = false;
}
We've defined some properties using the this keyword which refers to the object itself. We can now create any number of "form" instances with the new keyword.
var comment_form = new Form($("#comment_form"));
//another instance
var contact_form = new Form($("#contact_form"));
//Take a look inside the object
console.log(comment_form);
Providing your forms actually contain some fields with a validation attribute, you should see some interesting results when printing the object in the firebug console.

The JavaScript prototype object

This may seem like a tricky concept at first, but once you can wrap your head around prototypal inheritance, it's a really powerful and useful feature of the JavaScript language.

The problem

We have a large number of instances of the Field object, all of which we need to add some methods to. At first it may seem like a perfectly good idea to do the following:
Field.validate = function() {}
But this essentially means that if we have 30 fields instances, we will have 30 instances of the validate function, which is really a waste, since they all do the same thing.

The solution

Adding the validate method to the prototype object of Field will make all instances of Field inherit the validate method, but the validate method only exists in one place, so any changes to it will be reflected upon all instances of the Field object.
field.prototype.validate = function() {}
This feature should be used with care, especially when used on native javascript objects, before you fiddle around with it to much I recommend you read up further on the subject.

The Field validation methods

These are thetwo methods attached to the Field prototype object.
Field.prototype = {
    // Method used to attach different type of events to
    // the field object.
    attach : function(event) {

        var obj = this;
        if(event == "change") {
            obj.field.bind("change",function() {
                return obj.validate();
            });
        }
        if(event == "keyup") {
            obj.field.bind("keyup",function(e) {
                return obj.validate();
            });
        }
    },

    // Method that runs validation on a field
    validate : function() {

        // Create an internal reference to the Field object. 
        var obj = this, 
            // The actual input, textarea in the object
            field = obj.field, 
            errorClass = "errorlist", 
            errorlist = $(document.createElement("ul")).addClass(errorClass),
            // A field can have multiple values to the validation
            // attribute, seprated by spaces.
            types = field.attr("validation").split(" "), 
            container = field.parent(),
            errors = []; 

        // If there is an errorlist already present
        // remove it before performing additional validation
        field.next(".errorlist").remove();

        // Iterate over validation types
        for (var type in types) {

            // Get the rule from our Validation object.
            var rule = $.Validation.getRule(types[type]);
            if(!rule.check(field.val())) {

                container.addClass("error");
                errors.push(rule.msg);
            }
        }
        // If there is one ore more errors
        if(errors.length) {

            // Remove existing event handler
            obj.field.unbind("keyup")
            // Attach the keyup event to the field because now
            // we want to let the user know as soon as she has
            // corrected the error
            obj.attach("keyup");

            // Empty existing errors, if any.
            field.after(errorlist.empty());
            for(error in errors) {

                errorlist.append("<li>"+ errors[error] +"</li>");        
            }
            obj.valid = false;
        } 
        // No errors
        else {
            errorlist.remove();
            container.removeClass("error");
            obj.valid = true;
        }
    }
}
As a last step, we're going to edit the Field object we defined earlier:
var Field = function(field) {

    this.field = field;
    this.valid = false;
    this.attach("change"); // add this line.
}
Now each field will validate upon the "change" event.

Finishing the Form Object

Now our Field object is pretty much complete, let's add a few more features to the Form object before moving on to the actual jQuery plugin implementation.
Form.prototype = {
    validate : function() {

        for(field in this.fields) {

            this.fields[field].validate();
        }
    },
    isValid : function() {

        for(field in this.fields) {

            if(!this.fields[field].valid) {

                // Focus the first field that contains
                // an error to let user fix it. 
                this.fields[field].field.focus();

                // As soon as one field is invalid
                // we can return false right away.
                return false;
            }
        }
        return true;
    }
}

The jQuery plugin methods

We're going to use the jQuery extend method to make our plugin accessible as methods on any jQuery object.
$.extend($.fn, {

    validation : function() {

        var validator = new Form($(this));
        $.data($(this)[0], 'validator', validator);

        $(this).bind("submit", function(e) {

            validator.validate();
            if(!validator.isValid()) {

                e.preventDefault();
            }
        });
    },
    validate : function() {

        var validator = $.data($(this)[0], 'validator');
        validator.validate();
        return validator.isValid();
    }
});
The validation method is what we use to create a new validation instance associated to a form. You can see that we're creating a new form instance and also binding the a submit event handler to run the validation upon form submission.

The jQuery $.data method

This is pretty nifty feature and allows us to store data assoicated to a jQuery object. In this case, we are storing an instance of the form object inside the object passed into the plugin. In the validate method, that we use to validate the form at anytime, we can now call the already existing form instance, instead of creating a new one.

Usage

Based on the plugin that we've now built, here's some usage examples.
$(function(){ // jQuery DOM ready function.

    var myForm = $("#my_form");

    myForm.validation();

    // We can check if the form is valid on
    // demand, using our validate function.
    $("#test").click(function() {

        if(!myForm.validate()) {

            alert("oh noes.. error!");
        }
    });
});
 
You can look at the full jquery.validation.js code itself, feel free to use it.

That's all

I hope you found this article useful and educational, the example plugin is far from the perfect form validation script but that was not the primary goal of this article, but rather write nicely structured JavaScript code in an object oriented approach.

ASP.net Interview Questions And Answers

Ques: 1 What does the keyword virtual declare for a method?
Ans: 
The method or property can be overridden. 
Ques: 2 Tell me  implicit name of the parameter that gets passed into the set property 
of a class? 
Ans: 
The data type of the value parameter is defined by whatever data type the property is declared as. 
Ques: 3 What is the difference between an interface and abstract class ?
Ans: 
1. In an interface class, all methods are abstract and there is no implementation.  In an abstract class some methods can be concrete.
2. In an interface class, no accessibility modifiers are allowed.  An abstract class may have accessibility modifiers. 
Ques: 4 How to Specify the accessibility modifier for methods inside the interface?
Ans:They all must be public, and are therefore public by default. 
Ques: 5 Define interface class ?
Ans: 
Interfaces, like classes, define a set of properties, methods, and events. But unlike classes, interfaces do not provide implementation. They are implemented by classes, and defined as separate entities from classes. 
Ques: 6 When you declared a class as abstract?
Ans: 
1. When at least one of the methods in the class is abstract.  
2. When the class itself is inherited from an abstract class, but not all base abstract methods have been overridden.  
Ques: 7 Define abstract class?
Ans:1. A class that cannot be instantiated.
2. An abstract class is a class that must be inherited and have the methods overridden.
3. An abstract class is essentially a blueprint for a class without any implementation
Ques: 8 How to allowed a class to be inherited, but it must be prevent the method from being over-ridden?
Ans: 
Just leave the class public and make the method sealed. 
Ques: 9 How to prevent your class from being inherited by another class? 
Ans:
 We use the sealed keyword to prevent the class from being inherited. 
Ques: 10 What class is underneath the SortedList class?

Ans:
 A sorted HashTable. 
Ques: 11 What is the .NET collection class that allows an element to be accessed using a unique key?
Ans:
 HashTable. 
Ques: 12 Difference between the System.Array.Clone() and System.Array.CopyTo()?
Ans:
 The Clone() method returns a new array (a shallow copy) object containing all the elements in the original array.  The CopyTo() method copies the elements into another existing array.  Both perform a shallow copy.  A shallow copy means the contents (each array element) contains references to the same object as the elements in the original array.  A deep copy (which neither of these methods performs) would create a new instance of each element's object, resulting in a different, yet identacle object.
Ques: 13 Difference between System.String and System.Text.StringBuilder classes?
Ans:
System.String is immutable.  System.StringBuilder was designed with the purpose of having a mutable string where a variety of operations can be performed. 
Ques: 14 What is the top .NET class that everything is derived from? 
Ans: 
System.Object. 
Ques: 15 How can you automatically generate interface for the remotable object in .NET?
Ans:
 Use the Soapsuds tool.
Ques: 16 How to configure a .NET Remoting object via XML file?
Ans: 
It can be done via machine.config and application level .config file (or web.config in ASP.NET). Application-level XML settings take precedence over machine.config. 
Ques: 17 What is Singleton activation mode?
Ans: 
A single object is instantiated regardless of the number of clients accessing it. Lifetime of this object is determined by lifetime lease. 
Ques: 18 What security measures exist for .NET Remoting?
Ans:
None. 
Ques: 19 In .NET Remoting, What are channels?
Ans: 
Channels represent the objects that transfer the other serialized objects from one application domain to another and from one computer to another, as well as one process to another on the same box. A channel must exist before an object can be transferred. 
Ques: 20 What are remotable objects in .NET Remoting?
Ans: 
1. They can be marshaled across the application domains.
2. You can marshal by value, where a deep copy of the object is created and then passed to the receiver. You can also marshal by reference, where  just a reference to an existing object is passed. 
Ques: 21 Do you know the proxy of the server object in .NET Remoting? 
Ans: 
This process is known as marshaling. It handles the communication between real server object and the client object. We can say that It’s a fake copy of the server object that resides on the client side and behaves as if it was the server. 
Ques: 22 Give your idea when deciding to use .NET Remoting or ASP.NET Web Services? Ans: 
1. Remoting is a more efficient communication exchange when you can control both ends of the application involved in the communication process. 2. Web Services provide an open-protocol-based exchange of informaion. Web Services are best when you need to communicate with an external organization or another (non-.NET) technology.  
Ques: 23 Define the possible implementations of distributed applications in .NET?  
Ans:.
NET Remoting and ASP.NET Web Services. If we talk about the Framework Class Library, noteworthy classes are in System.Runtime.Remoting and System.Web.Services.  
Ques: 24 Explain what relationship is between a Process, Application Domain, and Application?  
Ans:A process is an instance of a running application. An application is an executable on the hard drive or network. There can be numerous processes launched of the same application (5 copies of Word running), but 1 process can run just 1 application.  
Ques: 25 What’s typical about a Windows process in regards to memory allocation?  
Ans:Each process is allocated its own block of available RAM space, no process can access another process’ code or data. If the process crashes, it dies alone without taking the entire OS or a bunch of other applications down.  
Ques: 26 What’s a Windows process?  
Ans:It’s an application that’s running and had been allocated memory.  
Ques: 27 Using XSLT, how would you extract a specific attribute from an element in an XML document?  
Ans:Successful candidates should recognize this as one of the most basic applications of XSLT. If they are not able to construct a reply similar to the example below, they should at least be able to identify the components necessary for this operation: xsl:template to match the appropriate XML element, xsl:value-of to select the attribute value, and the optional xsl:apply-templates to continue processing the document.
Ques: 28 What is SOAP and how does it relate to XML?  
Ans:The Simple Object Access Protocol (SOAP) uses XML to define a protocol for the exchange of information in distributed computing environments. SOAP consists of three components: an envelope, a set of encoding rules, and a convention for representing remote procedure calls. Unless experience with SOAP is a direct requirement for the open position, knowing the specifics of the protocol, or how it can be used in conjunction with HTTP, is not as important as identifying it as a natural application of XML.
Ques: 29 What is main difference between Global.asax and Web.Config?  
Ans:ASP.NET uses the global.asax to establish any global objects that your Web application uses. The .asax extension denotes an application file rather than .aspx for a page file. Each ASP.NET application can contain at most one global.asax file. The file is compiled on the first page hit to your Web application. ASP.NET is also configured so that any attempts to browse to the global.asax page directly are rejected. However, you can specify application-wide settings in the web.config file. The web.config is an XML-formatted text file that resides in the Web site’s root directory. Through Web.config you can specify settings like custom 404 error pages, authentication and authorization settings for the Web site, compilation options for the ASP.NET Web pages, if tracing should be enabled, etc  
Ques: 30 What is the difference between the value-type variables and reference-type variables in terms of garbage collection?  
Ans:The value-type variables are not garbage-collected, they just fall off the stack when they fall out of scope, the reference-type objects are picked up by GC when their references go null.  
Ques: 31 Where do the reference-type variables go in the RAM?  
Ans:The references go on the stack, while the objects themselves go on the heap. However, in reality things are more elaborate.  
Ques: 32 What’s the difference between struct and class in C#?  
Ans:1. Structs cannot be inherited. 2. Structs are passed by value, not by reference. 3. Struct is stored on the stack, not the heap.
Ques: 33 To test a Web service you must create a windows application or Web application to consume this service?  
Ans:The webservice comes with a test page and it provides HTTP-GET method to test.  
Ques: 34 What is the transport protocol you use to call a Web service?
Ans: SOAP is the preferred protocol.
Ques: 35 Can you give an example of what might be best suited to place in the Application Start and Session Start subroutines? 
Ans:This is where you can set the specific variables for the Application and Session objects.  
Ques: 36 Where do you store the information about the user’s locale?
Ans:System.Web.UI.Page.Culture
Ques: 37 Where does the Web page belong in the .NET Framework class hierarchy?  
Ans:System.Web.UI.Page
Ques: 38 Name two properties common in every validation control?  
Ans:ControlToValidate property and Text property  
Ques: 39 What property must you set, and what method must you call in your code, in order to bind the data from some data source to the Repeater control?  
Ans:You must set the DataSource property and call the DataBind method.  
Ques: 40 How can you provide an alternating color scheme in a Repeater control?  
Ans:Use the AlternatingItemTemplate
Ques: 41 Which template must you provide, in order to display data in a Repeater control? 
Ans:
ItemTemplate 
Ques: 42 Can you edit data in the Repeater control?  
Ans:No, it just reads the information from its data source 
 Ques: 43 Which method do you invoke on the DataAdapter control to load your generated dataset with data?
Ans:The .Fill() method  
Ques: 44 Describe the difference between inline and code behind.  
Ans:Inline code written along side the html in a page. Code-behind is code written in a separate file and referenced by the .aspx page.  
Ques: 45 What’s a bubbled event?  
Ans:When you have a complex control, like DataGrid, writing an event processing routine for each object (cell, button, row, etc.) is quite tedious. The controls can bubble up their eventhandlers, allowing the main DataGrid event handler to take care of its constituents.
Ques: 46 What is the role of global.asax.  
Ans:Store global information about the application
Ques: 47 Can the action attribute of a server-side <form> tag be set to a value and if not how can you possibly pass data from a form page to a subsequent page. 
Ans:No, You have to use Server.Transfer to pass the data to another page.  
Ques: 48 Can you give an example of when you might use it?  
Ans:When you want to inherit (use the functionality of) another class. Base Class Employee. A Manager class could be derived from the Employee base class.  
Ques: 49 Can you explain the difference between an ADO.NET Dataset and an ADO Recordset?
Ans:1. A DataSet can represent an entire relational database in memory, complete with tables, relations, and views. 2. A DataSet is designed to work without any continuing connection to the original data source. 3. Data in a DataSet is bulk-loaded, rather than being loaded on demand.  
Ques: 50 What is the difference between Server.Transfer and Response.Redirect?
Ans:1. Server.Transfer() performs server side redirection of the page avoiding extra round trip. While The Response .Redirect () method can be used to redirect the browser to specified url. 2. Server.Transfer is used to post a form to another page. Response.Redirect is used to redirect the user to another page or site.  
Ques: 51 Explain the difference between a database administrator and a data administrator.
Ques: 52 What is smart navigation? 
  Ans:Smart navigation is, cursor position is maintained when the page gets refreshed due to the server side validation and the page gets refreshed.
Ques: 53 What is the difference between Literal and Lable Control?  
Ans:We use literals control if we want to typed text using HTML formating and without using property.We typed HTML code in .cs file when used literals. Lable control when displayed already formated.Typed text can not be formated in .cs file.  
Ques: 54 What are the 2 Layouts supported by a Web form in ASP.NET?  
Ans:1. Grid layout: Pages using grid layout will not always display correctly in non-Microsoft browsers,and controls are placed exactly where they draw.It means they have absolute positions on the page. Use grid layout for Microsoft Windows–style applications, in which controls are not mixed with large amounts of text. 2. Flow layout: Controls relative to other elements on the page. Controls that appear after the new element move down if you add elements at run time. Flow layout for document-style applications, in which text and controls are intermingled.  
Ques: 55 Can you specify authorization settings both in Web.config and in IIS?
Ans:Yes,It wil be done. For this, the IIS setting is evaluated first and then the setting in Web.config is evaluated. Hence we can say,the most restrictive setting will be used.
Ques: 56 How do you determine, what is the role of the current user?  
Ans:The User object provides an IsInRole method to determine the role of the current user, as shown in the following example: if(User.IsInRole("Administrators")) { /////// }
Ques: 57 How do you get a User Identity?  
Ans:Using the User object’s Identity property. The Identity property returns an object that includes the user name and role information, as shown in the following code: private void Page_Load(object sender, System.EventArgs e) { Label1.Text = User.Identity.IsAuthenticated.ToString(); Label2.Text = User.Identity.Name; Label3.Text = User.Identity.AuthenticationType; }
Ques: 58 What is the default authentication method when you create a new Web application project? 
Ans:Windows authentication is the default authentication method when you create a new Web application project. Ques: 59 What is the advantage of using Windows authentication in a Web application? Ans:The advantage of Windows authentication: 1. Web application can use the exact same security that applies to your corporate network like user names, passwords, and permissions. 2. To access the Web application users logged on to the network. It is importent that user does'nt logged on again.  
Ques: 60 What do you mean by neutral cultures?
Ans:Neutral cultures represent general languages, such as English or Spanish and a specific language and region.ASP.NET assigns that culture to all the threads running for that Web application.When user set culture attribute for a Web application in Web.config.ASP.NET maintains multiple threads for a Web application within the aspnet_wp.exe worker process.
 

Populate a select dropdown list using jQuery and Ajax

In this post I’ll explain how to populate a select dropdownlist using jQuery and Ajax.  I am using an ASP.NET web application and page methods to perform the Ajax calls.  Using page methods means that you do not need a seperate web service, which is good if the functionality is specifically for the page.  The page methods must be declared public static and use the WebMethod attribute.

First of all here is the contents of my form with two select lists, one for gender and one for names.  Each list is given a unique ID to be able to reference them in jQuery.  The intention here is to display a list of genders in the first list, which when selected populates the second select with a list of names for that gender.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<table>
    <tr>
        <th>
            Gender
        </th>
        <td>
            <select id="ddlGender">
            </select>
        </td>
    </tr>
    <tr>
        <th>
            Name
        </th>
        <td>
            <select id="ddlName">
            </select>
        </td>
    </tr>
</table>
Here is the page method that gets my list of genders:
1
2
3
4
5
6
7
8
9
[WebMethod]
public static ArrayList GetGenders()
{
    return new ArrayList()
    {
        new { Value = 1, Display = "Male" },
        new { Value = 2, Display = "Female" }
    };
}
For the purpose of the example I am just returning an ArrayList of an anonymous type containing a value and display text which will be converted to JSON in jQuery and used to populate the select list.  You could easily replace this code to get some data from a database if required.
Here is the method used to get the list of names based on the selected gender.  I will be passing the Value property from the anonymous gender type through to this method to filter the list of names:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[WebMethod]
public static ArrayList GetNames(int genderID)
{
    if (genderID.Equals(1))
    {
        return new ArrayList()
        {
            new { Value = 1, Display = "Joe" },
            new { Value = 2, Display = "Tom" },
            new { Value = 3, Display = "Sylvain" }
        };
    }
    else if (genderID.Equals(2))
    {
        return new ArrayList()
        {
            new { Value = 4, Display = "Emily" },
            new { Value = 5, Display = "Lauri" },
        };
    }
    else
    {
        throw new ApplicationException("Invalid Gender ID");
    }
}
Again I am returning an ArrayList of an anonymous type containing a list of names depending on the genderID passed into the method.
Now for the fun part, hooking it all up with jQuery.  First I need to populate the gender list when the page loads:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    
$().ready(function() {
    $.ajax({
        type: "POST",
        url: "Default.aspx/GetGenders",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(msg) {
            $("#ddlGender").get(0).options.length = 0;
            $("#ddlGender").get(0).options[0] = new Option("Select gender", "-1");   
            $.each(msg.d, function(index, item) {
                $("#ddlGender").get(0).options[$("#ddlGender").get(0).options.length] = new Option(item.Display, item.Value);
            });
        },
        error: function() {
            alert("Failed to load genders");
        }
    });
});   

Here I am using jQuery’s Ajax method to make a call to the GetGenders page method.  In the successful callback from the call I then do the following:
Clear the select list’s current items:
1
$("#ddlGender").get(0).options.length = 0;
Add an item at the top of the list prompting to select a gender with a value of -1, I’ll check this value later before making a call to GetNames:
1
$("#ddlGender").get(0).options[0] = new Option("Select gender", "-1");
Loop through the results of the Ajax call and add the items to the list:
1
2
3
$.each(msg.d, function(index, item) {
    $("#ddlGender").get(0).options[$("#ddlGender").get(0).options.length] = new Option(item.Display, item.Value);
});
Now the gender dropdown list is populated when the page loads. Next I need the names list to be populated when choosing a gender.  To do this I have created a JavaScript function called GetNames which accepts the genderID as a parameter:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
function GetNames(genderID) {
    if (genderID > 0) {
        $("#ddlName").get(0).options.length = 0;
        $("#ddlName").get(0).options[0] = new Option("Loading names", "-1"); 
        $.ajax({
            type: "POST",
            url: "Default.aspx/GetNames",
            data: "{genderID:" + genderID + "}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(msg) {
                $("#ddlName").get(0).options.length = 0;
                $("#ddlName").get(0).options[0] = new Option("Select name", "-1"); 
                $.each(msg.d, function(index, item) {
                    $("#ddlName").get(0).options[$("#ddlName").get(0).options.length] = new Option(item.Display, item.Value);
                });
            },
            error: function() {
                $("#ddlName").get(0).options.length = 0;
                alert("Failed to load names");
            }
        });
    }
    else {
        $("#ddlName").get(0).options.length = 0;
    }

First I check if the genderID is greater than zero, if not (the ‘Select gender’ item has been chosen) then clear the names list.  If it is I clear the list and add an option with the text Loading names to the select list as I did with gender.  This will be displayed while the Ajax call is being made to let the user know something is happening.  Next I use the same approach as getting the list of gender to get the list of names but I pass a JSON string through as the data property containing the selected gender ID.  The successful callback works in the same way as populating the list of genders.
Finally I need this method to be called when a gender is selected so I’ve added the following to my successful Ajax callback underneath the loop that populates the genders:
1
2
3
$("#ddlGender").bind("change", function() {
    GetNames($(this).val());
});
This binds the onChange event to call the GetNames function passing through the selected gender ID.