jQuery with ASP.NET

Building rich UI with jQuery and ASP.NET

jQuery UI Selectable With ASP.NET

without comments


While playing with jQuery UI library I have found great way to utilize jQuery UI Selectable plugin with ASP.NET. It can be used as a replacement for long series of checkboxes. For instance, in my scenario, I had to give authors (it’s a CMS system) ability to create a news and additionally give them an option to select countries relevant for the news. Logic behind it is that later we can easily filter news by country.

The most obvious approach is to give authors list of checkboxes or multiselect list. In my opinion both options are not very pleasant to use. Therefore I was looking for some alternative. And here is what I was able to achieve with jQuery Selectable plugin:

 

jQuery Selectable Plugin

Selectable list of countries implemented with jQuery Selectable

Authors have an option to select countries in a few different ways:

The jQuery UI Selectable plugin allows for elements to be selected by dragging a box (sometimes called a lasso) with the mouse over the elements. Also, elements can be selected by click or drag while holding the Ctrl/Meta key, allowing for multiple (non-contiguous) selections.

On top of that it’s very easy to add functional buttons like ‘Select All’ and ‘Deselect All’.

I think that’s it in terms of introduction, now I will show you how to get jQuery UI Selectable plugin integrated with ASP.NET. Also I will show you how to pre-select some elements and how to add select all (and deselect all) functionality.

How to integrate jQuery UI Selectable plugin with ASP.NET

Step 1 – download jQuery UI on your machine. I was using version 1.8.14.

Step 2 – Make sure that your page has all the required JS and CSS files included. jQuery Selectable plugin has a few dependencies. Here is everything you need:

<link href="Styles/ui-lightness/jquery-ui-1.8.14.custom.css" rel="stylesheet" type="text/css" />
<script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
<script src="Scripts/ui/jquery.ui.core.js" type="text/javascript"></script>
<script src="Scripts/ui/jquery.ui.widget.js" type="text/javascript"></script>
<script src="Scripts/ui/jquery.ui.mouse.js" type="text/javascript"></script>
<script src="Scripts/ui/jquery.ui.selectable.js" type="text/javascript"></script>

Step 3 – HTML

Our goal is to get HTML like this:

<h3>This is Selectable plugin demo!</h3>
<div>
    <ol id="selectable">
		<li class="ui-widget-content">Argentina</li>
		<li class="ui-widget-content">Australia</li>
		<li class="ui-widget-content">Austria</li>
		<li class="ui-widget-content">Belgium</li>
	</ol>
</div>

But it’s not a good idea to hardcode countries in HTML, ASP.NET should generate the list. So on server side we will replace the HTML list with ASP.NET Repeater control:

<h3>This is Selectable plugin demo!</h3>
<div>
    <asp:Repeater ID="rptCountries" runat="server">
        <HeaderTemplate><ol id="selectable"></HeaderTemplate>
        <ItemTemplate>
            <li class="ui-widget-content">
                    <%# ((Country)Container.DataItem).Name %>
            </li>
        </ItemTemplate>
        <FooterTemplate></ol></FooterTemplate>
    </asp:Repeater>
</div>

You can see that on server side there is a class Country which has all the country related data. So let’s jump to server side where you will find the details.

Step 4 – ASP.NET code

At the moment, server side code looks like this:

public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public partial class SelectableDemo : System.Web.UI.Page
{
    // list of countries can be much longer
    private IList<Country> countries = new List<Country>() {
                new Country () { Id = 1, Name = "Argentina" },
                new Country () { Id = 2, Name = "Australia" },
                new Country () { Id = 3, Name = "Austria" }
            };

    protected void Page_Load(object sender, EventArgs e)
    {
        rptCountries.DataSource = countries;
        rptCountries.DataBind();
    }
}

One thing worth noticing is that Country class has an Id property which is set for all countries from my example but it’s not used anywhere. It will be required in further steps when we will get the point of saving selected countries.

Step 5 – jQuery code

The final step is to enable jQuery Selectable plugin on our list. This is as simple as this:

$(document).ready(function () {
    $("#selectable").selectable();
});

To find our countries list I’m using jQuery selector $(“#selectable”) which will find all tags with ID selectable.

After completing this step you should get list of countries generated by ASP.NET and jQuery Selectable plugin enabled for the list. So in fact you should be able to already select countries which you like.

But the job is not really finished yet! How are you going to save selected countries? How are you going to pre-select countries saved earlier? How to implement select all or deselect all functionality? This is exactly where the fun begins…

Step 1 – Let’s start with changes in HTML generated by ASP.NET, we need to add a few elements there:

  • button to save selected countries,
  • button to select all countries
  • button to deselect all countries
  • text box where jQuery will list selected countries – this way it will be easy to get it on server side,
  • and a literal to display a message after saving the list – it is not really needed, but it will handy to prove that everything works ;)
  • HTML list has to change as well – there will be a new attribute countryid which is not displayed anywhere but it’s a way to give jQuery information about ID of selected country

Here are the changes:

<h3>This is Selectable plugin demo!</h3>
<div>
    <asp:Repeater ID="rptCountries" runat="server">
        <HeaderTemplate><ol id="selectable"></HeaderTemplate>
        <ItemTemplate>
            <li
                countryid="<%# ((Country)Container.DataItem).Id %>"
                class="ui-widget-content">
                    <%# ((Country)Container.DataItem).Name %>
            </li>
        </ItemTemplate>
        <FooterTemplate></ol></FooterTemplate>
    </asp:Repeater>
