<转>Javascript Infinite Level Select 无限级联动下拉菜单

Overview

  • 多级联动,支持Ajax动态获取数据并缓存数据,动态生成下级select菜单,设置动态生成"option"第一个条目作为提示项,自动选择唯一选项的菜单,设置回调函数在onChange事件触发时获取下拉菜单相关信息。 详细功能及设置请见DEMO。

Requirement

  • jQuery v1.6+

License

Author

Update

Download

Settings

  • 调用方式: var linkageSel = new LinkageSel(opts);
  • opts参数列表:
    参数名 类型 默认值 可选 注释
    data Object null 指定本地数据源。至少要指定data、url、ajax其中一个的值,data可以和ajax配合使用
    url String   url地址,一次性远程获得所有数据
    ajax String   ajax远程获得下级菜单数据
    autoBind Boolean true 自动生成下级select菜单
    autoHide Boolean true 自动隐藏下级菜单.若false,则可配合level固定值使用
    hideWidth Boolean true 如果设定自动隐藏下级菜单,则是否同时隐藏其占位宽度 true:'display:none'||false: 'visibility:hidden'
    autoLink Boolean true 如果只有唯一选项则选中并联动下级
    defVal Integer|Array true 默认选择项,指定多级菜单默认选项需要使用数组方式,并且按照层级顺序排列
    head String|Number|false 请选择 作为下拉菜单第一选择名称自动添加, 空字符('')有效。若false则不自动添加
    level Integer 20 限定层级防止死循环
    loaderImg String images/ui-anim_basic_16x16.gif loader动态图标
    root Integer|Array   根所在位置,决定获取数据入口.不适用于ajax模式
    select String|Array     jQuery选择器字符串或者jQuery选择器字符串数组
    selClass String LinkageSel 应用于所有下拉菜单的class属性,包括预先生成的对象
    selStyle String margin-left:1px; 应用于下拉菜单的style属性
    minWidth Integer 120 下拉菜单最小宽度
    maxWidth Integer 300 下拉菜单最大宽度
    fixWidth Integer 0 下拉菜单固定,此设置将覆盖minWidth、maxWidth的效果
    onChange Function   菜单选择变化时回调函数
    mvcQuery Boolean false 置true后ajax请求会生成符合MVC格式的URI, 比如 http://linkagesel.xiaozhong.biz/district/get_nodes/0 URI第一个分段district为controller控制器名, 第二分段get_nodes为方法名, 第三分段为节点的id值
    此时 ajax值需要设定为MVC格式, 比如 ajax: 'district/get_nodes'
    dataReader Object {id: 'id', name: 'name', cell: 'cell'} 自定义数据结构中键名, 比如 {id: 'gid', name: 'value', cell: 'subcell'}
  • 实例方法:
    方法名 参数及其类型 返回值类型 可链式操作 注释
    changeValues parm1:Integer|Array
    parm2: Boolean[option=false]
    Object 手动改变选单值,可选触发onchange用户自定义回调函数
    getSelectedValue idx:Integer String   返回select的值。不带参数获得联动select中'最后一个'有选择select菜单的选择值; 如果大于等于0则 返回第 idx 个菜单(从0开始)选择值,如果都无有选择(一般是初始化后)则返回 null
    getSelectedArr   Array   返回数组包含所有select选择值
    getSelectedData key: String
    idx: Interger[option] 空则返回当前最后一个有选择项选单的选项项值对象
    Object   返回第idx级(从0开始)菜单所选项目的对应数据的对象
    getSelectedDataArr key: String[option] Array   获得所有有选择菜单的数据对象或对象值,遇到第一个未选择的停止。 对于返回值,如果指定key则返回 data[key] 对应值: int|str|null; 如果未指定key返回数据对象data: obj|null
    onChange callback: Function;   选项变化时回调函数,callback内的this被绑定到当前实例对象(可见Demo2)
    reset     回复到初始状态
    resetAll     回复到初始状态,包括默认选择项及初始数据

Demo

SyntaxHighlighter语法高亮比较耗资源,重复刷新页面可能会导致内存占用攀高

加载:

1
2
3
4
<script src="js/jquery.js"></script>
<script src="js/comm.js"></script>
<script src="js/linkagesel-min.js"></script>

