How to persist model data when form post - asp.net-mvc-3

When form is showing initially then I show question and their answer. I show multiple radio button for answer. So user can select only one answer. The problem occurs when I submit my form and action method calls. I saw when form post then answer model is getting null. So guide me how to write code as a result answer model should not be null when form will post.
Here is full code. Please go through the code and if requires changes as a result answer model will not be null when form will be posted to action method.
my ViewModels code
namespace ViewModels
{
public class Question
{
public int ID { set; get; }
public string QuestionText { set; get; }
public List<Answer> Answers { set; get; }
[Required]
public string SelectedAnswer { set; get; }
public Question()
{
Answers = new List<Answer>();
}
}
public class Answer
{
public int ID { set; get; }
public string AnswerText { set; get; }
}
public class Evaluation
{
public List<Question> Questions { set; get; }
public Evaluation()
{
Questions = new List<Question>();
}
}
}
controller code
public ActionResult Index()
{
var evalVM = new Evaluation();
//the below is hardcoded for DEMO. you may get the data from some
//other place and set the questions and answers
var q1 = new Question { ID = 1, QuestionText = "What is your favourite language" };
q1.Answers.Add(new Answer { ID = 12, AnswerText = "PHP" });
q1.Answers.Add(new Answer { ID = 13, AnswerText = "ASP.NET" });
q1.Answers.Add(new Answer { ID = 14, AnswerText = "Java" });
evalVM.Questions.Add(q1);
var q2 = new Question { ID = 2, QuestionText = "What is your favourite DB" };
q2.Answers.Add(new Answer { ID = 16, AnswerText = "SQL Server" });
q2.Answers.Add(new Answer { ID = 17, AnswerText = "MySQL" });
q2.Answers.Add(new Answer { ID = 18, AnswerText = "Oracle" });
evalVM.Questions.Add(q2);
return View(evalVM);
}
[HttpPost]
public ActionResult Index(Evaluation model)
{
if (ModelState.IsValid)
{
foreach (var q in model.Questions)
{
if(q.Answers==null)
{
// Answers is null
}
var qId = q.ID;
var selectedAnswer = q.SelectedAnswer;
// Save the data
}
return RedirectToAction("ThankYou"); //PRG Pattern
}
//reload questions
return View(model);
}
index.cshtml code
#model ViewModels.Evaluation
<h2>Quiz 24</h2>
#using (Html.BeginForm())
{
#Html.EditorFor(x=>x.Questions)
<input type="submit" />
}
and view code which is stored in EditorTemplates folder
#model ViewModels.Question
<div>
#Html.HiddenFor(x=>x.ID)
<h3> #Model.QuestionText </h3>
#foreach (var a in Model.Answers)
{
<p>
#Html.RadioButtonFor(b=>b.SelectedAnswer,a.ID) #a.AnswerText
</p>
}
</div>
the problem is here
[HttpPost]
public ActionResult Index(Evaluation model)
{
if (ModelState.IsValid)
{
foreach (var q in model.Questions)
{
if(q.Answers==null)
{
// Answers is null
}
var qId = q.ID;
var selectedAnswer = q.SelectedAnswer;
// Save the data
}
return RedirectToAction("ThankYou"); //PRG Pattern
}
//reload questions
return View(model);
}
q.Answers==null is getting null when i post the form. i like to know the trick that how to write code in such a way when form will be post to action then Answers should be null.
many guy told me that i need to rebuild the model manually because Answers will be always null. is there any no mechanism in MVC to persist all the data and properly De-serialize it to model when form will be posted.

AnswerText Normally I would recommend using another nested Editor Template for the Answer model, but in this case it will cause issues to properly construct the radio-button group and aftwerwards retrieve the value of SelectedAnswer. As a simple solution I would adapt the Editor Template for Question model in the following way:
<div>
#Html.HiddenFor(x=>x.ID)
<h3> #Model.QuestionText </h3>
<div>
#for (int i = 0; i < Model.Answers.Count; i++)
{
<p>
#Html.RadioButtonFor(model => model.SelectedAnswer, Model.Answers[i].AnswerText #Model.Answers[i].AnswerText
#Html.HiddenFor(model => model.Answers[i].ID)
#Html.HiddenFor(model => model.Answers[i].AnswerText)
</p>
}
</div>
</div>
This will create the following HTML (skipped not-relevant attributes):
<input type="radio" name="Questions[0].SelectedAnswer" ...>
<input type="hidden" name="Questions[0].Answers[0].ID" ...>
<input type="hidden" name="Questions[0].Answers[0].AnswerText" ...>
Output will allow MVC to properly reconstruct the Answer collection.
Update
In your original code you were looking for the Answer.AnswerText, so I've updated the code to include it instead of the Answer.ID.
Hope this helps.