<br />
<button id="selectall">Select All</button>
<button id="deselectall">Deselect All</button> <br />
<asp:Button ID="btnSaveChanges" runat="server" Text="Save Changes" onclick="btnSave_Click" /> <br />
<asp:Literal ID="litMessage" runat="server" />
<asp:TextBox ID="txbSelectedCountries" runat="server" CssClass="selectedCountries" />
</div>

Step 2 – Changes in ASP.NET, code behind file:

  • Country class will have an additional property – Selected,
  • Page_Load method has to not only set DataSource for the Repeater, it has to also check which countries are selected and put this information to the text box txbSelectedCountries. jQuery will later parse it and select appropriate countries.
  • method btnSave_Click has to be added – within this method, after clicking on ‘Save Changes’ button, we will get list of all selected countries (from text box txbSelectedCountries) and display relevant information in the literal component (litMessage). It also has to update internal list of countries and mark selected countries as selected.

Here are the changes:

public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool Selected { get; set; }
}

public partial class SelectableDemo : System.Web.UI.Page
{
    private IList<Country> countries = new List<Country>() {
            new Country () { Id = 1, Name = "Argentina", Selected = true },
            new Country () { Id = 2, Name = "Australia", Selected = false },
            new Country () { Id = 3, Name = "Austria", Selected = false }
        };

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            rptCountries.DataSource = countries;
            rptCountries.DataBind();

            // add selected countries to a textbox
            StringBuilder selectedCountries = new StringBuilder();
            foreach (var country in countries)
            {
                if (country.Selected) selectedCountries.Append(country.Id + ",");
            }

            txbSelectedCountries.Text = selectedCountries.ToString();
        }
    }

    protected void btnSave_Click(object sender, EventArgs e)
    {
        // mark all in-memory countries as Selected = false
        foreach (var country in countries)
        {
            country.Selected = false;
        }

        // selected countries are in format: 1,2,5,6,
        string[] selectedIds = txbSelectedCountries.Text
                        .Substring(0, txbSelectedCountries.Text.Length-1).Split(',');
        StringBuilder output = new StringBuilder();

        foreach (string id in selectedIds)
        {
            var country = (from c in countries where c.Id.ToString().Equals(id) select c)
                        .First<Country>();
            country.Selected = true;
            output.Append(country.Name + "<br/>");
        }

        litMessage.Text = "Saved Countries: <br/>" + output.ToString();
    }
}

IDs of selected countries are stored as a single string, IDs are comma separated, for instance: 1,56,42,2,
Please note that after last ID there is an additional comma.

Step 3 – Changes in jQuery code

This part is the most complex, firstly you need to bind custom function to “selectablestop” event. Custom function will figure out which countries are selected and will update the txbSelectedCountries text box with the IDs:

$(document).ready(function () {
    $("#selectable").selectable();

    $("#selectable").bind("selectablestop", function (event) {
        var result = "";
        $(".ui-selected", this).each(function () {
            result += this.getAttribute("countryid") + ",";
        });
        $("input.selectedCountries").val(result);
    });

    //update selected countries based on value in selectedCountries input (textbox)
    var ids = $("input.selectedCountries").val().split(',');
    for (var i = 0; i < ids.length - 1; i++) {
        $("#selectable li[countryid=" + ids[i] + "]").addClass("ui-selected");
    }
});

Additionally, in last lines, jQuery has to parse data from selectedCountries input and select those countries which IDs are there. This way countries selected earlier and saved will appear on page load as selected. Those lines will be executed only once, it’s a way to keep data synchronised between ASP.NET on server side and jQuery on client side.

Next thing to do is to add ‘select all’ and ‘deselect all’ functionality. Here is how to get it done:

$(document).ready(function () {
    $("button, input:submit").button();

    $("button#selectall").click(function (event) {
        $("#selectable li").addClass("ui-selected");
        $("#selectable").trigger("selectablestop");
        event.preventDefault();
    });

    $("button#deselectall").click(function (event) {
        $("#selectable li").removeClass("ui-selected");
        $("#selectable").trigger("selectablestop");
        event.preventDefault();
    });
});

Three things are important here:

  • First line is an example of jQuery UI button plugin used. The only reason why it’s here is make buttons look nice. If you want to use it, it’s not a problem, but you need to add reference to the jquery.ui.button.js file
  • Next function is responsible for ‘select all’ functionality. You will find there basic usage of jQuery selectors (“#selectable li”) to find all list items and add “ui-selected” class. In the next line we are manually triggering “selectablestop” event to tell jQuery that selection has been made. As a result our function bound to that event will be executed and IDs of selected countries will end up in text box. And finally event.preventDefault() function prevents button from submitting the form.
  • And the last function is responsible for ‘deselect all’ functionality. The only difference is that instead of adding “ui-selected” class we are removing this class to make sure that all countries are not selected.

And this is the final effect after saving the countries:

jQuery Selectable Plugin with ASP.NET

View after saving the countries

Is that all? 

Well, almost – this is all in terms of functionality. You still need to play with CSS a bit to get the final effect like the one on attached screen. It’s not difficult, you can download the code and check modifications which I made, there are very few. Also you can download the project just to play with it and see how it all works together.

You can as well check how to integrate other jQuery UI widgets with ASP.NET like:

You may also need to check other events and options which you use with jQuery UI Selectable plugin.

VN:F [1.9.20_1166]
Rating: 7.3/10 (7 votes cast)
jQuery UI Selectable With ASP.NET, 7.3 out of 10 based on 7 ratings

Written by admin

August 1st, 2011 at 8:05 am

Leave a Reply