Abhishek Jadhav Abhishek Jadhav - 6 months ago 12
Javascript Question

Ajax call is not binding all model properties

I am going to create table using jquery on the basis of selection in dropdownlist..When I select any option in dropdown the blank table will be generated on the screen..But when i insert values in blank table and press submit then in action I got model but that model consist only properties in the table which I have added from Ajax..But it ignores value of dropdownlist which I have selected first..If I remove that ajax success code then it gives model with proper values but I wont get values in Table created by ajax success....

Here is my ajax code:

$("#Award").change(function () {
var selectdAward = $("#Award").val();
$('#criteriaTable').empty();
var ServiceUrl = "/Nomination/CriteriasForAward?awardId=" + selectdAward;

$.ajax({
type: 'post',
url: ServiceUrl,
contentType: "application/json; charset=utf-8",
error: function (xhr, err) {
alert(xhr.responseText)
},
success: function (data) {
$('#criteriaTable').append('<tr><th>Id</th><th>Criteria-Description</th><th>Comment</th></tr>');

for (var key in data) {
$('#criteriaTable tr:last')
.after('<tr><td><label>' + data[key].Id + '</label></td>'
+ '<td><label>' + data[key].Title + '</label></td>'
+ '<td><input type="text" name=Model.Comments[' + key + '].Comment></td>'
+ '<td><input type="hidden" name=Model.Comments[' + key + '].Id value=' + data[key].Id + '></td></tr>');
}
}
});
});


This is my ViewModel:

public class NominationViewModel
{
public int AwardId { get; set; }
public int ManagerId { get; set; }
public int UserId { get; set; }
public int ProjectID { get; set; }
public string SelectResourcesBy { get; set; } //from project or from department
public IList<CriteriaCommentViewModel> Comments { get; set; }

public NominationViewModel()
{
Comments = new List<CriteriaCommentViewModel>();
}

}


This is navigational property class in view model:

public class CriteriaCommentViewModel
{
public int Id { get; set; }
public string Comment { get; set; }
}


This is the view:

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.Label("Nomination Category", htmlAttributes: new { @class = "control-label col-md-4" })

<div class="col-md-8">
@Html.DropDownListFor(model => model.AwardId, @ViewBag.Awards as SelectList, "Select", new { htmlAttributes = new { @class = "form-control" }, id = "Award" })
@Html.ValidationMessageFor(model => model.AwardId, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.Label("Resource From", htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
<label> @Html.RadioButtonFor(model => model.SelectResourcesBy, "Project", new { htmlAttributes = new { @class = "form-control" } })Project</label>
<label> @Html.RadioButtonFor(model => model.SelectResourcesBy, "Department", new { htmlAttributes = new { @class = "form-control" } })Department</label>
@Html.ValidationMessageFor(model => model.UserId, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.Label("Project", htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.DropDownListFor(model => model.ProjectID, @ViewBag.ProjectsUnderCurrentUser as SelectList, "Select", new { htmlAttributes = new { @class = "form-control" }, id = "SelectedProject" })
@Html.ValidationMessageFor(model => model.ManagerId, "", new { @class = "text-danger" })
</div>
</div>

<div class="form-group">
@Html.Label("Resource Name", htmlAttributes: new { @class = "control-label col-md-4" })
<div class="col-md-8">
@Html.DropDownListFor(model => model.UserId, @ViewBag.Resources as SelectList, "Select", new { htmlAttributes = new { @class = "form-control" }, id = "Resources" })
@Html.ValidationMessageFor(model => model.UserId, "", new { @class = "text-danger" })
</div>
</div>
<br />
<br />
<hr />

<div class="form-group">
@Html.Label("Criteria", htmlAttributes: new { @class = "control-label col-md-2" })
<br />
<div class="form-group">
<div id="Criterias">
<table border="1" id="criteriaTable"></table>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Save Draft" class="btn btn-default" />
<input type="submit" value="Submit" class="btn btn-default" />
<input type="button" value="Cancel" class="btn btn-default" />
</div>
</div>
</div>
}

<div>
@Html.ActionLink("Back to List", "Index")
</div>


And this is the controller action on which i m posting values:

[HttpPost]
public ActionResult AddNomination(NominationViewModel model)
{
return RedirectToAction("Dashboard", "Dashboard");
}


Please suggest the way to solve this problem..Thanks in advance

Answer

Your view model does not contain a property named Model so you need to modify the code for generating the table html to

for (var key in data) {
    $('#criteriaTable tr:last')
        .after('<tr><td><label>' + data[key].Id + '</label></td>' 
        + '<td><label>' + data[key].Title + '</label></td>'
        + '<td><input type="text" name=Comments[' + key + '].Comment></td>'
        + '<td><input type="hidden" name=Comments[' + key + '].Id value=' + data[key].Id + '></td></tr>');
}

i.e. remove the "Model." prefix from the input's name attribute.

Comments