Asif Rahman
Asif Rahman

Reputation: 83

knockout datatable binding with remove element

I've been trying to bind my datatable with knockout js. I've a button for adding element to an observableArray which update the table efficiently. And for each row I've a remove button, the problem is I can remove an item first time, then the table updates. After that no remove button works. If I add an item and the click to remove some other item then the remove seems not working. Strangely, If I sort or search the table (meaning update it) the remove seems working for a second time.

Here is my code

<script id="sample2RowTemplate" type="text/html">
 <td> <label data-bind="text: Id" /></td>
        <td> <input type="text" data-bind="value: Title" /></td>
        <td> <input type="text" data-bind="value: Price" /></td>      
        <td><a data-bind="click: function() { vm.removeGift($data); }">Remove</a></td>
    </script>

And:

    var initialData = [{
    Id: 1,
    Title: 'Star Wars Blue Ray',
    Price: '90.00'}];
var initCounter = 1;

//define record class

function GiftRecord(id, title, price) {
    this.Id = ko.observable(id);
    this.Title = ko.observable(title);
    this.Price = ko.observable(price);
}

//map the records
var mappedData = ko.utils.arrayMap(initialData, function(item) {
    return new GiftRecord(item.Id, item.Title, item.Price);
});

//Build viewModel

function viewModel() {
    this.gifts = ko.observableArray(mappedData);
    this.addGift = function() {
        initCounter += 1;
        var title = $("#newTitle").val();
        var price = $("#newPrice").val();
        var rec = new GiftRecord(initCounter, title, price);
        this.gifts.push({
            Id: rec.Id,
            Title: rec.Title,
            Price: rec.Price
        });
    };
    this.removeGift = function(gift) {
        this.gifts.remove(function(item2) {
            return gift.Id == item2.Id;
        });
    };

    this.testUpdate = function() {
        this.gifts()[0].Title("test123");
    };

    this.save = function() {
        ko.utils.postJson(location.href, {
            gifts: ko.toJS(this.gifts()),
            guid: giftsSignalR.guid
        });
    };
}
vm = new viewModel();
//Bind viewModel to HTML
$(function() {
    ko.applyBindings(vm, $("#sample2")[0]);
});

which is basically the same as in: http://jsfiddle.net/bdetchison/b4SsE/

Please Help....

Upvotes: 1

Views: 873

Answers (1)

beauXjames
beauXjames

Reputation: 8418

Using your code seemed to work fine. I was expecting things not to work. I would do things a bit differently with binding my model to the page...but this does seem to work ::

http://jsfiddle.net/beauxjames/RYUHy/1/

Now...to take it in a little different direction, I would do the following ::

http://jsfiddle.net/beauxjames/RYUHy/

In this model I've completely removed reference to the DOM from the models. On top of that, take note of the ko.mapping invocation and see how the gifts are not only being added, but their properties are also automatically observed. There was a small change to the initial data and I wrapped the array of gifts into a named object...which gave me the ability to have a parent model and keep the gifts as a child.

var initialData = { 'gifts' : [ ... ] };

var giftMapping = {
    'gifts': {
        create: function (options) {
            if (options.data != null) return new GiftModel(options.data);
        }
    }
}

The addition of the new Gift no longer relies on references to the input fields from within the associated view model. I spun up a property called newGift within the parent model and bound the forms controls to that using the data-bind="with: newGift" attribute. Since I did this, I did have to declare and initialize the properties within Gift Model...otherwise I could have left them out. They would have been initialized with the initial data as observables.

var GiftModel = function(data) {
    var self = this;
    self.Id = ko.observable();
    self.Title = ko.observable();
    self.Price = ko.observable();
    ko.mapping.fromJS(data, {}, self);
}

Anyways, hope this helps and gives you a new way to look @ things. I see these methods as being much more common as the move toward platforms like angular start to take shape.

Upvotes: 1

Related Questions