Abhishek Jadhav
Abhishek Jadhav

Reputation: 129

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

Upvotes: 4

Views: 1082

Answers (1)

user3559349
user3559349

Reputation:

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.

Upvotes: 2

Related Questions