JavaScript通用层次式下拉列表框
下拉列表框在各种软件界面,包括网页环境中都是十分常用的组件,或称元素。这种元素提供了对同类对象进行选择的一种方式。然而,我们在项目实践中发现,有些数据记录之间具有层次关系。把这类数据集载入到下拉列表框中供用户选择时,我们就有必要使列表框中的选项反映出数据记录的层次关系。因此,我们尝试实现了基于Prototype JavaScript框架的层次式下拉列表框。
我们的层次式下拉列表框具有如下特点。每个下拉列表框中的选项包含数据集中的一个层次。当某个选项被选中时,若其有子选项,则在紧随当前列表框元素的位置,会弹出新的下拉列表框,包含相应子选项供用户选择。由此可以看出,所谓层次式下拉列表框本质上是一个具有层次关系的下拉列表框序列。我们把这种元素表达为类。你只要在需要的地方创建该类的一个对象,便可获得这样一个层次式下拉列表框。如果你对我们的层次式下拉列表框感兴趣,或你正需要这样一种元素来丰富你的页面,那么请到Kudelabs的代码库去获取这个组件。同时,在下面的例子页面中,我们详细地示范了如何创建和使用我们的层次式下拉列表框,并显示出其效果。
请点击例子,体验一下我们的层次式下拉列表框。
Javascript 通用筛选功能
如何对 HTML 上的元素,如表格,列表或者 DIV 等等按照关键字进行筛选呢?最简单的方法是通过循环遍历各个元素,对比关键字与元素的 inner html 内容。但是,这个方法有一个很大的缺陷。例如,如果对跨行的表格 tr 进行筛选呢?在显示上,跨行的 tr 与其他 tr 显示在同一行,但是它们的 inner html 往往却不同。而代码上,它们又在不同的 tr 上。所以,隐藏了跨行的 tr 会破坏整个表格的布局。对于这个问题,我们的解决方案是对任何可筛选的元素添加匹配字符串变量,这样,筛选功能就变得更加通用和灵活了。因为,就算 tr 的内容不一样,我们仍然可以在代码中设置相同的匹配字符串变量,使其在筛选中被同样处理,显示或者隐藏。下面我们简单介绍筛选功能的 javascript:
<table>
<thead>
<tr>
<th>菜系</th>
<th>菜名</th>
<th>价钱</th>
</tr>
</thead>
<tbody id="food">
<tr id="tr_01"><td rowspan="3">粤菜</td><td>烧汁茄子</td><td>10.00</td></tr>
<tr id="tr_02"><td>烧鸭</td><td>20.00</td></tr>
<tr id="tr_03"><td>西芹炒百合</td><td>15.00</td></tr>
<tr id="tr_04"><td rowspan="2">东北菜</td><td>酱骨架</td><td>35.00</td></tr>
<tr id="tr_05"><td>火龙鱼</td><td>70.00</td></tr>
<tr id="tr_06"><td rowspan="x">湘菜</td><td>xx</td><td>xx.xx</td></tr>
...
<tr id="tr_0x"><td rowspan="x">潮菜</td><td>xx</td><td>xx.xx</td></tr>
...
<tr id="tr_0x"><td rowspan="x">越菜</td><td>xx</td><td>xx.xx</td></tr>
...
<tr id="tr_0x"><td rowspan="x">寿司</td><td>xx</td><td>xx.xx</td></tr>
...
<tr id="tr_0x"><td rowspan="x">清真</td><td>xx</td><td>xx.xx</td></tr>
...
</tbody>
</table>
function strip_spaces(stripee) {
return stripee.replace(/(^[ ]*) | ([ ]*$)/g,'');
}
function filter(id, criteria) {
var t = $(id);
if (!t) { return; }
t.getElementsByClassName('no_matched_notice').each(function(elem) {
elem.remove();
});
var notice_msg = 'No matching data found!';
criteria = strip_spaces(criteria);
empty_input = criteria.length === 0;
var matched_none = true;
t.childElements().each(function(elem) {
// if the user doesn't input anything, then show all the elements
if (!elem.matched_strs || empty_input) {
Element.show(elem);
} else {
// else find the element
matched = false;
elem.matched_strs.each(function(str) {
if (str.toUpperCase().indexOf(criteria.toUpperCase()) != -1) {
matched = true;
matched_none = false;
return;
}
});
matched ? Element.show(elem) : Element.hide(elem);
}
});
if (matched_none && !empty_input) {
var tag = t.tagName;
var ins = null;
switch (tag) {
case "TBODY":
case "TABLE":
ins = new Insertion.Bottom(t, "<tr class=\"no_matched_notice\"><td colspan='100'>" + notice_msg + "</td></tr>");
break;
case "OL":
case "UL":
ins = new Insertion.Bottom(t, "<li class=\"no_matched_notice\">" + notice_msg + "</li>");
break;
default:
ins = new Insertion.Bottom(t, "<" + tag + " class=\"no_matched_notice\">" + notice_msg + "</" + tag + ">");
break;
}
}
}
在 HTML中,我们需要做的工作是:
1) 添加匹配字符串到所有可匹配元素上,为了能够匹配多个关键字,将以数组的形式存储:
$('tr_01').matched_strs = ["粤菜", "烧汁茄子", "烧鸭", "西芹炒百合"];
$('tr_02').matched_strs = ["粤菜", "烧汁茄子", "烧鸭", "西芹炒百合"];
$('tr_03').matched_strs = ["粤菜", "烧汁茄子", "烧鸭", "西芹炒百合"];
$('tr_04').matched_strs = ["东北菜", "酱骨架", "火龙鱼"];
$('tr_05').matched_strs = ["东北菜", "酱骨架", "火龙鱼"];
...
2) 添加筛选关键字的输入框:
<input id="keyword" type="text" />
3) 绑定 filter 函数到输入框事件上:
$('keyword').onkeyup = function() {filter('food', this.value);};
$('keyword').onchange = function() {filter('food', this.value);};
恭喜你,完成了!
