Search code examples
jqueryasp.net-mvcknockout.jsknockout-mapping-plugin

knockout data grid not updating


I have created a page for populating data which is working fine .Now I have a button & on the click i open a form in a dialog .Now problem is that when i click on save the data is saved but the grid is not updating.Please help me in this..

Below is my Js Code for binding the grid with model.

    var EmpViewModel = function () {
    //Make the self as 'this' reference
    var self = this;

    //Declare observable which will be bind with UI 
    self.EmpCode = ko.observable("0");
    self.EmpName = ko.observable("");
    self.ContactNo = ko.observable("");
    self.MartialStatus = ko.observable("");
    self.Email = ko.observable("");

    //The Object which stored data entered in the observables
    var EmpData = {
        EmpCode: self.EmpCode,
        EmpName: self.EmpName,
        ContactNo: self.ContactNo,
        MartialStatus: self.MartialStatus,
        Email: self.Email
    };



    //Declare an ObservableArray for Storing the JSON Response
    self.Employees = ko.observableArray([]);
    GetEmployees();
    debugger
    this.addNewEmp = function () {
        $.ajax({
            type: "POST",
            url: '/Employee/Exercise4',
            contentType: 'application/json',
            dataType: 'html',
            success: function (data) {
                $('#InnerDialogBox').html(data);
                $("#OuterDialogBox").dialog({
                    title: 'Add New Employee',
                    height: 600,
                    width: 600,
                    modal: true,
                    buttons: [
                        {
                            text: "Close",
                            click: function () {
                                $.unblockUI();
                                $(this).dialog("close");
                            }
                        }]
                });
            },
            error: function () {
                alert('error');
            },
            complete: function () {

            }
        });
    }

    //Function to perform DELETE Operation
    self.deleterec = function (employee) {
        $("#InnerConfirmmBoxDel").dialog({
            title: 'Are You Sure You want to delete this record ?',
            buttons: {
                "Confirm": function () {
                    var dialog = $(this);
                    $.ajax({
                        type: "POST",
                        url: "/Employee/DeleteEmployee?EmpCode=" + employee.EmpCode,
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        success: function (data) {
                            dialog.dialog("close");
                            GetEmployees();
                        },
                        error: function (error) {
                            dialog.dialog("close");
                            alert(error.status + "<--and--> " + error.statusText);
                        }
                    });
                },
                "Cancel": function () {
                    $(this).dialog("close");
                }
            }
        });
    };
    function GetEmployees() {
        $.ajax({
            type: "POST",
            url: "/Employee/GetAllEmployees",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                debugger
                self.Employees(data.Data); //Put the response in ObservableArray
            },
            error: function (error) {
                alert(error.status + "<--and--> " + error.statusText);
            }
        });
        //Ends Here
    }
};

ko.applyBindings(new EmpViewModel());   

Logic to save the data

$(document).ready(function () {
$("#btnSave").live('click', function (e) {
    e.preventDefault();
    var form = $('form');
    debugger;
    if (form.valid()) {
        Save();
    }
 });
});
function Save() {
var ob = new Object();
ob.EmpName = $("#EmpName").val();
ob.EmpCode = $("#EmpCode").val();
ob.DOB = $("#DOB").val();
ob.Age = $("#Age").val();
ob.ContactNo = $("#ContactNo").val();
ob.Email = $("#Email").val();
ob.Address = $("#Address").val();
ob.City = $("#City").val();
ob.IsEmpRefrence = $("#EmpRef").is(':checked');
var selectedVal = "";
var selected = $("input[type='radio'][name='MartialStatus']:checked");
if (selected.length > 0) {
    selectedVal = selected.val();
}
ob.MartialStatus = selectedVal;
var param = { 'emp': ob };
$.ajax({
    type: "POST",
    url: '/Employee/SaveNewEmployee',
    data: JSON.stringify(param),
    contentType: 'application/json',
    dataType: 'json',
    success: function (data) {
        $("#OuterDialogBox").dialog("close");
        debugger
        ko.applyBindings(new EmpViewModel());


    },
    error: function () {
        alert('error');
    }
});

}