Related

Recommended way to implement array of Ajax cascading dropdown lists in MVC4/Razor?

I am writing an ASP.NET MVC4 / Razor / C# based application that needs to render a grid of records. Each row has several columns, and there may be 100 or so rows.
Each row has a checkbox field, text field and then three cascading dropdown lists. The first dropdown is prepopulated on page load. The second needs to be populated using Ajax on change of the first dropdown list. The third from a change on the second. Each row is separate and does not influence each other.
What is the recommended way to implement something like this? The various solutions for cascading dropdown lists are only for single cascading lists - they do not work (for me) when placed inside a foreach loop.
The skeleton of what I have is shown below:
#model IList<MyModel>
#using (Html.BeginForm("MyAction", "Home")) {
<table><tr><th>Use?</th><th>Name</th><th>List A</th><th>List B</th><th>List C</th></tr>
#Html.EditorForModel()
</table>
}
The model looks something like this:
public class MyModel
{
public bool Use { get; set; }
public string Name { get; set; }
public int? ListAId { get; set; }
public int? ListBId { get; set; }
public int? ListCId { get; set; }
public IList<ListAList> ListA { get; set; }
}
The shared EditorTemplates file MyModel.cshtml follows this structure:
#model MyNamespace.MyModel
<tr>
<td>#Html.CheckBoxFor(model => model.Use)</td>
<td>#Html.DisplayFor(model => model.Name)</td>
<td>#Html.DropDownListFor(model => model.ListAId, new SelectList(Model.ListA, "Id", "Name", Model.ListAId), "")</td>
<td>??</td>
<td>??</td>
</tr>
The ?? indicates I am unsure what to put in here.
How do I proceed to render the ListB select box using Ajax on change of the ListA select box, then on change of ListB render the ListC select box?
check this:
on select change event - Html.DropDownListFor
http://addinit.com/node/19
or
http://www.codeproject.com/Articles/258172/Simple-Implementation-of-MVC-Cascading-Ajax-Drop-D
Update1: Suppose that there is Name ROWID, (and list all the same data source).
Update2: the example available on github
Based on these responses:
How to populate a #html.dropdownlist mvc helper using JSon
Populate a <select></select> box with another
Model:
using System.Collections.Generic;
namespace MyNamespace
{
public class MyModel
{
public MyModel() { ListA = new List<ListAList>(); }
public bool Use { get; set; }
public string Name { get; set; }
public int? ListAId { get; set; }
public int? ListBId { get; set; }
public int? ListCId { get; set; }
public IList<ListAList> ListA { get; set; }
}
public class ListAList
{
public int Id { get; set; }
public string Name { get; set; }
}
}
Main action in the Home Controller:
public ViewResult MyAction()
{
var model = new List<MyModel>();
for (int i = 0; i < 10; i++)
{
var item = new MyModel()
{
Name = string.Format("Name{0}", i),
Use = (i % 2 == 0),
ListAId = null,
ListBId = null,
ListCId = null
};
for (int j = 0; j < 10; j++)
{
item.ListA.Add( new ListAList()
{
Id=j,
Name = string.Format("Name {0}-{1}",i,j)
});
}
model.Add(item);
}
return View(model);
}
Data source provider in the Home controller:
public JsonResult PopulateOption(int? listid, string name)
{
//todo: preparing the data source filter
var sites = new[]
{
new { id = "1", name = "Name 1" },
new { id = "2", name = "Name 2" },
new { id = "3", name = "Name 3" },
};
return Json(sites, JsonRequestBehavior.AllowGet);
}
EditorTemplate:
#model MyNamespace.MyModel
<tr>
<td>#Html.CheckBoxFor(model => model.Use)</td>
<td>#Html.DisplayFor(model => model.Name)</td>
<td>#Html.DropDownListFor(model => model.ListAId, new SelectList(Model.ListA, "Id", "Name", Model.ListAId), "", new { #id = string.Format("ListA{0}", Model.Name), #class="ajaxlistA" })</td>
<td><select class="ajaxlistB" id="ListB#(Model.Name)"></select></td>
<td><select class="ajaxlistC" id="ListC#(Model.Name)"></select></td>
</tr>
And the main view with Ajax functions:
#using MyNamespace
#model IList<MyModel>
#using (Html.BeginForm("MyAction", "Home")) {
<table><tr><th>Use?</th><th>Name</th><th>List A</th><th>List B</th><th>List C</th></tr>
#Html.EditorForModel()
</table>
}
<script src="#Url.Content("~/Scripts/jquery-1.7.1.js")" type="text/javascript"></script>
<script>
$(document).ready( $(function () {
$('.ajaxlistA').change(function () {
// when the value of the first select changes trigger an ajax request
list = $(this);
var listvalue = list.val();
var listname = list.attr('id');
$.getJSON('#Url.Action("PopulateOption", "Home")', { listid: listvalue, name: listname }, function (result) {
// assuming the server returned json update the contents of the
// second selectbox
var listB = $('#' + listname).parent().parent().find('.ajaxlistB');
listB.empty();
$.each(result, function (index, item) {
listB.append(
$('<option/>', {
value: item.id,
text: item.name
})
);
});
});
});
$('.ajaxlistB').change(function () {
// when the value of the first select changes trigger an ajax request
list = $(this);
var listvalue = list.val();
var listname = list.attr('id');
$.getJSON('#Url.Action("PopulateOption", "Home")', { listid: listvalue, name: listname }, function (result) {
// assuming the server returned json update the contents of the
// second selectbox
var listB = $('#' + listname).parent().parent().find('.ajaxlistC');
listB.empty();
$.each(result, function (index, item) {
listB.append(
$('<option/>', {
value: item.id,
text: item.name
})
);
});
});
});
}));
</script>
And the result:

