Reputation: 1799
I need to pass data from a click:
event into another div. Here is a scenario:
There is a link on one side of the page.
<a data-bind="text: Name, click: $root.editAction"></a>
On the other side of the page, there is a hidden div.
<div data-bind="if: $root.editActionShow">
<input type="text" data-bind="value: Name"/>
</div>
I need to be able to pass $data
from the click:
event, do that hidden div.
Perhaps I am over-thinking this, but my viewModel
has many different Actions
buried deep in viewModel.DataGroups.DataGroup.ActionDataGroup
and there is only 1 HTML form to edit action information, so I can't figure out how to make the form only show that one particular action I want to edit.
Here is another kicker. I prefer not to add any observables to my viewModel
. Reason being is that I have to do .toJS()
map it at the end, and then convert JSON into XML, which must validate against a pretty strict schema, so having extra elements is a bad thing. It will not pass validation, unless I manually remove them before conversion. However, I can add this.blah = function() {}
objects to my viewModel
, because .toJS()
strips them during conversion.
UPDATE:
Aaand solution to all this is hands down hilarious
viewModel.editAction = function(data) {
viewModel.editActionFormShow(true);
ko.applyBindings(data, $('#myHiddenDiv')[0]);
};
Upvotes: 1
Views: 1707
Reputation: 19738
From what I understand, you want something like a 'click-to-edit' function, which can be solved pretty neatly with just 2 custom bindings!
The great advantage about this approach is you won't polute your viewModel with extra observables.
Bindings:
ko.bindingHandlers.hidden = {
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
ko.bindingHandlers.visible.update(element, function() {
return!value; });
}
};
ko.bindingHandlers.clickToEdit = {
init: function(element, valueAccessor,allBindingsAccessor){
var value = valueAccessor(),
input = document.createElement('input'),
link = document.createElement('a');
element.appendChild(input);
element.appendChild(link);
value.isEditing = ko.observable(false);
ko.applyBindingsToNode(link,{
text: value,
hidden: value.isEditing,
click: function(){
value.isEditing(true);
}
});
ko.applyBindingsToNode(input,{
value: value,
visible: value.isEditing,
hasfocus: value.isEditing
});
}
};
ViewModel
var vm = {
name: ko.observable()
}
The HTML
<div data-bind="clickToEdit: name"></div>
Working fiddle: http://jsfiddle.net/8Qamd/
All credit goes to Ryan Niemeyer.
Upvotes: 1