HTML for Grid Data

 <table cellspacing="0" cellpadding="5" width="100%">
    <thead>
        <tr>
            <td>
                <b>Employee Code</b>
            </td>
            <td>
                <b>Employee Name</b>
            </td>
            <td>
                <b>Contact Number</b>
            </td>
            <td>
                <b>Martial Status</b>
            </td>
            <td>
                <b>Email</b>
            </td>
            <td>
            </td>
            <td>
            </td>
        </tr>
    </thead>
    <tbody data-bind="foreach:Employees">
        <tr>
            <td data-bind="text:EmpCode">
            </td>
            <td data-bind="text:EmpName">
            </td>
            <td data-bind="text:ContactNo">
            </td>
            <td data-bind="css:    {UnMarried:MartialStatus!='Married',Married:MartialStatus=='Married'}">
            </td>
            <td data-bind="text:Email">
            </td>
            <td>
                <a class="updateEmp" style="cursor: pointer">Edit</a> |
            </td>
            <td>                  
                <button data-bind="click: $root.deleterec">
                    Delete</button>
            </td>
        </tr>
    </tbody>
</table>

Html for New Employee Form

  <table cellpadding="5">
    <tr>
        <td align="right">
            <b>Name</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.TextBoxFor(x => x.EmpName)
        </td>
        <td style="width: 100px;">
            @Html.ValidationMessageFor(x => x.EmpName)
        </td>
    </tr>
    <tr>
        <td align="right">
            <b>Emp#</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.TextBoxFor(x => x.EmpCode)
        </td>
        <td>
            @Html.ValidationMessageFor(x => x.EmpCode)
        </td>
    </tr>
    <tr>
        <td align="right">
            <b>Date of Birth</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.TextBox("DOB")
        </td>
        <td>
            @Html.ValidationMessageFor(x => x.DOB)
        </td>
    </tr>
    <tr>
        <td align="right">
            <b>Age</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.TextBoxFor(x => x.Age)
        </td>
        <td>
            @Html.ValidationMessageFor(x => x.Age)
        </td>
    </tr>
    <tr>
        <td align="right">
            <b>Contact Number</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.TextBoxFor(x => x.ContactNo)
        </td>
        <td>
            @Html.ValidationMessageFor(x => x.ContactNo)
        </td>
    </tr>
    <tr>
        <td align="right">
            <b>Email</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.TextBoxFor(x => x.Email)
        </td>
        <td>
            @Html.ValidationMessageFor(x => x.Email)
        </td>
    </tr>
    <tr>
        <td align="right">
            <b>Address</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.TextAreaFor(x => x.Address)
        </td>
        <td>
            @Html.ValidationMessageFor(x => x.Address)
        </td>
    </tr>
    <tr>
        <td align="right">
            <b>City</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.DropDownListFor(x => x.City, (SelectList)(ViewData["CityLst"]))
        </td>
        <td>
        </td>
    </tr>
    <tr>
        <td align="right">
            <b>Martial Status</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.RadioButtonFor(model => model.MartialStatus, "Married") Married
            @Html.RadioButtonFor(model => model.MartialStatus, "UnMarried") UnMarried
        </td>
        <td>
        </td>
    </tr>
    <tr>
        <td align="right">
            <b>Any Employee Refrence</b>
        </td>
        <td>
            :
        </td>
        <td>
            @Html.CheckBox("EmpRef", false) Yes
        </td>
        <td>
        </td>
    </tr>
    <tr>
        <td colspan="3" align="right">
            <br />                
            <input type="button" id="btnSave" value="Save" data-bind="click: $root.loadData"/>                
            &nbsp;
            <input type="button" id="btnCancel" value="Cancel" />
        </td>
        <td></td>
    </tr>
</table>

Solution

  • In the success callback on the AJAX call to '/Employee/SaveNewEmployee', it looks like you're calling ko.applyBindings() again with a new instance of EmpViewModel(); The data should be mapped to the existing view model since you cannot apply bindings multiple times to the same element!

    success: function (data) {
        $("#OuterDialogBox").dialog("close");
        debugger
        ko.applyBindings(new EmpViewModel());
    }
    

    Check it out:

    http://jsfiddle.net/062h38Lx/

    Everything works great, but when you click save you'll see how it creates the multiple bindings error. Is that the error you're receiving? If not, please provide the HTML after it's been parsed by the browser - we can't debug your HTML if we don't know what the client-side looks like.