Web Development Blog

Getting the selected value of RadioButtonList with JQuery

It struck me the other day that it is so easy to use AJAX with ASP.NET it can make you lazy. I was working on a project where I had some radio boxes and based in the selection of the radio boxes another fields was displayed or hidden. I didn't want the page to post back so initially it though I'll just pop it in a AJAX UpdatePanel and write some code to show or hide the fields after the selection is made on the RadioButtonList.

I paused for a moment and thought for a moment, its all good, its easy so why not.

I'm being lazy, I really shouldn't do a post back at all. I should write a bit of JavaScript to achieve this client side as the post back only serves to show or hide the fields.

So in the project I'm already using JQuery so its my first choice to implement my snippet of functionality.

Implementing a client side action for a RadioButtonList with JQuery

I wanted to take an action based on the selection of only one of the radio buttons. I wanted to find the selected index of the RadioButtonList. I cam up with the The functionality involved a RadioButtonList with the class 'Options' applied, which was only to save me have to get the ClientID property. If the third item is selected the FieldPanel div is shown otherwise it is hidden.

function setPanelVis(){  
        $(".Options input:radio").each(function(index) {  
            if($(this).val()==$(".Options input:radio:checked").val()){  
                if(index==2){  
                    $("div.FieldPanel").show("fast");  
                }  
                else{  
                    $("div.FieldPanel").hide("fast");  
                    $("div.FieldPanel input").val("");  
                }  
            }  
        });  
}  
//bind to radio button click   
$(document).ready(function() {  
    setPanelVis();  
    $(".Options input:radio").click(setPanelVis);  
}); 

So it works well and is all client side without any post backs. 


Using a multiple class selector on the one element

I came across the situation the other day where I wanted to apply a CSS rule when two classes appeared in the same element. The Html generated was a div containing buttons. I wanted to apply a custom background to one of the items in the list.

The Rendered Html 

As you hover over each of the button elements JavaScript toggled the button-hover class.

<div class="buttons"
    <button class="button-1">Ok</button> 
    <button class="button-2 button-hover">Cancel</button> 
</div> 

I wanted to have background image change on all of the list elements when button-hover was applied. The problem was I wanted to have a custom roll over images for each of the buttons.

The CSS

After a some re-reading of the CSS rules, the solution turned out to be quite straight forward. I could use the attribute value selector to test for the second class.

.buttons .button-1[class~="button-hover"
    backgroundred
.buttons .button-2[class~="button-hover"
    backgroundgreen


Sort a generic collection dynamically by class properties

Sorting items in a database using SQL is easy, simply order by whatever field you want that supports sorting, its easy to take that power for granted. But what if you already have your data in the form of a generic object collection which you want to sort.

It turns out to be quite simple, all you need to do is create a collection of System.Collections.Generic.List<T> and call the Sort() method. This will sort the collection by the item's System.IComparable interface. I have for this example created a simple class of type Item with a few properties. Take a look at the method int IComparable.CompareTo(object obj) in my class. When the Sort method is called on the collection it will be sorted alphabetically a-z on the Title property. Quite simple really, only what if you want to reorder your collection ordering by the CreatedDate property say in descending order?

    public class Item : IComparable 
    { 
        public int ID { getset; } 
        public string Title { getset; } 
        public DateTime CreatedDate { getset; } 
 
        int IComparable.CompareTo(object obj) 
        { 
            if ((obj == null) || (obj.GetType() != GetType())) 
            { 
                return -1; 
            } 
            Item castObj = (Item)obj; 
            return Title.CompareTo(castObj.Title); 
        } 
    } 

Implement a IComparer class

Create a ItemComparer class that inherits from the generic IComparer class and implement the method int IComparer<Item>.Compare(Item x, Item y). You can see in the example below I have created a Field and SortDirection enum. I prefer this approach to passing a string value, particularly if someone else is going to use your class.

    public sealed class ItemComparer : IComparer<Item> 
    { 
        public enum SortDirection 
        { 
            Ascending = 0, 
            Descending = 1 
        } 
 
        public enum Field 
        { 
            ID, 
            Title, 
            CreatedDate 
        } 
 
        private readonly Field _field = Field.Title; 
        private readonly SortDirection _sortDirection = SortDirection.Ascending; 
 
        public ItemComparer(Field field, SortDirection sortDirection) 
        { 
            _field = field; 
            _sortDirection = sortDirection; 
        } 
 
        int IComparer<Item>.Compare(Item x, Item y) 
        { 
            if (_sortDirection == SortDirection.Ascending) 
            { 
                switch (_field) 
                { 
                    case Field.Title: 
                        return string.Compare(x.Title, y.Title); 
                    case Field.CreatedDate: 
                        return DateTime.Compare(x.CreatedDate, y.CreatedDate); 
                    case Field.ID: 
                        return x.ID.CompareTo(y.ID); 
                    default
                        goto case Field.Title; 
                } 
            } 
            switch (_field) 
            { 
                case Field.Title: 
                    return string.Compare(y.Title, x.Title); 
                case Field.CreatedDate: 
                    return DateTime.Compare(y.CreatedDate, x.CreatedDate); 
                case Field.ID: 
                    return y.ID.CompareTo(x.ID); 
                default
                    goto case Field.Title; 
            } 
        } 
    } 

Sort the Generic Collection using IComparer

Great now I have an item IComparer class and can choose which field to sort by and the sort order.

    List<Item> items = new List<Item>(); 
    items.Add(new Item { ID = 1, CreatedDate = DateTime.Now, Title = "Title 1" }); 
    items.Add(new Item { ID = 2, CreatedDate = DateTime.Now, Title = "Title 2" }); 
    items.Add(new Item { ID = 3, CreatedDate = DateTime.Now, Title = "Title 3" }); 
    items.Sort(new ItemComparer(ItemComparer.Field.CreatedDate, ItemComparer.SortDirection.Descending)); 

So you can see it is quite straight forward to sort you collection dynamically on different properties of your class.