Simple Ajax in asp.net MVC 3, update the model and rerender part

I come from a more WPF application background and I'm used to bindings and such. Jumping into websites then can come with it's problems as they work so much more differently.
I'm trying to do a simple Ajax action but not sure where to begin. Basically I want to make a dropdownlist that changes one property on the model and re-renders that part of the page. Perhaps this is too much of a WPF way to do this so my Model could be twisted for the thing it is supposed to do.
Here is what I got already:
public class TheViewModel
{
private IEnumerable<TheData> _data;
public TheViewModel(IEnumerable<TheData> data)
{
_data = data;
Year = 2012;
}
public int Year { get; set; }
public ICollection<TheData> Data
{
get
{
return _data.Where(d => d.Year == this.Year).ToList();
}
}
public IEnumerable<SelectListItem> YearList
{
// lists the available years
}
}
public class TheData
{
public int Year { get; set; }
//Some more info I want to represent in Table
}
And the razor:
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "thetable" }))
{
#Html.DropDownListFor(model => model.Year, Model.YearList, new { AutoPostBack = "true"})
<input type="submit" name="name" value="Submit" />
}
<table id="thetable">
<thead>
//some headers
</thead>
<tbody>
#foreach ( var item in Model.Data)
{
//row for each data
}
</tbody>
</table>
As you can see I'm hoping for the Year property to be updated and a new call to be made for the Data property which would result in new information. That information would be rendered in thetable Table
Here's a full example.
Model:
public class MyViewModel
{
public int Year { get; set; }
public IEnumerable<SelectListItem> Years
{
get
{
return Enumerable.Range(1980, 40).Select(x => new SelectListItem
{
Value = x.ToString(),
Text = x.ToString()
});
}
}
public IList<TheData> Data { get; set; }
}
public class TheData
{
public int Year { get; set; }
public string Foo { get; set; }
public string Bar { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(int year)
{
var model = new[]
{
new TheData { Year = year, Foo = "foo 1", Bar = "bar 1" },
new TheData { Year = year, Foo = "foo 2", Bar = "bar 2" },
new TheData { Year = year, Foo = "foo 3", Bar = "bar 3" },
};
return PartialView("_data", model);
}
}
Index.cshtml view:
#model MyViewModel
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$('#yearsddl').change(function () {
$(this).closest('form').trigger('submit');
});
});
</script>
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "data" }))
{
#Html.DropDownListFor(x => x.Year, Model.Years, new { id = "yearsddl" })
}
<table>
<thead>
<tr>
<th>Year</th>
<th>Foo</th>
<th>Bar</th>
</tr>
</thead>
<tbody id="data">
#Html.Partial("_data", Model.Data ?? Enumerable.Empty<TheData>())
</tbody>
</table>
The jquery.unobtrusive-ajax.js script inclusion should be moved out of the index view inside the layout for example and the custom js that subscribes for the change event of the dropdownlist should be moved into a separate js file and included from the Layout. I just put them here to illustrate a full example of what's required for the view to work.
_Data.cshtml partial:
#model IList<TheData>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Html.DisplayFor(x => x[i].Year)</td>
<td>#Html.DisplayFor(x => x[i].Foo)</td>
<td>#Html.DisplayFor(x => x[i].Bar)</td>
</tr>
}

