Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

knockout visible binding with hover?

Tags:

knockout.js

I have the following:

<input type="checkbox" data-bind="visible: selectedItemsCount() > 0, attr: { value: itemId()}, checked: $parent.selectedFolderIds" />

What I'm trying to do is add another conditional so that visible is activated if the user hovers over the element. Is there any way to do this within the visible binding? Something like:

<input type="checkbox" data-bind="visible: selectedItemsCount() > 0 || isHovering(), attr: { value: itemId()}, checked: $parent.selectedFolderIds" />
like image 684
SB2055 Avatar asked Apr 30 '13 21:04

SB2055


People also ask

What are the types of binding supported by Knockout JS?

Binding Values The binding value can be a single value, literal, a variable or can be a JavaScript expression.

What is binding in Knockout?

A binding context is an object that holds data that you can reference from your bindings. While applying bindings, Knockout automatically creates and manages a hierarchy of binding contexts. The root level of the hierarchy refers to the viewModel parameter you supplied to ko. applyBindings(viewModel) .

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.

How does Ko identify the template block that needs to be rendered?

Shorthand syntax: If you just supply a string value, KO will interpret this as the ID of a template to render. The data it supplies to the template will be your current model object.


1 Answers

In general, it's a good practice to avoid putting logic directly in your Knockout binding within HTML. Not the end of the world, but it can quickly lead down a messy road.

If possible, use a custom binding to provide the desired UI behavior for your visibility. It is useful to put that logic inside a custom binding, because it separates the implementation details from the view. You may decide later that instead of changing the visibility, you want to add/remove some CSS to control the appearance, or maybe you want to add some animation.

Here's a very simple binding that sets the visibility on hover:

ko.bindingHandlers.hoverTargetId = {};
ko.bindingHandlers.hoverVisible = {
    init: function (element, valueAccessor, allBindingsAccessor) {

        function showOrHideElement(show) {
            var canShow = ko.utils.unwrapObservable(valueAccessor());
            $(element).toggle(show && canShow);
        }

        var hideElement = showOrHideElement.bind(null, false);
        var showElement = showOrHideElement.bind(null, true);
        var $hoverTarget = $("#" + ko.utils.unwrapObservable(allBindingsAccessor().hoverTargetId));
        ko.utils.registerEventHandler($hoverTarget, "mouseover", showElement);
        ko.utils.registerEventHandler($hoverTarget, "mouseout", hideElement);
        hideElement();
    }
};

Use it like this:

<div><label id='hoverTarget'>Hover to see the details</label></div>
<div data-bind="hoverVisible: hasItems, hoverTargetId: 'hoverTarget'">Here's the details</div>

See the Fiddle


A couple other recommendations:

  1. Define a property in your view model that represents the application logic of whether the element is allowed to be displayed, say something like hasItems.
  2. Use the built-in checked binding for binding the value of an input type='checkbox' />
like image 170
Joseph Gabriel Avatar answered Sep 18 '22 20:09

Joseph Gabriel