数据结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
    var data = {
        "key": {"name": nameValue, "otherAttr": otherAttrVal, "cell": { ... },
    };
</script>
key为条目的索引值,也等于 <option value="VALUE" > </option> 中的 value 值,必须有
name为条目的显示值,即 <optio> name<option> ,必须有
otherAttr其他属性,比如code,price,但不能为cell,        可选
 
cell为下级菜单包含的数据内容,包含同样的key/name/cell格式, 可选
     
比如:
var data1 = {
    1: {name: '蔬菜',
        cell: {
            10: {name: '菠菜', price: 4 },
            11: {name: '茄子', price: 5}
        }
};
蔬菜|-->菠菜 (id等于1, price为4)
    |-->茄子 (id等于10, price为5)

Demo1:开始一个简单的

 
 

获得最后一个有效选项value

获得最后一个有效选项属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<script>
$(document).ready(function(){
    var data1 = {
        1: {name: '蔬菜', cell: { 10: {name: '菠菜', price: 4 }, 11: {name: '茄子', price: 5} }
        },
        3: {name: '水果',
            cell: {
                20: {name: '苹果', cell: {201: {name: '红富士', price: 20}  } } ,
                21: {name: '桃',
                        cell: {
                            210: {name: '猕猴桃', price: 30},
                            211: {name: '油桃', price: 31},
                            212: {name: '蟠桃', priece: 32} }
                }
            }
        },
        9: {name: '粮食',
            cell: {
                30: {name: '水稻',    cell: { 301: {name: '大米', cell: {3001: {name: '五常香米', price: 50}} } }   }
            }
        }
    };
    var opts = {
            data: data1,
            select: '#demo1'
    };
    var linkageSel1 = new LinkageSel(opts);
     
    $('#getSelectedValue').click(function() {
        var v = linkageSel.getSelectedValue();
        alert(v);
    });
     
    $('#getSelectedData').click(function() {
        var name = linkageSel.getSelectedData('name'),
            price = linkageSel.getSelectedData('price');
        alert('名称:' + name + ' 价格:' + price);
 
    });
});
</script>

Demo2:省市地三级联动, 本地加载数据。onChange时获取相关属性

 
 
 
获得各级菜单所选值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<select id="demo2"></select>
地址:<input type="text" value="tip" id="tip" size="50" />
<input type="button" title="获得各级菜单所选值" value="button3" id="getValueArr2"/>
 
<script src="js/district-all.js"></script>
<script>
    var opts = {
            data: districtData,     // districtData为district-all.js中定义的变量
            selStyle: 'margin-left: 3px;',
            select:  '#demo2'
    };
             
    var linkageSel2 = new LinkageSel(opts);
    districtData = opts = null; // 如果数据量大最好在创建LinkageSel实例之后清空
     
    $('#getValueArr2').click(function() {
        var arr = linkageSel2.getSelectedArr();
        alert(arr.join(','));
    });
     
    linkageSel2.onChange(function() {
        var input = $('#tip'),
            d = this.getSelectedDataArr('name'),    // 所有有选定菜单的name. this === linkageSel2
            zip = this.getSelectedData('zip'),      // 最末选定菜单的zip数据值
            arr = [];
        for (var i = 0, len = d.length; i < len; i++) {
            arr.push(d[i]);
        }
        zip = zip ? ' 邮编:' + zip : '';
        input.val(arr.join(' ') + zip);
    });
</script>

Demo3:省市地三级联动, Ajax动态获取下级数据

 
 
1
2
3
4
5
6
7
8
9
10
<script>
    var opts = {
            ajax: 'district_crud.php?aj=15',
            selStyle: 'margin-left: 3px;',
            select: '#demo3'
    };
             
    var linkageSel3 = new LinkageSel(opts);
</script>

Demo4:1级数据JS中赋值, Ajax动态获取2、3级数据

 
 
1
2
3
4
5
6
7
8
9
10
11
12
<script>
    var data4 = {2: {name: '北京市'}, 4:{name: '河北省'} };
    var opts4 = {
            data: data4,
            ajax: 'district_crud.php?aj=15',    // ajax与data配合获取未定义的下级数据
            selStyle: 'margin-left: 3px;',
            select: '#demo4'
    };
             
    new LinkageSel(opts4);
</script>

Demo5:指定默认选项

 
 
1
2
3
4
5
6
7
8
9
10
11
12
<script src="js/district-all.js"></script>
<script>
    var opts5 = {
            data: districtData,         // districtData为district-all.js中定义的变量
            selStyle: 'margin-left: 3px;',
            select:  ['#demo5'],        // select的值可以是个数组
            defVal: [4]
    };
             
    var linkageSel5 = new LinkageSel(opts5);
</script>

Demo6:指定默认选项, 静态动态混合select

 
 
1
2
3
4
5
6
7
8
9
10
11
<select id="demo61"></select> <select id="demo62"></select>
<script>
    var opts6 = {
            data: districtData,
            select:  [ '#demo61', '#demo62' ],      // 2个静态,剩余的动态生成
            defVal: 4
    };
             
    var linkageSel6 = new LinkageSel(opts6);
</script>

Demo7:指定多个默认选项, 动态生成select

 
 
1
2
3
4
5
6
7
8
9
10
11
12
<select id="demo7"></select>
<script>
    var opts7 = {
            data: districtData,
            selStyle: 'margin-left: 3px;',
            select:  '#demo7',      // 只有一个
            defVal: [5, 256]        // 可是两个哟
    };
             
    var linkageSel7 = new LinkageSel(opts7);
</script>

Demo8:定义数据入口

山西省:
 
1
2
3
4
5
6
7
8
9
10
11
12
山西省:<select id="demo8"></select>
<script>
    var opts8 = {
            data: districtData,
            root: 5,                // 数据入口
            selStyle: 'margin-left: 3px;',
            select:  '#demo8'      
    };
             
    var linkageSel8 = new LinkageSel(opts8);
</script>

Demo9:指定数据入口, 多个默认选项

山西省:
 
1
2
3
4
5
6
7
8
9
10
11
12
13
山西省:<select id="demo9"></select>
<script>
    var opts9 = {
            data: districtData,
            root: 5,                // 数据入口
            selStyle: 'margin-left: 3px;',
            select:  '#demo9',     
            defVal: [256, 257]      // 两个哟
    };
             
    var linkageSel9 = new LinkageSel(opts9);
</script>

Demo10:指定深层数据入口, 默认选项

山西省 太原市:
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
山西省:<select id="demo10"></select>
<script>
    var opts10 = {
            data: districtData,
            root: [5, 256],             // 深层数据入口
            selStyle: 'margin-left: 3px;',
            select:  '#demo9',     
            defVal: 257
    };
             
    var linkageSel10 = new LinkageSel(opts10);
     
</script>

Demo11:固定宽度

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="demo11"></select>
<script>
    var opts11 = {
            data: districtData,
            selStyle: 'margin-left: 3px;',
            select: '#demo11',
            fixWidth: 200,          // 固定宽度
            head: '想好了选哪个么' // 自定义
    };
             
    var linkageSel11 = new LinkageSel(opts11);
</script>

Demo12:不使用提示条目

 
 
1
2
3
4
5
6
7
8
9
10
11
<select id="demo12"></select>
<script>
    var opts12 = {
            data: districtData,
            select: '#demo12',
            head: false // 不使用自动生成提示作为菜单第一项
    };
             
    var linkageSel12 = new LinkageSel(opts12);
</script>

Demo13:一次性远程获取数据,不适合大数据量情况

 
 
1
2
3
4
5
6
7
8
9
10
<select id="demo13" > </select>
<script>
    var opts13 = {
            select: '#demo13',
            url: 'exampledata.php'
    };
             
    var linkageSel13 = new LinkageSel(opts13);
</script>

Demo14:1级菜单数据JS文件加载, Ajax动态获取2、3级数据

 
 
1
2
3
4
5
6
7
8
9
10
11
12
<script src="js/district-level1.js"></script>
<script>
    var opts14 = {
            data: districtData1,        //  注意变量名
            ajax: 'district_crud.php?aj=15',    // ajax与data配合获取未定义的下级数据
            selStyle: 'margin-left: 3px;',
            select: '#demo14'
    };
             
    var linkageSel14 = new LinkageSel(opts14);
</script>

Demo15:1级菜单数据JS文件加载, Ajax动态获取2、3级数据。手动设定值,可用于编辑页面的自动选定

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body>
    <button type="button" onclick="javascript: ls15.changeValues([23, 2244])">changeValues</button>
</body>
 
<script src="js/district-level1.js"></script>
<script>
    var ls15;   // must outside of ready() !
    $(document).ready(function(){
        var opts15 = {
                data: districtData1,        //  注意变量名
                ajax: 'district_crud.php?aj=15',    // ajax与data配合获取未定义的下级数据
                selStyle: 'margin-left: 3px;',
                select: '#demo15'
        };
                 
        window.ls15 = new LinkageSel(opts15);
    });
</script>

Demo16:自定义数据key名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script>
$(document).ready(function(){
    var data16 = {
        1: {gid: 1, value: 'IBM',
            sub: {
                10: {gid: 10, value: 'X3650'},
                11: {gid: 11, value: 'X3860'}
            }
        },
        3: {gid: 3, value: 'HP',
            sub: {
                20: {gid: 20, value: '360'} ,
                21: {gid: 21, value: '380'}
            }
        },
        9: {gid: 9, value: 'DELL',
            sub: {
                29: {gid: 29, value: 'R710'}
                30: {gid: 30, value: 'R720'}
            }
        }
    };
    var opts = {
            data: data16,
            select: "[name='demo16']",
            dataReader: {id: 'gid', name: 'value', cell: 'sub'} // self defined data key name
    };
    var ls16 = new LinkageSel(opts);
});
</script>

Demo17:ajax获取数据且多个默认值. 注意与demo7的区别

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
<select id="demo17"></select>
<script>
    var opts17 = {
            //data: districtData,   // demo7
            ajax: 'district_crud.php?aj=15',
            selStyle: 'margin-left: 3px;',
            select:  '#demo17',
            defVal: [5, 256, 257]
    };
             
    var linkageSel17 = new LinkageSel(opts17);
</script>

Demo18:不使用提示条目,指定默认值

 
 

 

1
2
3
4
5
6
7
8
9
10
11
12
<select id="demo18"></select>
<script>
    var opts18 = {
            data: districtData,
            select: '#demo18',
            defVal: [5, 256, 257],
            head: false // 不使用自动生成提示作为菜单第一项
    };
             
    var linkageSel18 = new LinkageSel(opts18);
</script>

posted on 2015-09-28 22:33  hahahahahai12  阅读(771)  评论(0)    收藏  举报

导航