I'm trying to build some accordion like functionality with KnockoutJS and custom bindings
So far I've got it half way there:
<div data-bind="foreach: items">
<div class="item"> <span data-bind="text: name() ? name() : 'New Thing'"></span>
<br /> <a href="#" data-bind="click: $parent.toggleVisibility">Show / Hide</a>
<div class="fullDetails" data-bind="accordion: visible">
<label>Name:</label>
<input type="text" data-bind="value: name" />
</div>
</div>
</div>
<a href="#" data-bind="click: addItem">Add new item</a>
and my Javascript
var ViewModel = function () {
var self = this;
self.items = ko.observableArray([new ItemModel()]);
self.addItem = function (item) {
ko.utils.arrayForEach(self.items(), function (i) {
i.visible(false);
});
self.items.push(new ItemModel())
};
self.toggleVisibility = function (item) {
ko.utils.arrayForEach(self.items(), function (i) {
i.visible(false);
});
item.visible(!item.visible())
};
};
var ItemModel = function () {
this.visible = ko.observable(true);
this.name = ko.observable();
}
ko.bindingHandlers.accordion = {
init: function (element, valueAccessor) {
var value = valueAccessor();
$(element).toggle(ko.utils.unwrapObservable(value));
},
update: function (element, valueAccessor) {
var value = valueAccessor();
ko.utils.unwrapObservable(value) ? $(element).slideDown() : $(element).slideUp();
}
};
ko.applyBindings(new ViewModel());
Also on JSFiddle: http://jsfiddle.net/alexjamesbrown/PPAsK/
Some issues I am having:
Show/Hide link
This seems to scroll up and then immediately scroll down again.
Adding a new item
I was trying to get the item currently visible to slideUp
, then the new item to slideDown
but this isn't working - whatever item is visible slidesUp, but the new item just appears
you are always showing on show/hide link click because the item previously gets reset to visible(false). Fix:
ko.utils.arrayForEach(self.items(), function (i) {
//don't bother with the item, we take care of it later
if (item !== i) {
i.visible(false);
}
});
you need to start with the added item hidden, then apply self.toggleVisibility(newItem) This will take care of hiding the others and animating the new one
self.addItem = function (item) {
var newItem = new ItemModel();
//make sure it starts hidden
newItem.visible(false);
self.items.push(newItem);
//highlight it the usual way
self.toggleVisibility(newItem);
};
fixed version here: http://jsfiddle.net/tudorilisoi/3LzbT/8/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.