Saturday, October 9, 2010

Cascading Drop Down List using ASP.NET and C# + LINQ TO SQL

This article explains how to build a cascading drop-down list, using the language of ASP.NET and C #. Cascading drop-down list allows you to filter information sent from the database, allowing users to select relevant information according to its previous selection. For example, when we want to allow the user to search our website name of a street, we can present him with a scrolling list of states / countries, and the user to select a state. The next drop-down list will be updated automatically from the database and ask for the relevant towns only.

The first thing we should do is create 3 tables in the database, the first one call “Countries”. This table including 2 columns for countId (int) and countName (nvchar = for the name of the country). The second table is called “Cities” and including 3 columns: cityId (int), countId (int – inherits from the Countries countId), cityName (nvchar) and “Streets” which including streetId (int), cityId (int – inherits from the Cities cityId), streetName (nvchar).

dbCount

At this article we are using LINQ TO SQL, so the next thing we are needing to do is to create Data Class and drag into it the database tables. My data class call “DataClass.dbml”.

Now lets Fill the database tables with data!

countries

at the cities table, don’t forget to fill up the countId!

cities

and finally, the streets table

streets

as you can see, i was filled some values for Miami and New York City only! so later when we will select for other cities, the street drop down list will not fire cause there will be no data to display. Lets begin write some code.

Create Aspx page and check the Place code in separate file. in this case i am not using Master Page. In the design mode, drag and drop 3 drop down list controls (ddl) to the Div section. Give each ddl unique id: countDDL, cityDDL and streetDDL. For the countDDL and cityDDL make sure you are using AutoPost and Enabled the cityDDL + streetDDL to false. next you will need to use the OnSelectedIndexChanged function for the 2 first DDLs.

<form id="form1" runat="server">
<
div>

<
asp:DropDownList ID="countDDL" AutoPostBack="true" runat="server" Height="16px" Width="217px" OnSelectedIndexChanged="countDDL_OnSelectedIndexChanged">
</
asp:DropDownList>
<
br />
<
br />
<
asp:DropDownList ID="cityDDL" AutoPostBack="true" runat="server" Height="16px" Width="217px" Enabled="false" OnSelectedIndexChanged="cityDDL_OnSelectedIndexChanged">
</
asp:DropDownList>
<
br />
<
br />
<
asp:DropDownList ID="streetDDL" runat="server" Height="16px" Width="217px" Enabled="false">
</
asp:DropDownList>

</
div>
</
form>

The next step, is to fill the countDDL with the countries names from the Countries table while the page is load. We need to do that on the Page_load event.

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
countDDL.AppendDataBoundItems = true;
countDDL.Items.Add(new ListItem("Select country...", ""));
DataClassesDataContext db = new DataClassesDataContext();
var selectCountries = from t in db.Countries
orderby t.countName
select t;
countDDL.DataSource = selectCountries;
countDDL.DataTextField = "countName";
countDDL.DataValueField = "countId";
countDDL.DataBind();

cityDDL.AppendDataBoundItems = true;
cityDDL.Items.Add(new ListItem("Select City...", ""));

streetDDL.AppendDataBoundItems = true;
streetDDL.Items.Add(new ListItem("Select Street...", ""));
}
}
protected void countDDL_OnSelectedIndexChanged(object sender, EventArgs e)
{

}
protected void cityDDL_OnSelectedIndexChanged(object sender, EventArgs e)
{

}

Don’t forget to use the OnSelectedIndexChanged functions for the countDDL and cityDDL so there will be no compile errors.At the Page_Load event we are first using the AppendDataBoundItems to display some content like “Select Country…” that not send from the SQL database. Next we are using Linq to sql select statement to read all the countries names from the Countries table (order by the name of the countries). Then we set the DataTextField to the countName column which hold the county name and the DataValueField that hold the countId integer.  The last action is to put some values in the cityDDL and the streetDDL AppendDataBoundItems property.


The next step is to fire the OnSelectedIndexChanged event for each DDL so when we will select some value from the countDDL the cityDDL will fill up with the relevant content.


The OnSelectedIndexChanged event code is very similar to the Page_Load event with few changes. First of all we need to Clear() the coutDDL so that the data inside the ddl will not duplicate again and again.

protected void countDDL_OnSelectedIndexChanged(object sender, EventArgs e)
{
cityDDL.Items.Clear();
cityDDL.Items.Add(new ListItem("Select City...", ""));
streetDDL.Items.Clear();
streetDDL.Items.Add(new ListItem("Select Street...", ""));

cityDDL.AppendDataBoundItems = true;
DataClassesDataContext db = new DataClassesDataContext();
var selectCities = from t in db.Cities
where t.countId == Convert.ToInt32(countDDL.SelectedItem.Value)
orderby t.cityName
select t;
cityDDL.DataSource = selectCities;
cityDDL.DataTextField = "cityName";
cityDDL.DataValueField = "cityId";
cityDDL.DataBind();

if (cityDDL.Items.Count > 1)
{
cityDDL.Enabled = true;
}
else
{
cityDDL.Enabled = false;
streetDDL.Enabled = false;
}
}

