Introduction
Hi every one today i am going to write an article on how to use Ajax cascading drop down list with in the grid using a web services.Cascading drop down list help us to save the post-back of a page and Each time ,When the selection of parent Drop-Down List controls
changes,It makes a call to a specified web service to retrieve the list of
values for the next Drop-Down List in the set.
Earlier we used the Ajax and java-script to achieve this kind of tasks , But now the same functionality is available in Ajax control-toolkit control named as Cascading Drop-down control. This article covers the following points:
- Ajax Cascading drop-down list binding inside the grid.
- How to set the properties of cascading control.
- After the page load.How to rebind it.
Background
You can also follow this Cascading-Dropdownlist to know the basic feature and the basic properties of this control.Some of the feature list given below:
- TargetControlID - The ID of the Drop-Down List to populate.
- Category - The name of the category this Drop-Down List represents.
- PromptText - Optional text to display before the user has selected a
value from the DropDownList.
- PromptValue - Optional value set when Prompt-text is displayed.
- EmptyText - Optional text to display when the Drop-Down List has no
data to display.
- EmptyValue - Optional value set when Empty-text is displayed.
- LoadingText - Optional text to display while the data for the
Drop-Down List is being loaded.
- ServicePath - Path to a web service that returns the data used to
populate the Drop-DownList. This property should be left null if ServiceMethod
refers to a page method. The web service should be decorated with the
System.Web.Script.Services.ScriptService attribute.
- ServiceMethod - Web service method that returns the data used to
populate the DropDownList.
- ContextKey - User/page specific context provided to an
optional overload of the web method described by ServiceMethod/ServicePath. If
the context key is used, it should have the same signature with an additional
parameter named contextKey of type string.
- UseContextKey - Whether or not the ContextKey property should be
used. This will be automatically enabled if the ContextKey property is ever set
(on either the client or the server).
- ParentControlID - Optional ID of the parent DropDownList that
controls the contents of this DropDownList.
- SelectedValue - Optional value to select by default. This needs to
exactly match the string representation of a value in the DropDownList.
Using the code
I am going to create a grid view control on my web page.I have placed two
drop-downlist and two cascading control inside my grid.
Client Side Code:
<asp:GridView GridLines="Vertical" ID="grdDemo" runat="server" AutoGenerateColumns="False"
BackColor="White" BorderColor="#DEDFDE" BorderStyle="None" BorderWidth="1px"
CellPadding="4" ForeColor="Black" OnRowDataBound="grdDemo_RowDataBound" OnRowDeleting="grdDemo_RowDeleting">
<EmptyDataTemplate>
<div>
No record found</div>
</EmptyDataTemplate>
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:TemplateField HeaderText="Brand Name">
<ItemTemplate>
<asp:DropDownList ID="ddlBrand" runat="server" Font-Size="9" Width="130">
</asp:DropDownList>
<ajaxToolKit:CascadingDropDown UseContextKey="true" ContextKey='<%# Bind("BrandId") %>'
ID="ccdRegion" runat="server" Category="BrandName" TargetControlID="ddlBrand"
ServiceMethod="GetAllCarBrand" ServicePath="~/WebService/CarService.asmx">
</ajaxToolKit:CascadingDropDown>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Model Name">
<ItemTemplate>
<asp:DropDownList ID="ddlModelName" runat="server" Font-Size="9" Width="130">
</asp:DropDownList>
<ajaxToolKit:CascadingDropDown UseContextKey="true" ContextKey='<%# Bind("ModelId") %>'
ID="ccdDistrict" runat="server" Category="Model" ParentControlID="ddlBrand" TargetControlID="ddlModelName"
ServiceMethod="GetAllModelByBrand" ServicePath="~/WebService/CarService.asmx">
</ajaxToolKit:CascadingDropDown>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="BtnAdd" Text="Add" runat="server" OnClick="BtnAdd_Click" />
<asp:Button ID="BtnDelete" Visible="false" Text="Delete" CommandName="Delete" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#CCCC99" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
<RowStyle BackColor="#F7F7DE" />
<SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#FBFBF2" />
<SortedAscendingHeaderStyle BackColor="#848384" />
<SortedDescendingCellStyle BackColor="#EAEAD3" />
<SortedDescendingHeaderStyle BackColor="#575357" />
</asp:GridView>
After Creating the grid on client-side page.I am going to create a web service named as CarService.asmx . Inside this web service ,I have created two method to bind
those drop-down list control named as GetAllCarBrand and
GetAllModelByBrand.
Those methods returns the array of
CascadingDropDownName Value class provided by Ajax Control-toolkit
Library. The list of car brand name and on the basis of those brand it will
return the car model name , Like Maruti is a brand name and swift is a car model.I
have used constant value to fill my list.In a web service method three
parameters should be defined.
- Category : The name of the category that represents the dropdownlist.
- KnownCategoryValues: This parameter will return a string containing
the currently selected category values, as well as the category to retrieve values
for.So that we can easily find out the value of parent
dropdownlist.
- Context key:It is used to bind the selected value of that
DropdownList.You can use this
context key to rebind the already selected value of dropdownlist.
Web Service code is given below:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[System.Web.Script.Services.ScriptService]
public class <var> CarService </var>: System.Web.Services.WebService
{
#region Public Member Declare Here
private List<CascadingDropDownNameValue> ListCascading;
#endregion
[WebMethod]
public CascadingDropDownNameValue[] GetAllCarBrand(string knownCategoryValues, string category, string contextKey)
{
try
{
ListCascading = new List<CascadingDropDownNameValue>();
List<CarBrand> LstBrand = new List<CarBrand>();
LstBrand.Add(new CarBrand() { BrandId = 1, BrandName = "BMW" });
LstBrand.Add(new CarBrand() { BrandId = 2, BrandName = "Maruti" });
LstBrand.Add(new CarBrand() { BrandId = 3, BrandName = "Audi" });
LstBrand.Add(new CarBrand() { BrandId = 4, BrandName = "Ford" });
foreach (var item in LstBrand)
{
string brandId = item.BrandId.ToString();
string brandName = item.BrandName;
ListCascading.Add(new CascadingDropDownNameValue(brandName, brandId));
}
CascadingDropDownNameValue selectedVal = (from x in ListCascading where x.value == contextKey select x).FirstOrDefault();
if (selectedVal != null)
selectedVal.isDefaultValue = true;
return ListCascading.ToArray();
}
catch (SoapException)
{
throw;
}
catch (Exception)
{
throw;
}
}
[WebMethod]
public CascadingDropDownNameValue[] GetAllModelByBrand(string knownCategoryValues, string category, string contextKey)
{
try
{
ListCascading = new List<CascadingDropDownNameValue>();
StringDictionary brandDetails = AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
var brandId = Convert.ToInt64(brandDetails["BrandName"]);
var LstOfCarModel = GetListOfModel().Where(u=>u.BrandId == brandId) ;
foreach (var item in LstOfCarModel)
{
string modelId = item.ModelId.ToString();
string modelName = item.CarName;
ListCascading.Add(new CascadingDropDownNameValue(modelName, modelId));
}
CascadingDropDownNameValue selectedVal = (from x in ListCascading where x.value == contextKey select x).FirstOrDefault();
if (selectedVal != null)
selectedVal.isDefaultValue = true;
return ListCascading.ToArray();
}
catch (SoapException)
{
throw;
}
catch (Exception)
{
throw;
}
}
GetAllCarBrand return the list of mulitiple car brands and method name GetAllModelByBrand return the cars model on the basis of their brand.
After creating the web service set properties of your's cascading drop-down list inside a grid.I have done those things in my client code.
The CascadingDropDown class has a helper method for unpacking the category values: <span style="color: teal; font-family: "Courier New"; font-size: 10pt;"></span><span style="font-family: "Courier New"; font-size: 10pt;"></span>
StringDictionary brandDetails = AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);
This method will return a StringDictionary containing the name/value pairs of the
currently selected values.
Here is my C# Class ,This class contains a method for bind a grid from a list of cars model named as CarList.I have also used grdDemo_RowDeleting event to delete the grid row and grdDemo_RowDataBound event to maintain the add and delete in very row of gridview control.
public partial class Default : System.Web.UI.Page
{
#region Define Member Variable Here
static List<CarList> Staticlist;
#endregion
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindGrid();
}
}
private void BindGrid()
{
if (Staticlist == null)
{
Staticlist = new List<CarList>();
Staticlist.Add(new CarList());
}
grdDemo.DataSource = Staticlist;
grdDemo.DataBind();
}
protected void BtnAdd_Click(object sender, EventArgs e)
{
FillExistingValue();
Staticlist.Add(new CarList());
BindGrid();
}
private void FillExistingValue()
{
for (int i = 0; i < grdDemo.Rows.Count; i++)
{
Staticlist[i].BrandId = Convert.ToInt32(((DropDownList)grdDemo.Rows[i].FindControl("ddlBrand")).SelectedItem.Value);
Staticlist[i].ModelId = Convert.ToInt32(((DropDownList)grdDemo.Rows[i].FindControl("ddlModelName")).SelectedItem.Value);
}
}
protected void grdDemo_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
Staticlist.RemoveAt(e.RowIndex);
BindGrid();
}
protected void grdDemo_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var BtnAdd = ((Button)e.Row.FindControl("BtnAdd"));
var BtnDel = ((Button)e.Row.FindControl("BtnDelete"));
if (e.Row.RowIndex == Staticlist.Count - 1)
{
BtnAdd.Visible = true;
BtnDel.Visible = false;
}
else
{
BtnAdd.Visible = false;
BtnDel.Visible = true;
}
}
}
}
I hope this article will help you guys a lot.I am going attach the whole code with this article. Final view of my demo grid is given below.
Points of Interest
This is a very good feature provided by a Ajax Control Toolkit.First, I tried the same thing with Jquery , It's a bit diffcult to handle the client side and server side in jquery you will lost the client side values after the page postback .You have to write a lot of client side code to maintain these kinds of situation. This control minimize the code as well as provide a more flexibility to handle yours page postbacks and events like, I have in my demo grid Add and Delete buttons.
Conclusion
For more details of the source code, please download the source code
from the link at the top of this article. The source code is easy and
well commented.
Hope this tutorial is useful .