I have a table:
table class="table">
<thead>
<tr>
<th>ID</th>
<th>Description</th>
</tr>
</thead>
<tbody data-bind="foreach: Curriculums">
<tr>
<td data-bind="text: ID"></td>
<td>
<div data-bind="event: { mouseover: toggle, mouseout: toggle }>
<span data-bind="text: curCode"></span>
</div>
<div data-bind="visible: selected">
<span data-bind="text: curDescription"></span>
</div>
</td>
</tr>
</tbody>
</table>
this is my knockout js
var Vm =
{
Curriculums: ko.observableArray([]),
ID: ko.Observable(),
curCode: ko.observable(),
curDescription: ko.observable(),
selected: ko.observable(false),
toggle: function() {
this.selected(!this.selected());
}
}
I am trying to load all of the records of curriculum table. I successfully retrieved it and displayed it without the mouse over/out bindings. The problem is when I implement the mouseover and mouseout bindings, the knockout throws an error:
Uncaught Error: Unable to parse bindings.
Message: ReferenceError: toggle is not defined;
Bindings value: event: { mouseover: toggle}
how can I make this work? I am hiding the curDescription span if the mouse is not hovering and make it reappear when the mouse hovers to the curCode span
toggle
should be prefixed with $parent
as you are using it inside a foreach
binding. Otherwise knockout will look for the function inside each
item in Curriculums
array.
<tbody data-bind="foreach: Curriculums">
<tr>
<td data-bind="text: ID"></td>
<td>
<div data-bind="event: { mouseover: $parent.toggle, mouseout: $parent.toggle }>
<span data-bind="text: curCode"></span>
</div>
<div data-bind="visible: selected">
<span data-bind="text: curDescription"></span>
</div>
</td>
</tr>
</tbody>
This still won't give you the expected result. ID
, curCode
selected
and curDescription
should be properties of items in Curriculums
array. You don't need to have that in your Vm
var Vm = {
Curriculums: ko.observableArray([{
ID: 1,
curCode: "CS101",
curDescription: "Why C#?",
selected: ko.observable(false) // this needs to be an observable
}, {
ID: 2,
curCode: "CS102",
curDescription: "Javascript 101",
selected: ko.observable(false)
}]),
// "item" will have the current "Curriculum" element which triggered the event
toggle: function(item) {
item.selected(!item.selected());
}
}
Here's a fiddle for you test. Go through the knockout documentation and play around with some fiddles to get a good understanding of ko bindings.
As mentioned in this answer on the other question, you can achieve this by pure CSS
. But again, it's important you understand how binding works inside foreach
.
Personally I'd just resort to CSS for such a simple thing, not least because it is more like a visual thing than program logic:
<table class="table show-on-hover">
<thead>...</thead>
<tbody data-bind="foreach: Curriculums">
<tr>
<td data-bind="text: ID"></td>
<td>
<span data-bind="text: curCode"></span>
<span class="shown-on-hover" data-bind="text: curDescription"></span>
</td>
</tr>
</tbody
CSS:
table.show-on-hover tr .shown-on-hover {
visibility: hidden;
}
table.show-on-hover tr:hover .shown-on-hover {
visibility: visible;
}
However, this is an alternative way, not really an explaination of why your solution does not work. The other answer posted here does a nice job at explaining that.