MVC3- Radion Button Grouping and Binding from database

How to get the radio button options from database using in MVC3 Razor. I have 4 options for each question, the options should be populated from the database and should be grouped.
#Html.RadioButtonFor(model => Model.AAAa, 'Y', new { title = "Please check this if AAA has been updated" })
Yes
This gives me hard coded value as Yes but text needs to be populated with DB Table.
How would I bind it back the selected value back to the database?. An Example would be more helpful.
Thank you
As always you start by defining a view model that will represent the information you will be dealing with in the view:
public class MyViewModel
{
public string SelectedValue { get; set; }
// In your question you seem to be dealing with a title attribute as well
// If this is the case you could define a custom view model ItemViewModel
// which will contain the Value, the Text and the Title properties for
// each radio button because the built-in SelectListItem class that I am using here
// has only Value and Text properties
public SelectListItem[] Items { get; set; }
}
then you write a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
// Obviously those will come from your database or something
Items = new[]
{
new SelectListItem { Value = "Y", Text = "Yes" },
new SelectListItem { Value = "N", Text = "No" },
new SelectListItem { Value = "D", Text = "Dunno" }
}
};
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
then a corresponding view:
#model MyViewModel
#using (Html.BeginForm())
{
for (int i = 0; i < Model.Items.Count; i++)
{
#Html.RadioButtonFor(x => x.SelectedValue, Model.Items[i].Value, new { id = "item_" + i })
#Html.Label("item_" + i, Model.Items[i].Text)
<br/>
}
<button type="submit">OK</button>
}
or to make the view less messy you could write a custom HTML helper that will render those radio buttons for you:
public static class HtmlExtensions
{
public static IHtmlString RadioButtonListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> items
)
{
var sb = new StringBuilder();
var i = 0;
foreach (var item in items)
{
var id = string.Format("item{0}", i++);
var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = id });
var label = htmlHelper.Label(id, item.Text);
sb.AppendFormat("{0}{1}<br/>", radio, label);
}
return new HtmlString(sb.ToString());
}
}
and now your view will simply become:
#model MyViewModel
#using (Html.BeginForm())
{
#Html.RadioButtonListFor(x => x.SelectedValue, Model.Items)
<button type="submit">OK</button>
}
which obviously is nicer to look.

Populating child drop down based on what was selected from parent drop down list

