Search code examples
knockout.jsknockout-mapping-plugin

Using ko.mapping plugin to edit and insert new records


I am using the ko.mapping plugin to map data from the server to the client.

I really love the fact is I can write the model once on the server and I don't have to rewrite the same model properties on the client.

I am doing something which I think is a pretty common task. I have a list of records and I am wanting to be able to insert and edit them. I created a jsfiddle

I have gotten as far as binding the list to the UI and have the editting of existing items working

I am stuck with how to allow inserting of new records.

My object is very basic

 [{
    "CustomerId": "1cd608c2-d980-4370-9861-c49e0811923c",
    "FirstName": "Adam",
    "LastName": "Jones",
    "StoreCustomerId": "9999 9999 9999 0002",
}]



var ViewModel = function (data) {
var self = this;

var mapping = {
    customers: {
        create: function (options) {
            console.log("mapping");
            var vm = ko.mapping.fromJS(options.data);
            console.log(vm);
            vm.FullName = ko.computed(function () {
                return vm.FirstName() + " " + vm.LastName();
            });

            return vm;
        }

    }
};

ko.mapping.fromJS(data, mapping, self);

self.selectedCustomer = ko.observable();


self.delete = function (customer) {
    self.customers.remove(customer);
}

self.edit = function (customer) {
    console.log(customer);
    self.selectedCustomer = customer;
}

self.save = function (customer) {
    console.log(customer);
    //      console.log(customer.FirstName);
    self.customers.push(customer);
}
 }

 ko.applyBindings(new ViewModel(dataFromServer));

Do I have to create a new observable something like

self.selectedCustomer = ko.observable();

When I click on the edit button the inputs are populated. How can I create a new record?

<div data-bind="with:selectedCustomer">
    <input placeholder="FirstName" data-bind="value:FirstName" />
    <input placeholder="LastName" data-bind="value:LastName" />
</div>

Could someone who is smarter then me please take a quick look at the fiddle and help out with what I am doing wrong. I think I am close but missing something.

Thanks for any assistance possible!


Solution

  • You need to create new customer viewmodel. You can do it using your existing mapping like this

    var customer = mapping.customers.create({ data: {
        CustomerId: "",
        FirstName: "",
        LastName: "",
        StoreCustomerId: ""
    }});
    

    Then just push it to existing customers and select:

    self.customers.push(customer);
    self.selectedCustomer(customer);
    

    See updated fiddle