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/0URI第一个分段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>

猜你喜欢

转载自blog.csdn.net/weixin_39214481/article/details/80736775