Reputation: 155
I want a <td>
to be visible or invisible depending on a boolean value in my javascript.
My HTML is:
<!-- ... -->
<tbody data-bind="foreach: entries">
<tr>
<td data-bind="visible: editable()">
<a href="#" data-bind="click: $root.removeEntry">Remove</a>
</td>
</tr>
</tbody>
<!-- ... -->
And my Javascript would be this:
//...
function TableEntryViewModel(){
editable: ko.observable(false);
//...
}
When it loads my data it only loads the first entry and then stops. Here's the error i get.
Uncaught TypeError: Unable to process binding "visible: function (){return editable() }" Message: string is not a function
This isn't an exact replica of my programm, but if you make this work i'm sure you'll help me a lot: http://jsfiddle.net/CuppleKay/S6Hwa/
Upvotes: 0
Views: 1126
Reputation: 1502
Ok, I can see from your example what you're trying to do. I've posted a modified version here:
JavaScript:
function TableEntryViewModel(){
var self = this;
self.editable = ko.observable(false);
self.removeEntry = function (row) {
self.entries.remove(row);
};
self.entries = ko.observableArray([
{name: "Hendrik", vorname: "Alex", adresse: "Southstreet", wohnort: "South", id: "239"},
{name: "Hendrik", vorname: "Alex", adresse: "Southstreet", wohnort: "South", id: "240"},
{name: "Hendrik", vorname: "Alex", adresse: "Southstreet", wohnort: "South", id: "241"}
]);
}
var model = new TableEntryViewModel();
ko.applyBindings(model);
HTML:
...
<td data-bind="visible: $root.editable"><a href="#" data-bind="click: $root.removeEntry">Remove</a> </td>
...
Note that I needed to change your binding to $root.editable
. If you want to hide "Remove" on a row-by-row basis, then try the slightly different version:
JavaScript:
function TableEntryViewModel(){
var self = this;
self.removeEntry = function (row) {
self.entries.remove(row);
};
self.entries = ko.observableArray([
{name: "Hendrik", vorname: "Alex", adresse: "Southstreet", wohnort: "South", id: "239", editable: ko.observable(false)},
{name: "Hendrik", vorname: "Alex", adresse: "Southstreet", wohnort: "South", id: "240", editable: ko.observable(false)},
{name: "Hendrik", vorname: "Alex", adresse: "Southstreet", wohnort: "South", id: "241", editable: ko.observable(false)}
]);
}
var model = new TableEntryViewModel();
ko.applyBindings(model);
HTML:
...
<td data-bind="visible: editable"><a href="#" data-bind="click: $root.removeEntry">Remove</a> </td>
...
Note that because each entry in your observableArray contains an editable
value, we don't need to use $root.
anymore.
Hope that helps.
Upvotes: 1
Reputation: 8053
This syntax is incorrect:
function TableEntryViewModel(){
editable: ko.observable(false);
//...
}
It should be either
function TableEntryViewModel(){
this.editable = ko.observable(false);
//...
}
//...
ko.applyBindings(new TableEntryViewModel());
Or
var TableEntryViewModel = {
editable: ko.observable(false),
//...
}
//...
ko.applyBindings(TableEntryViewModel);
Upvotes: 0
Reputation: 1672
This error can occur if you are not providing the correct context. Are your <td>
elements inside a KO foreach
?
For example:
<table data-bind="foreach: items">
<tr>
<td data-bind="visible: editable()">
<a href="#" data-bind="click: $root.removeEntry">Remove</a>
</td>
</tr>
</table>
In this example, the context within the foreach
is items
and not the parent ViewModel. If editable
exists in the parent ViewModel then you need to provide that context like so:
<td data-bind="visible: $parent.editable()">
Upvotes: 0