Is there any way to specify an enable condition for the click binding? For example if I have the following:
Clic
You can use this approach that I did for anchors
http://jsfiddle.net/xCfQC/11/
(function() {
//First make KO able to disable clicks on Anchors
var orgClickInit = ko.bindingHandlers.click.init;
ko.bindingHandlers.click.init = function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
if(element.tagName === "DIV" && allBindingsAccessor().enable != null) {
var disabled = ko.computed({
read: function() {
return ko.utils.unwrapObservable(allBindingsAccessor().enable) === false;
},
disposeWhenNodeIsRemoved: element
});
ko.applyBindingsToNode(element, { css: { disabled: disabled} });
var handler = valueAccessor();
valueAccessor = function() {
return function() {
if(ko.utils.unwrapObservable(allBindingsAccessor().enable)) {
handler.apply(this, arguments);
}
}
};
}
orgClickInit.apply(this, arguments);
};
})();
More details: https://github.com/AndersMalmgren/Knockout.BindingConventions/wiki/Button-convention
I've recently done this and put the condition check into the click function itself, so it won't do anything unless the condition is met. I also then use a computed function to provide the css class for the element, and change the cursor dependent on whether the element will react to the click:
In my view model:
iconStyle = ko.computed(function () {
var cssClass = 'DefaultClass';
if (/*condition to check if click is valid*/) {
cssClass = cssClass + ' Off';
}
return cssClass;
})
Then bind like this:
<div class="stepIcon" data-bind="click: clickFunction, css: iconStyle"></div>
It's actually a good amount simpler than any of these options. You can't make the binding conditional but you can make what function is fired conditional. Just use a conditional in the binding:
<div data-bind="click: myName() === 'John' ? toggleDialog : function(){ /* Nothing Happens */}">Click Me</div>
That will either fire toggleDialog()
or an anonymous function(){}
that does nothing.
You can even stack bound properties to disable the button itself:
<div data-bind="
disabled: myName() !== 'John',
click: myName() === 'John' ? toggleDialog : function(){ /* Nothing Happens */}
">Click Me</div>
Or have another function that runs in response to an unmet condition:
<div data-bind="
disabled: myName() !== 'John',
click: myName() === 'John' ? toggleDialog : tellUserTheyAreWrong
">Click Me</div>
Hope this helps
Kyle, after reading your comment to nemsev, I believe you want to disable your button, not your dialog function.
The binding...
<button data-bind="click: doAlert, enable: allowAlert">Open Dialog</button>
<div data-bind="click: doAlert">Click me for another call to trigger the dialog</div>
<button data-bind="click: toggleAllowAlert, text: allowButtonText"></button>
And the code...
var viewModel = function(){
var self = this;
self.allowAlert = ko.observable(true);
self.allowButtonText = ko.computed(function(){
if(self.allowAlert()){
return 'Turn off button';
} else {
return 'Turn on button';
}
});
self.toggleAllowAlert = function(){
self.allowAlert(!self.allowAlert());
};
self.doAlert = function(){
alert('The dialog has opened');
};
}
ko.applyBindings(new viewModel());
http://jsfiddle.net/DQg5P/1/