Reputation: 73
I've been trying to get Knockout's click-to-edit function in my application. However, it has some really strange behavior when I try and make it work. Specifically, the input doesn't appear when you try to edit on a page with multiple editable values, and all you get with tables is a single input box, regardless of how many objects are in an array. Why does this happen?
Here's the multiple values code:
HTML:
<h1>Job App Tracker</h1>
<div data-bind="foreach: apps">
<p>
<b data-bind="visible: !editing(), text: title, click: edit"> </b>
<input type="text" class="form-control" data-bind="visible: editing, value: title, hasFocus: editing" />
<b data-bind="visible: !editing(), text: description, click: edit"> </b>
<input type="text" class="form-control" data-bind="visible: editing, value: description, hasFocus: editing" />
<b data-bind="visible: !editing(), text: company, click: edit"> </b>
<input type="text" class="form-control" data-bind="visible: editing, value: company, hasFocus: editing" />
<b data-bind="visible: !editing(), text: submit_date, click: edit"> </b>
<input type="text" class="form-control" data-bind="visible: editing, value: submit_date, hasFocus: editing" />
<b data-bind="visible: !editing(), text: link, click: edit"> </b>
<input type="text" class="form-control" data-bind="visible: editing, value: link, hasFocus: editing" />
</p>
</div>
JS:
// Job app object:
function JobApp(title, description, company, submit_date, link) {
var self = this;
self.title = ko.observable(title);
self.description = ko.observable(description);
self.company = ko.observable(company);
self.submit_date = ko.observable(submit_date);
self.link = ko.observable(link);
self.editing = ko.observable(false);
self.edit = function () {
self.editing(true);
};
}
// Main KO logic:
function AppViewModel() {
var self = this;
self.apps = ko.observableArray([new JobApp('Noodle Picker', 'Picks, noodles, and leaves', 'Noodle Pickers, Inc.', '2014-1-25', 'noodlepickers.com'),
new JobApp('Not A Real Job', 'Not a real job', 'Not A Real Company', '1969-1-1', 'nope.com')]);
}
ko.applyBindings(new AppViewModel());
And the tables code:
HTML:
<h1>Job App Tracker</h1>
<table>
<div data-bind="foreach: apps">
<tr>
<td>
<b data-bind="visible: !editing(), text: title, click: edit"> </b>
<input type="text" class="form-control" data-bind="visible: editing, value: title, hasFocus: editing" />
</td>
</tr>
</div>
</table>
JS:
// Job app object:
function JobApp(title, description, company, submit_date, link) {
var self = this;
self.title = ko.observable(title);
self.description = ko.observable(description);
self.company = ko.observable(company);
self.submit_date = ko.observable(submit_date);
self.link = ko.observable(link);
self.editing = ko.observable(false);
self.edit = function () {
self.editing(true);
};
}
// Main KO logic:
function AppViewModel() {
var self = this;
self.apps = ko.observableArray([new JobApp('Noodle Picker', 'Picks, noodles, and leaves', 'Noodle Pickers, Inc.', '2014-1-25', 'noodlepickers.com'),
new JobApp('Not A Real Job', 'Not a real job', 'Not A Real Company', '1969-1-1', 'nope.com')]);
}
ko.applyBindings(new AppViewModel());
Upvotes: 1
Views: 1098
Reputation: 19617
The problem was in hasFocus
binding. When user clicks by text, all inputs shows, and tried to take focus for yourself! I've deleted hasFocus bindings from inputs and now they are displayed.
I've updated example.
Update
I found a solution how to hide inputs. You can use blur js event. When input will lose focus, all edits will be hidden, and all text will be shown:
<input type="text" class="form-control" data-bind="visible: editing, value: title, event: {blur: stopEdit}" />
Upvotes: 1
Reputation:
You can try a solution like this.
http://jsfiddle.net/eguneys/j4NB4/5/
// Editable Text object:
function EditableText(text, editable) {
var self = this;
self.text = ko.observable(text);
self.editing = ko.observable(editable);
}
Upvotes: 4