Reputation: 6242
I am using knockout js here.
I have a HTML table and the table has 4 columns. I have button to add a row to table and then remove button against each row to delete it. HTML table as below.
<table class="table table-bordered">
<thead class="mbhead">
<tr class="mbrow">
<th>Input</th>
<th>First Name</th>
<th>Last Name</th>
<th>Address</th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td>
<select class="form-control common-input-text" data-bind="event: { change: $root.addNewItem }">
<option value="">One</option>
<option value="">Two</option>
<option value="">Three</option>
</select>
</td>
<td><span class="input-small" data-bind="value: firstName" /></td>
<td><span class="input-small" data-bind="value: lastName" /></td>
<td><span class="input-small" data-bind="value: address" /></td>
<td>
<input type="button" value="Remove Row" data-bind="click: removeRow" class="btn btn-danger" />
</td>
</tr>
</tbody>
</table>
<input type="button" value="Add Row" class="btn btn-primary" data-bind="click: addRow" />
My knockout as:
(function () {
var ViewModel = function () {
var self = this;
//Empty Row
self.items = ko.observableArray([]);
self.addRow = function () {
self.items.push(new Item());
};
self.removeRow = function (data) {
self.items.remove(data);
};
}
var Item = function (fname, lname, address) {
var self = this;
self.firstName = ko.observable(fname);
self.lastName = ko.observable(lname);
self.address = ko.observable(address);
};
vm = new ViewModel()
ko.applyBindings(vm);
})();
When I click add row, it adds the first row but gives me console error:
knockout.js:73 Uncaught ReferenceError: Unable to process binding "click: >function (){return removeRow }" Message: removeRow is not defined
When I click add row again it gives me another console error:
Uncaught Error: You cannot apply bindings multiple times to the same element.
And when I click removeRow nothing happens.
When I comment out the code for removeRow, I am able to add a new row. Not sure where I am going wrong.
Here is my jsfiddle:
https://jsfiddle.net/aman1981/nz2dtud6/2/
Upvotes: 2
Views: 2092
Reputation: 49095
Since your <tbody>
defines a new scope by using a foreach: items
binding, you need to use $parent.removeRow
to refer to the method.
<input data-bind="click: $parent.removeRow" type="button" value="Remove Row" />
See BindingContext
Upvotes: 1
Reputation: 2076
When using the data binding foreach
the context changes to the context of its childs. To access the context of the parent, you need to add $parent
to access removeRow
<td>
<input type="button" value="Remove Row" data-bind="click: $parent.removeRow" class="btn btn-danger" />
</td>
Upvotes: 2