I am using the latest version of jQuery and ASP.NET MVC 3 with the Razor view engine.
I have tried Google looking for a decent example of loading a child drop down list when a parent drop down item is selected. I am looking to do this via jQuery AJAX using JSON. My knowledge of this is zero.
I have a Category class with a list of categories. It's a parent-child association.
If I select a category from the parent drop down list, then all the child categories need to be listed in the child drop down list for the selected parent category.
This is what I currently have, but need to complete it, not sure if I am in the right direction:
$(document).ready(function () {
$('#ddlParentCategories').change(function () {
alert('changed');
});
});
I loaded my drop down list from my view model as such:
#Html.DropDownListFor(x => x.ParentCategoryId, new SelectList(Model.ParentCategories, "Id", "Name", Model.ParentCategoryId), "-- Select --", new { id = "ddlParentCategories" })
The first item has text "-- Select --" (for both parent and child drop down lists). On initial page load nothing must be loaded in the child drop down list. When a value is selected then the child drop down list must be populated. And when "-- Select --" is selected again in the parent drop down list then all the items in the child drop down list must cleared except "-- Select --".
If possible, if the child categories is loading, how do I display that "round" loading icon?
UPDATE
I have updated my code to Darin's code, and I cannot get it to work properly:
Category class:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string MetaKeywords { get; set; }
public string MetaDescription { get; set; }
public bool IsActive { get; set; }
public int? ParentCategoryId { get; set; }
public virtual Category ParentCategory { get; set; }
public virtual ICollection<Category> ChildCategories { get; set; }
}
EditProductViewModel class:
public class EditProductViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string ShortDescription { get; set; }
public string LongDescription { get; set; }
public bool IsActive { get; set; }
public string PageTitle { get; set; }
public bool OverridePageTitle { get; set; }
public string MetaKeywords { get; set; }
public string MetaDescription { get; set; }
public int ParentCategoryId { get; set; }
public IEnumerable<Category> ParentCategories { get; set; }
public int ChildCategoryId { get; set; }
public IEnumerable<Category> ChildCategories { get; set; }
}
ProductController class:
public ActionResult Create()
{
EditProductViewModel viewModel = new EditProductViewModel
{
ParentCategories = categoryService.GetParentCategories()
.Where(x => x.IsActive)
.OrderBy(x => x.Name),
ChildCategories = Enumerable.Empty<Category>(),
IsActive = true
};
return View(viewModel);
}
public ActionResult AjaxBindingChildCategories(int parentCategoryId)
{
IEnumerable<Category> childCategoryList = categoryService.GetChildCategoriesByParentCategoryId(parentCategoryId);
return Json(childCategoryList, JsonRequestBehavior.AllowGet);
}
Create view:
<tr>
<td><label>Parent Category:</label> <span class="red">*</span></td>
<td>#Html.DropDownListFor(x => x.ParentCategoryId,
new SelectList(Model.ParentCategories, "Id", "Name", Model.ParentCategoryId),
"-- Select --",
new { data_url = Url.Action("AjaxBindingChildCategories"), id = "ParentCategories" }
)
#Html.ValidationMessageFor(x => x.ParentCategoryId)
</td>
</tr>
<tr>
<td><label>Child Category:</label> <span class="red">*</span></td>
<td>#Html.DropDownListFor(x => x.ChildCategoryId,
new SelectList(Model.ChildCategories, "Id", "Name", Model.ChildCategoryId),
"-- Select --",
new { id = "ChildCategories" }
)
#Html.ValidationMessageFor(x => x.ChildCategoryId)
</td>
</tr>
<script type="text/javascript">
$(document).ready(function () {
$('#ParentCategories').change(function () {
var url = $(this).data('url');
var data = { parentCategoryId: $(this).val() };
$.getJSON(url, data, function (childCategories) {
var childCategoriesDdl = $('#ChildCategories');
childCategoriesDdl.empty();
$.each(childCategories, function (index, childCategory) {
childCategoriesDdl.append($('<option/>', {
value: childCategory, text: childCategory
}));
});
});
});
});
</script>
It goes into my AjaxBindingChildCategories action and it brings back records, it just doesn't want to display my child category dropdownlist. I had a look in Fire Bug and the error that I get is:
GET AjaxBindingChildCategories?parentCategoryId=1
500 Internal Server Error
Here's an example of cascading drop down lists. As always start by defining a view model:
public class MyViewModel
{
[DisplayName("Country")]
[Required]
public string CountryCode { get; set; }
public IEnumerable<SelectListItem> Countries { get; set; }
public string City { get; set; }
public IEnumerable<SelectListItem> Cities { get; set; }
}
then a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
// TODO: Fetch countries from somewhere
Countries = new[]
{
new SelectListItem { Value = "FR", Text = "France" },
new SelectListItem { Value = "US", Text = "USA" },
},
// initially we set the cities ddl to empty
Cities = Enumerable.Empty<SelectListItem>()
};
return View(model);
}
public ActionResult Cities(string countryCode)
{
// TODO: based on the selected country return the cities:
var cities = new[]
{
"Paris", "Marseille", "Lyon"
};
return Json(cities, JsonRequestBehavior.AllowGet);
}
}
a view:
#model MyViewModel
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(x => x.CountryCode)
#Html.DropDownListFor(
x => x.CountryCode,
Model.Countries,
"-- Select country --",
new { data_url = Url.Action("cities") }
)
#Html.ValidationMessageFor(x => x.CountryCode)
</div>
<div>
#Html.LabelFor(x => x.City)
#Html.DropDownListFor(
x => x.City,
Model.Cities,
"-- Select city --"
)
#Html.ValidationMessageFor(x => x.City)
</div>
<p><input type="submit" value="OK" /></p>
}
and finally the unobtrusive javascript in a separate file:
$(function () {
$('#CountryCode').change(function () {
var url = $(this).data('url');
var data = { countryCode: $(this).val() };
$.getJSON(url, data, function (cities) {
var citiesDdl = $('#City');
citiesDdl.empty();
$.each(cities, function (index, city) {
citiesDdl.append($('<option/>', {
value: city,
text: city
}));
});
});
});
});
jQuery script will look like this:
<script type="text/javascript">
function getCities(abbr) {
$.ajax({
url: "#Url.Action("Cities", "Locations")",
data: {abbreviation: abbr},
dataType: "json",
type: "POST",
error: function() {
alert("An error occurred.");
},
success: function(data) {
var items = "";
$.each(data, function(i, item) {
items += "<option value=\"" + item.Value + "\">" + item.Text + "</option>";
});
$("#City").html(items);
}
});
}
$(document).ready(function(){
$("#State").change(function() {
var abbr = $("#State").val();
getCities(abbr);
});
});
</script>
A repository to retrieve data could look like this (obviously hook it up to live data though):
public class LocationRepository : ILocationRepository
{
public IQueryable<State> GetStates()
{
return new List<State>
{
new State { Abbreviation = "NE", Name = "Nebraska" },
new State { Abbreviation = "NC", Name = "North Carolina" }
}.AsQueryable();
}
public IQueryable<City> GetCities(string abbreviation)
{
var cities = new List<City>();
if (abbreviation == "NE")
{
cities.AddRange(new List<City> {
new City { Id = 1, Name = "Omaha" },
new City { Id = 2, Name = "Lincoln" }
});
}
else if (abbreviation == "NC")
{
cities.AddRange(new List<City> {
new City { Id = 3, Name = "Charlotte" },
new City { Id = 4, Name = "Raleigh" }
});
}
return cities.AsQueryable();
}
}
public interface ILocationRepository
{
IQueryable<State> GetStates();
IQueryable<City> GetCities(string abbreviation);
}
Controllers could look like this:
public class LocationsController : Controller
{
private ILocationRepository locationRepository = new LocationRepository();
[HttpPost]
public ActionResult States()
{
var states = locationRepository.GetStates();
return Json(new SelectList(state, "Id", "Name"));
}
[HttpPost]
public ActionResult Cities(string abbreviation)
{
var cities = locationRepository.GetCities(abbreviation);
return Json(new SelectList(cities, "Abbreviation", "Name"));
}
}
I am assuming you populate the parent dropdown from server side and also the first option in this parent dd is "--- Select ---"
You can try this
$(document).ready(function () {
var $parent = $('#ddlParentCategories');
var $child = $('#ddlChildCategories');
$child.find("option:gt(0)").remove();
if(!$parent.children().eq(0).is(":selected")){
$parent.change(function () {
$.ajax({
url: "urlToFetchTheChild",
data: { categoryId: this.value },
success: function(data){
//The data you send should be a well formed array of json object containing code/value pair of child categories
for(var i = 0;i<data.length;i++){
$child.append("<option value='"+ data[i].code +"'>"+ data[i].value +"</option>");
}
}
});
});
}
});

