KO Bootstrap bindings.
by gbos
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
<div class="container">
<ul data-bind="tbsTabs: tabIdx">
<li>aaaaaa</li>
<li>bbbbb</li>
<li>cccccccc</li>
<li>ddddd</li>
<li>dddddd</li>
<li>eeeeee</li>
</ul>
<br>
<input data-bind="value: tabIdx">
<br>
<hr>
<tbs-pager params="total: total, pageSize: pageSize, pageIndex: pageIndex"></tbs-pager>
<br>
<input data-bind="value: total">
<input data-bind="value: pageSize">
<input data-bind="value: pageIndex">
<hr>
<button class="btn" data-bind="click: show">Dialog</button>
</div>
<!-- Modal -->
<div class="modal fade" tabindex="-1" data-bind="tbsModal: modalOpen">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
JavaScript
(function(ko) {
//'use strict';
Element.prototype.on = Element.prototype.addEventListener;
NodeList.prototype.forEach = Array.prototype.forEach;
ko.bindingHandlers.tbsTabs = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var val = valueAccessor();
var $ = element.querySelector.bind(element),
$$ = element.querySelectorAll.bind(element);
element.classList.add('nav', 'nav-tabs');
$('li').classList.add('active');
var eventHandlers = []; // array of objects: target, eventName, handler
$$('li').forEach(function (li, i) {
var a = document.createElement('a');
a.setAttribute('href', '#');
a.textContent = li.textContent;
li.replaceChild(a, li.firstChild);
a.on('click', function(evt) {
eventHandlers.push({target: evt.target, eventName: evt.type, handler: arguments.callee});
val(i);
$('li.active').classList.remove('active');
$$('li')[i].classList.add('active');
});
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
this.eventHandlers.forEach(function (eh) { eh.target.removeEventListener(eh.eventName, eh.handler); });
$$('li').forEach(function (li, i) {
li.replaceChild(li.firstChild.firstChild, li.firstChild);
});
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var val = valueAccessor();
var $ = element.querySelector.bind(element),
$$ = element.querySelectorAll.bind(element);
var idx = val() || 0;
$('li.active').classList.remove('active');
$$('li')[idx].classList.add('active');
}
};
})(ko);
/**
* Twitter bootstrap pagination component.
* component name: 'tbs-pager'
* component template id: 'tbs-pager'
* params: total: nbr of elements, pageSize: nr of elements to show on 1 page, pageIndex: currently selected page (0 based) (observable).
*
*/
(function(ko) {
...