Reputation: 3745
I'm using knockout.js (v2.2.1) for the first time, and am trying to build a table where elements toggle between text and input fields based on an "IsReadOnly" property in the view model. This is accomplished using "visible" on span and input tags within the table cells.
Here's the table:
<table>
<tr>
<td colspan="2">
<button id="btnEditSave" data-bind="text: btnEditSave, click: doEditSave" style="float:right;" />
</td>
</tr>
<tr>
<td>Server Name: </td>
<td>
<span data-bind="text: Server.ServerName, visible: IsReadOnly() == true" />
<input data-bind="value: Server.ServerName, visible: IsReadOnly() == false" maxlength="50" style="width:400px;" />
</td>
</tr>
</table>
and the model:
var ServerViewModel = function () {
// Data
var self = this;
self.IsReadOnly = ko.observable(true); // the form's input mode
self.btnEditSave = ko.observable("Edit"); // the Edit/Save button text
self.Server = ko.observable({}); // the Server object
// Operations
self.doEditSave = function () {
var flag = self.IsReadOnly();
if (flag) {
// switch to Edit mode
self.btnEditSave("Save");
self.IsReadOnly(false);
}
else {
// will eventually save the form data here...
// switch back to readOnly
self.btnEditSave("Edit");
self.IsReadOnly(true);
}
}
}
Everything toggles as expected, except that the input field is not displayed. I've tried various forms of the input tag's "visible" expression, yet nothing works. What am I missing?
Upvotes: 1
Views: 1697
Reputation: 45135
Try:
<span data-bind="text: Server.ServerName, visible: IsReadOnly"></span>
<input data-bind="value: Server.ServerName, visible: !IsReadOnly()" maxlength="50" style="width:400px;" />
Edit: good catch by Warappa on the self-closing span. Knockout don't like 'em.
Upvotes: 0
Reputation: 5120
I think you should write ...value: Server().ServerName,...
and ...text: Server().ServerName,...
as Server
is an observable
.
Everything else seems pretty right to me.
BTW: A jsfiddle would help alot.
I just set up a jsfiddle: http://jsfiddle.net/GRShn/1/
The problem is that you write a self-closing span - which cannot be selfclosing. Just write <span ...></span>
instead of <span ... />
and your initial version works!
Upvotes: 2
Reputation: 3745
I couldn't determine why my first example didn't work, but I did find a solution: use another property "IsEditable" which is the opposite of "IsReadOnly" so my expressions only test for true.
The table row is now:
<tr>
<td>Server Name: </td>
<td>
<input data-bind="value: Server.ServerName, visible: IsEditable" maxlength="50" style="width:400px;" />
<span data-bind="text: Server.ServerName, visible: IsReadOnly" />
</td>
</tr>
and the model is:
var ServerViewModel = function () {
// Data
var self = this;
self.IsReadOnly = ko.observable(true); // the form's input mode
self.IsEditable = ko.observable(false); // <<--- the workaround
self.btnEditSave = ko.observable("Edit"); // the Edit/Save button text
self.Server = ko.observable({}); // the Server object
// Operations
self.doEditSave = function () {
var flag = self.IsReadOnly();
if (flag) {
// switch to Edit mode
self.btnEditSave("Save");
self.IsReadOnly(false);
self.IsEditable(true);
}
else {
// switch back to readOnly
self.btnEditSave("Edit");
self.IsReadOnly(true);
self.IsEditable(false);
}
}
}
Upvotes: 0