CheckboxList in MVC3.0

How can I create a checkboxList in asp.net MVC and then to handle the event with the checkboxList
You could have a view model:
public class MyViewModel
{
public int Id { get; set; }
public bool IsChecked { get; set; }
}
A controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new[]
{
new MyViewModel { Id = 1, IsChecked = false },
new MyViewModel { Id = 2, IsChecked = true },
new MyViewModel { Id = 3, IsChecked = false },
};
return View(model);
}
[HttpPost]
public ActionResult Index(IEnumerable<MyViewModel> model)
{
// TODO: Handle the user selection here
...
}
}
A View (~/Views/Home/Index.cshtml):
#model IEnumerable<AppName.Models.MyViewModel>
#{
ViewBag.Title = "Home Page";
}
#using (Html.BeginForm())
{
#Html.EditorForModel()
<input type="submit" value="OK" />
}
and the corresponding Editor template (~/Views/Home/EditorTemplates/MyViewModel.cshtml):
#model AppName.Models.MyViewModel
#Html.HiddenFor(x => x.Id)
#Html.CheckBoxFor(x => x.IsChecked)
Now when you submit the form you would get a list of values and for each value whether it is checked or not.
There is even simpler way - use custom #Html.CheckBoxList() extension from here:
http://www.codeproject.com/KB/user-controls/MvcCheckBoxList_Extension.aspx
Usage example (MVC3 view with Razor view engine):
#Html.CheckBoxList("NAME", // NAME of checkbox list
x => x.DataList, // data source (list of 'DataList' in this case)
x => x.Id, // field from data source to be used for checkbox VALUE
x => x.Name, // field from data source to be used for checkbox TEXT
x => x.DataListChecked // selected data (list of selected 'DataList' in thiscase),
// must be of same data type as source data or set to 'NULL'
)

Resources