Conditional 'click' binding with Knockout
15,172
Solution 1
Do this
<ul class="modal-subject-list" data-bind="foreach: filteredSubjects">
<li data-bind="click: hasBeenAdded ? null : $parent.pickSubject">
<!-- Lots of code here -->
</li>
</ul>
Read -
If the filteredSubject has been added, do nothing, else add to the list or whatever.
Solution 2
Just want to expand on @PW Kad's answer in case it helps others.
I found that I could apply a condition to the knockout event node so that all or none of the handlers are bound. In my case, I needed to bind events only to inputs that were not read only. So this does work if you need to do something similar. Happy coding.
event: $data.SomeProperty() ? null : { multiple event handlers }
Example Code:
<input type="number"
data-bind="value: $data.Value,
css: $data.Css,
attr: {
title: $data.Title,
min: $data.Min,
max: $data.Max,
readonly: $data.ReadOnly
},
event: $data.ReadOnly() ? null : { // <----- HERE
focus: $root.onFocus,
blur: $root.onBlur,
input: $root.onInput,
keypress: $root.onKeypress
}" />
Related videos on Youtube
Author by
RobVious
Updated on June 11, 2022Comments
-
RobVious almost 2 years
I am binding the click event to every list item in a list:
<ul class="modal-subject-list" data-bind="foreach: filteredSubjects"> <li data-bind="click: $parent.pickSubject, css: {alreadyAddedBackground: hasBeenAdded}"> <!-- Lots of code here --> </li> </ul>
I want to disable the
click:
binding if 'hasBeenAdded' resolves to true. I know some messy ways to take care of it:- Have two list items, one for
if: hasBeenAdded
, and the other forif: !hasBeenAdded
. This is far from DRY - Handle this check with javascript and leave the view alone - I don't like this because unnecessary markup is being generated for list items that should be essentially disabled.
Is there a way to register a "clickIf" binding?
- Have two list items, one for
-
Anders over 10 yearsA button that does nothing when you click is hardly user friendly, better just to use the enable/disble binding
-
PW Kad over 10 yearsOP was very specific in that he wanted to conditionally handle the click binding, whether he uses null or not in a production environment is his choice...
-
Kishor about 9 yearsit's better to replace "null" with function, <li data-bind="click: hasBeenAdded ? function() { return false; } : $parent.pickSubject">
-
Alexander Abakumov about 9 years@Kishor, Could you please explain why it is better?
-
Zoltán Tamási almost 8 yearsBe careful, using the function returning false has a completely different meaning. If there is
null
, knockout will not bind anything to the event. When you pass that kind of function, for example the default event will be prevented to say the least. -
Zoltán Tamási almost 8 yearsAlso note, that knockout is not treating event bindings as
computeds
, which means that the first result which your expression evaluates to will be used by knockout for the whole lifetime. You cannot do something like this for example:data-bind="click: myObservable() ? null : myHandler"
and expect that the handler will get bound and unbound based on the expression. This was kind of a surprise for me, but I guess it would add a big amount of complexity to implement properly. -
zergski over 2 yearsI'm not the biggest fan of that a large chunk of our application uses knockout at work, but you sir, showed me something that now seems so obvious. Thank you!