Earlier post we saw, how to do a simple cascaded dop down using ASP.Net AJAX. In this post we will modify that
code to use JSON to pass objects back from server side to client side. (Read more about JSON )here.)
Here is the server side code (explanations inline),
public partial class _Default : System.Web.UI.Page
{
/* This is our entity object. IComparable implementation helps me to
* sort the list of cars using its "Make" property. Also another point to note here is that
* I have used "Automatic Properties" feature of C# 3.0 (More about new features of C# 3.0 in
* a later post :)
*/
class Car : IComparable<Car>
{
public string Make { get; set; }
public string Model { get; set; }
#region IComparable<Car> Members
int IComparable<Car>.CompareTo(Car other)
{
return Make.CompareTo(other.Make);
}
#endregion
}
/* This is the web method we will be calling from our javascript code. WebMethod attribute
* makes it a web service method and ScriptMethod makes it visible to Javascript
*/
[System.Web.Services.WebMethodAttribute(), System.Web.Script.Services.ScriptMethodAttribute()]
public static string GetModelsJSON(string key)
{
/* Next couple of calls are basic setup of data for this, MakeList() creates a list of
* Car objects, SearchModel will get a subset of that list using the key passed from
* client script
*/
List<Car> cars = MakeList();
List<Car> selected = SearchModel(cars, key);
/* Now we create a JSON string that will be sent back to calling JavaScript code.
* Read more on JSON Specification => http://www.json.org/
*/
StringBuilder sb = new StringBuilder();
sb.Append("{\"Models\":[");
foreach (Car car in selected)
{
PropertyInfo[] properties = car.GetType().GetProperties();
sb.Append ("{");
foreach (PropertyInfo p in properties)
{
sb.Append("\""+p.Name+"\"");
sb.Append(":");
sb.Append("\""+p.GetValue(car, null)+"\"");
sb.Append(",");
}
sb.Remove(sb.Length - 1,1);
sb.Append ("},");
}
sb.Remove(sb.Length - 1,1);
sb.Append("]}");
return (sb.ToString());
}
/* Methods I was mentioning earlier on...Search for cars
* This method uses an anonnymous method to delegate FindAll
*/
private static List<Car> SearchModel(List<Car> cars, string key)
{
cars.Sort();
List<Car> selectedCars =
cars.FindAll(
delegate(Car car)
{
return (car.Make == key);
});
return (selectedCars);
}
private static List<Car> MakeList()
{
List<Car> cars = new List<Car>();
Car car = new Car();
car.Make = "BMW";
car.Model = "330 i";
cars.Add(car);
/* Add more cars */
return (cars);
}
/* Set up drop down lists on Page_Load
*/
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Populate "One"
One.Items.Add(new ListItem("BMW", "BMW"));
One.Items.Add(new ListItem("Audi", "Audi"));
One.Items.Add(new ListItem("Honda", "Honda"));
One.Items.Add(new ListItem("Pick One", ""));
One.Items[3].Selected = true;
Two.Items.Add(new ListItem("Pick One", ""));
//add attribute for "One"
One.Attributes.Add("onchange", "return getModels();");
}
}
}
Once this much is done, server side code is complete. Run it at this point.
You will get a client script error when you change the first drop down list..
Adding Javascript code will take care of that... getModels() method is called
each time when you pick a new item from the list. This method calls the web method
and result returned is an JSON string. You can use eval('(' + result + ')') or
Sys.Serialization.JavaScriptSerializer.deserialize(result, true); to invoke Javacript
compiler to convert JSON string to object.
Here is my code for aspx page...
<div>
<asp:ScriptManager ID="sm" runat="server" EnablePageMethods="true" >
</asp:ScriptManager>
<script language="javascript" type="text/javascript" >
//This is the mehod called from first drop downs "onchange" event
function getModels()
{
var makelist = document.getElementById("One");
// get selected car make from dropdown list
var key = makelist.options[makelist.selectedIndex].value;
// call the method on the server and wait till the code
// has completed its execution.
PageMethods.GetModelsJSON(key,OnGetModelsComplete);
}
function OnGetModelsComplete(result)
{
try
{
var o = Sys.Serialization.JavaScriptSerializer.deserialize(result, true);
PopulateModels(o)
}catch(e){}
}
function PopulateModels(o)
{
var models = document.getElementById("Two");
for (var count=models.options.length-1;count > -1; count--)
models.options[count] = null;
var idValue;
var textValue;
var optionItem;
for(i = 0; i < o.Models.length;i++)
{
textValue = o.Models[i].Model;
idValue = o.Models[i].Make;
optionItem = new Option( textValue, idValue, false, false);
models.options[i] = optionItem;
}
}
</script>
<asp:DropDownList ID="One" runat="server">
</asp:DropDownList><br />
<asp:DropDownList ID="Two" runat="server">
</asp:DropDownList>
</div>
0 comments:
Post a Comment