The changes we used in this code is the where statement to filter and match the cities values to the selected country (by using the countId integer) and the if statement that check the return value(s) from the cityDDL so if there is no value the cityDDL will stay enabled false. We need to handle the cityDDL OnSelectedIndexChanged function to fire the streetDDL. We are doing that exactly the same way we’ve thread the cityDDL OnSelectedIndexChanged function.

protected void cityDDL_OnSelectedIndexChanged(object sender, EventArgs e)
{
streetDDL.Items.Clear();
streetDDL.Items.Add(new ListItem("Select Street...", ""));

streetDDL.AppendDataBoundItems = true;
DataClassesDataContext db = new DataClassesDataContext();
var selectStreets = from t in db.Streets
where t.cityId == Convert.ToInt32(cityDDL.SelectedItem.Value)
orderby t.streetName
select t;
streetDDL.DataSource = selectStreets;
streetDDL.DataTextField = "streetName";
streetDDL.DataValueField = "streetId";
streetDDL.DataBind();

if (streetDDL.Items.Count > 1)
{
streetDDL.Enabled = true;
}
else
{
streetDDL.Enabled = false;
}
}

I hope you find this article useful, feel free to comment.


This is the full Default.aspx.cs code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
countDDL.AppendDataBoundItems = true;
countDDL.Items.Add(new ListItem("Select country...", ""));
DataClassesDataContext db = new DataClassesDataContext();
var selectCountries = from t in db.Countries
orderby t.countName
select t;
countDDL.DataSource = selectCountries;
countDDL.DataTextField = "countName";
countDDL.DataValueField = "countId";
countDDL.DataBind();

cityDDL.AppendDataBoundItems = true;
cityDDL.Items.Add(new ListItem("Select City...", ""));

streetDDL.AppendDataBoundItems = true;
streetDDL.Items.Add(new ListItem("Select Street...", ""));
}
}
protected void countDDL_OnSelectedIndexChanged(object sender, EventArgs e)
{
cityDDL.Items.Clear();
cityDDL.Items.Add(new ListItem("Select City...", ""));
streetDDL.Items.Clear();
streetDDL.Items.Add(new ListItem("Select Street...", ""));

cityDDL.AppendDataBoundItems = true;
DataClassesDataContext db = new DataClassesDataContext();
var selectCities = from t in db.Cities
where t.countId == Convert.ToInt32(countDDL.SelectedItem.Value)
orderby t.cityName
select t;
cityDDL.DataSource = selectCities;
cityDDL.DataTextField = "cityName";
cityDDL.DataValueField = "cityId";
cityDDL.DataBind();

if (cityDDL.Items.Count > 1)
{
cityDDL.Enabled = true;
}
else
{
cityDDL.Enabled = false;
streetDDL.Enabled = false;
}
}
protected void cityDDL_OnSelectedIndexChanged(object sender, EventArgs e)
{
streetDDL.Items.Clear();
streetDDL.Items.Add(new ListItem("Select Street...", ""));

streetDDL.AppendDataBoundItems = true;
DataClassesDataContext db = new DataClassesDataContext();
var selectStreets = from t in db.Streets
where t.cityId == Convert.ToInt32(cityDDL.SelectedItem.Value)
orderby t.streetName
select t;
streetDDL.DataSource = selectStreets;
streetDDL.DataTextField = "streetName";
streetDDL.DataValueField = "streetId";
streetDDL.DataBind();

if (streetDDL.Items.Count > 1)
{
streetDDL.Enabled = true;
}
else
{
streetDDL.Enabled = false;
}
}
}

21 comments:

  1. thank you! your code is perfect!!!

    ReplyDelete
  2. Thanks for your code simple and perfect

    ReplyDelete


  3. Greetings. I know this is somewhat off-topic, but I was wondering if you knew where I could get a captcha plugin for my comment form? I’m using the same blog platform like yours, and I’m having difficulty finding one? Thanks a lot.

    AWS Training in Bangalore | Amazon Web Services Training in Bangalore

    Amazon Web Services Training in Pune | Best AWS Training in Pune

    AWS Online Training | Online AWS Certification Course - Gangboard

    ReplyDelete
  4. Wow it is really wonderful and awesome thus it is very much useful for me to understand many concepts and helped me a lot. it is really explainable very well and i got more information from your blog.

    rpa training in velachery| rpa training in tambaram |rpa training in sholinganallur | rpa training in annanagar| rpa training in kalyannagar

    ReplyDelete
  5. Its really an Excellent post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog. Thanks for sharing....

    Java training in Tambaram | Java training in Velachery

    Java training in Omr | Oracle training in Chennai

    ReplyDelete
  6. Useful information.I am actual blessed to read this article.thanks for giving us this advantageous information.I acknowledge this post.and I would like bookmark this post.Thanks

    devops online training

    aws online training

    data science with python online training

    data science online training

    rpa online training

    ReplyDelete