I want extension of the following code for selected value in edit view. take a case of country -> state -> city.
i have script CascadingDropDownList.js:
function bindDropDownList(e, targetDropDownList) { var key = this.value; var allOptions = targetDropDownList.allOptions; var option; var newOption; targetDropDownList.options.length = 0; for (var i=0; i < allOptions.length; i++) { option = allOptions[i]; if (option.key == key) { newOption = new Option(option.text, option.value); targetDropDownList.options.add(newOption); } } }
and I have a helper class:
public static class JavaScriptExtensions { public static string CascadingDropDownList(this HtmlHelper helper, string name, string associatedDropDownList) { var sb = new StringBuilder(); // render select tag sb.AppendFormat('<select name='{0}' id='{0}'></select>', name); sb.AppendLine(); // render data array sb.AppendLine('<script type='text/javascript'>'); var data = (CascadingSelectList)helper.ViewDataContainer.ViewData[name]; var listItems = data.GetListItems(); var colArray = new List<string>(); foreach (var item in listItems) colArray.Add(String.Format('{{key:'{0}',value:'{1}',text:'{2}'}}', item.Key, item.Value, item.Text)); var jsArray = String.Join(',', colArray.ToArray()); sb.AppendFormat('$get('{0}').allOptions=[{1}];', name, jsArray); sb.AppendLine(); sb.AppendFormat('$addHandler($get('{0}'), 'change', Function.createCallback(bindDropDownList, $get('{1}')));', associatedDropDownList, name); sb.AppendLine(); sb.AppendLine('</script>'); return sb.ToString(); } } public class CascadingSelectList { private IEnumerable _items; private string _dataKeyField; private string _dataValueField; private string _dataTextField; public CascadingSelectList(IEnumerable items, string dataKeyField, string dataValueField, string dataTextField) { _items = items; _dataKeyField = dataKeyField; _dataValueField = dataValueField; _dataTextField = dataTextField; } public List<CascadingListItem> GetListItems() { var listItems = new List<CascadingListItem>(); foreach (var item in _items) { var key = DataBinder.GetPropertyValue(item, _dataKeyField).ToString(); var value = DataBinder.GetPropertyValue(item, _dataValueField).ToString(); var text = DataBinder.GetPropertyValue(item, _dataTextField).ToString(); listItems.Add(new CascadingListItem(key, value, text)); } return listItems; } } public class CascadingListItem { public CascadingListItem(string key, string value, string text) { this.Key = key; this.Value = value; this.Text = text; } public string Key { get; set; } public string Value { get; set; } public string Text { get; set; } }
I have achieved it. Where selected value is in Hidden Filed.
And make sure that your controller method returns json object with two fields.
ADDED controller (My url is student/state i.e. in student controller I put following code)
You can return any number of fields but if any of them will have a null value then it will not converted in json object. I am not sure about this but it wasn’t working when I return whole state object. At that time states table was having field called deletedby and it was containing null values!. But when I return only two ‘needed’ fields then it is working properly!