Add a sub property in ko.bindingHandlers and write your custom code in init and update method. This blog does not explain how to create custom binding. You can find its help in the knockout documentation. Here is the complete code of the custom binding for show/hide element using jQuery.
ko.bindingHandlers.collapseVisible = { init: function (element, valueAccessor) { var value = valueAccessor(); $(element).toggle(ko.utils.unwrapObservable(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable }, update: function (element, valueAccessor, allBindingsAccessor) { var value = valueAccessor(); var allBindings = allBindingsAccessor(); // Grab some more data from another binding property var duration = allBindings.slideDuration || 500; ko.utils.unwrapObservable(value) ? $(element).slideDown(duration) : $(element).slideUp(duration); } };
In the init method set the initial state of the element. This method calls once for each DOM element. Get element using $(element) and perform action which you want.
Whenever the associated observable change, the ko calls you update callback method. In this example I get the value of element using ko.utils.unwrapObservable(value) and call slideUp or slideDown method according to value.
Now next step is to bind your DOM element using ‘CollapseVisible’ custom binding.
<div data-bind="collapseVisible: displayDetail, slideDuration: 1000" class="desc"> Lorem Ipsum is simply dummy text of the ... </div>
So whenever the value of displayDetail observable will change. The Update callback method will be called and according to value the slideUp and slideDown method will be called.
Complete Solution
Now here is complete working solution for it. Set style for your element.
<script src="Scripts/jquery-2.0.0.js"></script> <script src="Scripts/knockout-2.2.1.js"></script> <style> .box { border: 1px black solid; width: 650px; margin-left: auto; margin-right: auto; } .box .title { padding: 8px; background-color: #e1e1e1; border-bottom: 1px black solid; } .box .title .showButton { float: right; } .box .desc { padding: 8px;font-size:12px; } </style>
Set your element, assign CSS classes and set binding etc.
<div class="box"> <div class="title"> <span data-bind="html: title"></span> <a class="showButton" href="#" data-bind="html: showButtonText, event: { click: onShow }"></a> </div> <div data-bind="collapseVisible: displayDetail, slideDuration: 1000" class="desc"> Lorem Ipsum is simply dummy... </div> </div>
Finally create your view model, custom binding and bind them to your page.
<script type="text/javascript"> var vm = { title: "Collapsible Box", showButtonText: ko.observable('Show'), displayDetail: ko.observable(false), onShow: function () { var newVal = !this.displayDetail(); this.displayDetail(newVal); this.showButtonText(newVal ? "Hide" : "Show"); } }; ko.bindingHandlers.collapseVisible = { init: function (element, valueAccessor) { var value = valueAccessor(); $(element).toggle(ko.utils.unwrapObservable(value)); // Use "unwrapObservable" so we can handle // values that may or may not be observable }, update: function (element, valueAccessor, allBindingsAccessor) { var value = valueAccessor(); var allBindings = allBindingsAccessor(); // Grab some more data from another binding property var duration = allBindings.slideDuration || 500; ko.utils.unwrapObservable(value) ? $(element).slideDown(duration) : $(element).slideUp(duration); } }; ko.applyBindings(vm); </script>