Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to data-bind visible to the negation ("!") of a boolean ViewModel property?

Tags:

knockout.js

People also ask

What happens in visible binding?

When the parameter transforms into true-like value (such as boolean true,or nonnull object or array ), the binding removes yourElement. style. display value, making it visible. If this is an observable property, then the binding will update visibility every time the property changes.

What is data bind attribute?

A data binding connects data from a custom element (the host element) to a property or attribute of an element in its local DOM (the child or target element). The host element data can be a property or sub-property represented by a data path, or data generated based on one or more paths.


When using an observable in an expression you need to access it as a function like:

visible: !charted()


I agree with John Papa's comment that there should be a built-in hidden binding. There are two benefits to a dedicated hidden binding:

  1. Simpler syntax, ie. hidden: charted instead of visible: !charted().
  2. Less resources, since Knockout can observe the observable charted directly, rather than creating a computed to observe !charted().

It's simple enough to create a hidden binding, though, like this:

ko.bindingHandlers.hidden = {
  update: function(element, valueAccessor) {
    ko.bindingHandlers.visible.update(element, function() {
      return !ko.utils.unwrapObservable(valueAccessor());
    });
  }
};

You can use it just like the built-in visible binding:

<i class="icon-search" data-bind="hidden: charted, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="visible: charted, click: $parent.pie_it"></i>

It's little confusing, as you have to do

visible:!showMe()

so, i did

<span data-bind="visible:showMe">Show</span>
<span data-bind="visible:!showMe()">Hide</span>
<label><input type="checkbox" data-bind="checked:showMe"/>toggle</label>​

my model is

var myModel={
    showMe:ko.observable(true)
}
ko.applyBindings(myModel);    

​ check in fiddle http://jsfiddle.net/khanSharp/bgdbm/


You could use my switch/case binding, which includes case.visible and casenot.visible.

<tbody data-bind="foreach: periods">
    <tr>
        <td data-bind="switch: true">
        <i class="icon-search" data-bind="case.visible: $else, click: $parent.pie_it"></i>
        <i class="icon-remove" data-bind="case.visible: charted, click: $parent.pie_it"></i>
        </td>
    </tr>
</tbody>

You could also have it as

        <i class="icon-search" data-bind="casenot.visible: charted, click: $parent.pie_it"></i>
        <i class="icon-remove" data-bind="case.visible: $else, click: $parent.pie_it"></i>

In order to make the binding aware of changes to the property, I copied the visible binding handler and inverted it:

ko.bindingHandlers.hidden = {
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var isCurrentlyHidden = !(element.style.display == "");
        if (value && !isCurrentlyHidden)
            element.style.display = "none";
        else if ((!value) && isCurrentlyHidden)
            element.style.display = "";
    }
};

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!