0

Here's a fiddle to reference with this question: http://jsfiddle.net/CJRDQ/3/

I've created a simple custom expander like so:

<div class="ui-expander">
  <h3 class="ui-expander-head">...</h3>
  <div class="ui-expander-content">...</div>
</div>

The functionality for the expander is impelemented via a custom Knockout.js binding and some jQuery (use of custom binding is to address issues created by the with binding).

ko.bindingHandlers.expand = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        if ($(element).hasClass('ui-expander')) {
            var expander = element;
            var head = $(expander).find('.ui-expander-head');
            var content = $(expander).find('.ui-expander-content');

            $(head).click(function () {
                $(head).toggleClass('ui-expander-head-collapsed')
                $(content).toggle();
            });
        }
    }
};

This works as expected unless there are clickable controls in the expander head. In my current scenario, I need to provide a checkbox in the expander head to filter results in the view model:

<div class="ui-expander" data-bind="expand: true">
    <h3 class="ui-expander-head">
        <span class="ui-expander-toggle">[-]</span> Expander Title
        <input id="cbx" type="checkbox" data-bind="checked: showAll" /> <label for="cbx">Show All</label>
    </h3>
    <div class="ui-expander-content">
        Expander Content
    </div>
</div>

If I click the label, expand/collapse behavior isn't triggered and the corresponding checkbox is checked/unchecked (desired). However, if I click the checkbox directly, expand/collapse is triggered and the corresponding checkbox is checked/unchecked (undesired).

I need to be able to click the checkbox and/or label without triggering expand/collapse but maintain expand/collapse if any other part of the expander head is clicked. What needs to be done to meet these requirements?

Again, I've provided a fiddle for reference: http://jsfiddle.net/CJRDQ/3/

Community
  • 1
  • 1
sellmeadog
  • 7,437
  • 1
  • 31
  • 45

2 Answers2

2

You can add a click handler and call stopPropagation() on the event to prevent it from propagating to the header and return true so it will still be processed by the checkbox to change the state. You need to add the handler to the label as well if you want it to be able to change the state of the checkbox and not trigger the expand or collaps:

<input id="cbx" type="checkbox" data-bind="checked: showAll, click: preventClick" />
<label for="cbx" data-bind="click: preventClick">

View model:

this.preventClick = function(data, event) {
    event.stopPropagation();
    return true;
};

http://jsfiddle.net/HGxc6/

Jason Goemaat
  • 28,692
  • 15
  • 86
  • 113
0

Your requirements seemed a little confusing to me. Is this updated fiddle what you were looking for: http://jsfiddle.net/photo_tom/CJRDQ/6/

photo_tom
  • 7,292
  • 14
  • 68
  • 116