Reputation: 424
I am having trouble getting this to work: http://jsfiddle.net/2jg2F/1/
I basically want to make a link that changes to an input box when someone clicks on the text. I have tried knockout 2.0 and 2.1.
HTML
<div data-bind="clickToEdit : message"> </div>
Javascript
ko.bindingHandlers.clickToEdit = {
init: function(element, valueAccessor) {
var observable = valueAccessor(),
link = document.createElement("a"),
input = document.createElement("input");
element.appendChild(link);
element.appendChild(input);
observable.editing = ko.observable(false);
ko.applyBindingsToNode(link, {
text: observable,
visible: !observable.editing,
click: function() {
observable.editing(true);
}
});
ko.applyBindingsToNode(input, {
value: observable,
visible: observable.editing,
hasfocus: observable.editing
});
}
};
function ViewModel() {
this.message = ko.observable("Click on me to edit");
}
ko.applyBindings(new ViewModel());
Upvotes: 2
Views: 6031
Reputation: 114792
Your problem is on this line:
visible: !observable.editing
This will evaluate to false and will stay that way. Even if you do !observable.editing()
, then it will be a static true value.
So, there are a couple of ways to handle it:
1 - a good choice is to create a quick hidden
binding handler that just passes the opposite value to the visible binding. There are a few ways to write it, but here is a simple way:
ko.bindingHandlers.hidden = {
update: function(element, valueAccessor) {
var isVisible = !ko.utils.unwrapObservable(valueAccessor());
ko.bindingHandlers.visible.update(element, function() { return isVisible; });
}
};
Now, you can use:
hidden: observable.editing
Here is a sample: http://jsfiddle.net/rniemeyer/2jg2F/2/
2 - another choice is to add a computed observable that returns the opposite. Something like:
observable.editing = ko.observable(false);
observable.notEditing = ko.computed(function() {
return !observable.editing();
});
Then, binding against notEditing
like:
http://jsfiddle.net/rniemeyer/2jg2F/3/
Upvotes: 4