我正在尝试对Bootstrap折叠/手风琴组件实施搜索功能。这个功能有用......有点儿。我遇到的问题是将实际的引导功能与搜索术语以及控件的打开和关闭方式结合在一起。
搜索词应该查看数组的最低级别,如果搜索词包含在该文本值中,则打开面板。
我正在使用Knockout JS来控制viewmodel,显然是用于组件显示的Bootstrap。
http://jsfiddle.net/ascendantofrain/d0rt2b29/6/
HTML
<script type="text/html" id="accordion-template">
<!-- ko foreach: accordionData -->
<div class="grouping-wrapper">
<div class="group-by">
<!-- ko if: $parent.searchEnabled -->
<input type="search" class="search-input show" name="search_group-by" placeholder="Search" data-bind="textInput: $parent.searchTerm" />
<!-- /ko -->
<div class="group-dropdown" data-bind="css: $parent.helperClass">
<div data-bind="attr: { id: 'accordion-' + id }" class="group-dropdown-top-level">
<!-- ko if: $data.hasOwnProperty('children') && children.length > 0 -->
<div class="panel" data-bind="foreach: children">
<!-- ko if: $parents[1].leafNodesCount($data) > 0 -->
<span data-toggle="collapse" data-bind="attr: { 'data-parent': '#accordion-' + $parent.id, href: '#collapse-' + id }, css: 'group-' + ($index() + 1)">
<!-- ko text: text --><!-- /ko -->
<i class="icon icon-arrow-right"></i>
</span>
<div class="collapse group-dropdown-second-level" data-bind="attr: { id: 'collapse-' + id, 'isOpen': li_attr.isOpen }">
<!-- ko if: $data.hasOwnProperty('children') && children.length > 0 -->
<div class="panel" data-bind="foreach: children">
<!-- ko if: children.length > 0 -->
<span data-toggle="collapse" data-bind="attr: { 'data-parent': '#collapse-' + $parent.id, href: '#collapse-' + id }">
<!-- ko text: text --><!-- /ko -->
<i class="icon icon-arrow-right"></i>
</span>
<div class="collapse group-dropdown-third-level" data-bind="attr: { id: 'collapse-' + id, 'isHierarchy': li_attr.isHierarchy, 'isOpen': li_attr.isOpen }">
<!-- ko if: $data.hasOwnProperty('children') && children.length > 0 -->
<!-- ko foreach: children -->
<div class="panel" data-bind="click: $parents[3].action, text: text, css: { in: $parents[3].search($data) }"></div>
<!-- /ko -->
<!-- /ko -->
</div>
<!-- /ko -->
</div>
<!-- /ko -->
</div>
<!-- /ko -->
</div>
<!-- /ko -->
</div>
</div>
</div>
</div>
<!-- /ko -->
</script>
<accordion params="data: metricData, searchEnabled: true"></accordion>
JS
ko.bindingHandlers.accordionToggleNodePropertyOnClick = {
init: function(element, valueAccessor, allBindings, viewModel) {
var options = ko.unwrap(valueAccessor());
//$(element).on('click', function() {
// options.property(!options.property());
//});
}
};
ko.components.register('accordion', {
viewModel: function (params) {
var self = this;
self.accordionData = params.data || [];
self.accordionType = params.accordionType || 'default';
self.searchEnabled = params.searchEnabled || false;
self.panelPrefix = params.panelPrefix || 'collapse';
self.helperClass = params.helperClass || '';
self.leafNodesCount = function (node) {
var cnt = 0;
_.each(node.children, function (c) {
_.each(c.children, function () {
cnt++;
});
});
return cnt;
};
self.action = function () {
var action = params.action || 'default';
if (action === 'none') {
return;
}
if (action === 'pivot') {}
};
self.searchTerm = ko.observable('');
self.search = function (node) {
if (self.searchTerm() && self.searchTerm().length >= 3) {
_.each(self.accordionData, function (c) {
_.each(c.children, function (c1) {
var open1 = _.find(c1.children, function (c2) {
return c2.li_attr.isOpen() === true;
});
c1.li_attr.isOpen(open1 ? true : false);
if (open1) {
$('#' + self.panelPrefix + '-' + c1.id).collapse('show');
} else {
$('#' + self.panelPrefix + '-' + c1.id).collapse('hide');
}
_.each(c1.children, function (c2) {
var open = _.find(c2.children, function (c3) {
return c3.text.toLowerCase().indexOf(self.searchTerm()) !== -1;
});
c2.li_attr.isOpen(open ? true : false);
if (open) {
$('#' + self.panelPrefix + '-' + c2.id).collapse('show');
} else {
$('#' + self.panelPrefix + '-' + c2.id).collapse('hide');
}
});
});
});
return node.text.toLowerCase().indexOf(self.searchTerm()) !== -1 ? true : false;
}
};
self.toggleOpen = function(node) {
};
},
template: {
element: 'accordion-template'
}
});
function daVM() {
// Define Alerts Configuration
self.metricData = [{
id: '1',
text: 'Define Alerts Metric Tab',
children: [{
id: '1-1',
text: 'First',
li_attr: {
isOpen: ko.observable(false)
},
children: [{
id: '2-1',
text: 'Second Level 1',
li_attr: {
isHierarchy: false,
isOpen: ko.observable(false)
},
children: [{
id: '2-3-4',
text: 'Thard Level 1',
li_attr: {
isHierarchy: false,
isOpen: ko.observable(false)
}
}]
}, {
id: '3-1',
text: 'Second Level 2',
li_attr: {
isHierarchy: false,
isOpen: ko.observable(false)
},
children: [{
id: '3-1',
text: 'Third Level 1',
li_attr: {
isHierarchy: false,
isOpen: ko.observable(false)
}
}]
}, {
id: '4-1',
text: 'Second Level 3',
li_attr: {
isHierarchy: false,
isOpen: ko.observable(false)
},
children: [{
id: '4-1',
text: 'Therd Level 1',
li_attr: {
isHierarchy: false,
isOpen: ko.observable(false)
}
}]
}],
}]
}];
}
ko.applyBindings(new daVM());