Using slideToggle with Knockout’s MVVM

I recommend you use the third option: Option 3 – Boolean binding using a custom binding handler called slideToggle

See it live here: http://plnkr.co/edit/1YGchAyjkNSjYzmXFfK2

<!-- Step 1a - Create the HTML File or the View -->
<!DOCTYPE html>
<html>
<head>
    <!-- Step 2 - Include jquery and knockout -->
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    <script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
     
    <!-- Step 3 - Add script to run when page loads -->
    <script type="text/javascript">
        $(document).ready(function(){
         
            <!-- Step 4 - Create a ViewModel -->           
            function viewModel() {
                _self = this;
                _self.showHideChild = function(viewModel, event) {
                    $(event.currentTarget).children('div').slideToggle()
                };
                _self.showHideNextSibling = function(viewModel, event) {
                    var siblings = $(event.currentTarget).siblings('div');
                    for (var i=0;i<siblings.length;i++) {
                        if (siblings[i].previousElementSibling == event.currentTarget ) {
                            $(siblings[i]).slideToggle();
                        }
                    }                 
                };
                _self.isVisible = ko.observable(false);
                _self.showHide = function() {
                    _self.isVisible(!_self.isVisible());
                }
            };
           
            ko.bindingHandlers.slideToggle = {
                init: function (element, valueAccessor) {
                    var value = valueAccessor();
                    $(element).toggle(ko.utils.unwrapObservable(value));
                },
                update: function (element, valueAccessor) {
                    var value = valueAccessor();
                    var isVisible = element.offsetWidth > 0 && element.offsetHeight > 0;
                    if (ko.utils.unwrapObservable(value) != isVisible) {
                        $(element).slideToggle();
                    }
                }
            };
           
            <!-- Step 5 -  Activates knockout.js bindings -->
          ko.applyBindings(new viewModel());
        });
    </script>
</head>
<!-- Step 4 - Create a HTML Elements with bindings -->
<body style="">
    <div>
        Option 1 - Child div
        <div id="child1" data-bind="click: showHideChild" style="border:2px solid;">
        Click me
            <div id="child2" style="display: none;">
              Now you see me!
            </div>
        </div>
        
        Option 2 - Siblings div
        <div id="sib1" style="border:2px solid;">
            <div id="sib2" data-bind="click: showHideNextSibling" >
            Click me
            </div>
            <div id="sib3" style="display: none;">
            Now you see me!
            </div>
            <div id="sib4">
            You should always see me.
            </div>
        </div>
        Option 3 - Boolean binding using a custom binding handler called slideToggle 
        <div id="bool1" style="border:2px solid;">
            <div id="bool2" data-bind="click: showHide" >
            Click me
            </div>
            <div id="bool3" data-bind="slideToggle: isVisible">
            Now you see me!
            </div>
        </div>
    </div>
</body>
</html>

One Comment

  1. Ray says:

    Excellent! Thanks for the help!

Leave a Reply to Ray

How to post code in comments?