标签:
业务中经常需要对数据进行下拉框的联动选择操作,可以假设成省份城市 省份城市县这样的多级联动
客户那边提供的数据大多为excel,格式都属于标准一行列的
假设需要对省份城市进行联动 实现如下
1 var pcd = []; 2 pcd[0] = [‘北京‘, ‘北京‘]; 3 pcd[1] = [‘天津‘, ‘天津‘]; 4 pcd[2] = [‘河北‘, ‘石家庄‘]; 5 pcd[3] = [‘河北‘, ‘唐山‘]; 6 pcd[4] = [‘山西‘, ‘太原‘]; 7 pcd[5] = [‘辽宁‘, ‘沈阳‘]; 8 pcd[6] = [‘吉林‘, ‘长春‘]; 9 pcd[7] = [‘黑龙江‘, ‘哈尔滨‘]; 10 pcd[8] = [‘上海‘, ‘上海‘]; 11 pcd[9] = [‘江苏‘, ‘南京‘]; 12 pcd[10] = [‘江苏‘, ‘无锡‘]; 13 pcd[11] = [‘江苏‘, ‘苏州‘]; 14 pcd[12] = [‘浙江‘, ‘杭州‘]; 15 pcd[13] = [‘浙江‘, ‘宁波‘]; 16 pcd[14] = [‘浙江‘, ‘温州‘]; 17 pcd[15] = [‘安徽‘, ‘合肥‘]; 18 pcd[16] = [‘福建‘, ‘福州‘]; 19 pcd[17] = [‘江西‘, ‘南昌‘]; 20 pcd[18] = [‘山东‘, ‘济南‘]; 21 pcd[19] = [‘山东‘, ‘青岛‘]; 22 pcd[20] = [‘河南‘, ‘郑州‘]; 23 pcd[21] = [‘湖北‘, ‘武汉‘]; 24 pcd[22] = [‘湖南‘, ‘长沙‘]; 25 pcd[23] = [‘广东‘, ‘广州‘]; 26 pcd[24] = [‘广东‘, ‘深圳‘]; 27 pcd[25] = [‘广西‘, ‘南宁‘]; 28 pcd[26] = [‘重庆‘, ‘重庆‘]; 29 pcd[27] = [‘四川‘, ‘成都‘]; 30 pcd[28] = [‘云南‘, ‘昆明‘]; 31 pcd[29] = [‘陕西‘, ‘西安‘]; 32 33 Array.prototype.contains = function (e) { 34 for (var i = 0; i < this.length; i++) { 35 if (this[i] === e) { 36 return true; 37 } 38 } 39 return false; 40 } 41 42 document.getElementById("aprovincename").onchange = function () { 43 bindCity(this.value); 44 } 45 document.getElementById("acityname").onchange = function () { 46 bindDealer(this.value); 47 } 48 49 function bindProvince() { 50 var items = new Array(); 51 var el = document.getElementById("aprovincename"); 52 el.length = 0; 53 el.options.add(new Option(‘请选择省份‘, ‘0‘)); 54 bindCity(0); 55 for (var i = 0, len = pcd.length; i < len; i++) { 56 if (!items.contains(pcd[i][0])) { 57 items.push(pcd[i][0]); 58 el.options.add(new Option(pcd[i][0], pcd[i][0])); 59 } 60 } 61 } 62 function bindCity(pid) { 63 64 var el = document.getElementById("acityname"); 65 el.length = 0; 66 el.options.add(new Option(‘请选择城市‘, ‘0‘)); 67 68 if (pid === 0) { 69 return; 70 } 71 var items = new Array(); 72 for (var i = 0, len = pcd.length; i < len; i++) { 73 if (pcd[i][0] === pid && !items.contains(pcd[i][1])) { 74 items.push(pcd[i][1]); 75 el.options.add(new Option(pcd[i][1], pcd[i][1])); 76 } 77 } 78 } 79 80 bindProvince();
基本需求就是这样的 在此基础上如果需要设置下拉框选项的value值为ID值 那么需要修改相应方法绑定的数据索引
把这部分功能参数封装一下,让其满足多级联动
(function () { var Linkage = function (paras) { var _$ = function (id) { return document.getElementById(id); } var items = [], item = {}, data = paras.data; var drop = function (options) { this.element = _$(options.id); this.text = options.text || ‘请选择‘; this.value = options.value || ‘0‘; options.selected && (this.selected = options.selected); options.filter && (this.filter = options.filter); options.datachange && (this.datachange = options.datachange); if (items.length > 0) { this.prevdrop = items[items.length - 1]; var self = this; this.prevdrop.element.onchange = function () { self.bind(); } this.prevdrop.nextdrop = this; if (options.textIndex == undefined) { options.textIndex = Math.max(this.prevdrop.textIndex, this.prevdrop.valueIndex) + 1; } } this.textIndex = options.textIndex || items.length; this.valueIndex = options.valueIndex || this.textIndex; }; drop.prototype.bind = function () { var self = this, element = self.element, currentData = [], filterObj = {}, nextbind = false; element.length = 0; element.options.add(new Option(self.text, self.value)); self.nextdrop && self.nextdrop.bind(); if (self.prevdrop && self.prevdrop.element.value == self.prevdrop.value) { self.datachange && self.datachange(self.element, []); return; } for (var i = 0; i < data.length; i++) { if (self.prevdrop) { //如果此条数据在上级未使用跳过 if (self.prevdrop.element.value != data[i][self.prevdrop.valueIndex]) { continue; } //如果上级存在过滤方法 执行 if (self.prevdrop.filter) { var pf = self.prevdrop.filter(data[i]); if (pf == undefined ? false : !pf) { continue; } } } currentData.push(data[i]); var text = data[i][self.textIndex]; //排重 if (filterObj[text] != undefined) continue; filterObj[text] = text; //如果存在过滤方法进行过来处理 调用方式有待优化 if (self.filter) { var f = self.filter(data[i]); if (f == undefined ? false : !f) { continue; } } var option = new Option(text, data[i][self.valueIndex]); element.options.add(option); //如果是选定的内容 设置选项选中并设置调用下一个的绑定方法 if (self.selected && (typeof self.selected == ‘function‘ ? self.selected() : self.selected) == text) { option.selected = true; nextbind = true; } } //如果选项中只有一个数据项 删除默认选项并设置调用下一个的绑定方法 if (element.length == 2) { element.remove(0); nextbind = true; } self.datachange && self.datachange(element, currentData); if (nextbind) { self.nextdrop && self.nextdrop.bind(); } } drop.prototype.gettext = function () { return this.element.options[this.element.selectedIndex].innerHTML; }; var add = function (optons) { var d = new drop(optons); items.push(d); item[item.id] = d; } var bind = function () { items[0].bind(); paras.success && paras.success(); } for (var i = 0; i < paras.items.length; i++) { add(paras.items[i]); } bind(); return { items: items, item: item, bind: bind } } window.AL = Linkage; })();
调用方式:
//默认调用1 AL({ items: [{ id: ‘aprovincename‘ }, { id: ‘acityname‘ }], data: pcd, success: function () { console.log(‘执行完成‘); } }); //默认调用2 AL({ items: [ { id: ‘aprovincename‘, //过滤函数 只展示北京的数据 filter: function (item) { return item[0] == ‘北京‘; } }, { id: ‘acityname‘ }], data: pcd });
封装规则按照传递过来的对象数组顺序定义上下级关系,对象textIndex和valueIndex用于获取属于这个下拉框的索引值,默认情况使用当前对象的索引值,下一个取值为上一个最大索引+1;通过selected属性可以设置默认选择当前值
缺点:
1.JS不怎么会 效果是实现了 不知道是不是有更好的实现方式
2.数据格式支持上述pcd数组类的,喜欢后续能支持js对象,ajax请求接口拿到数据那种
3.只支持select下拉框联动 无法用于自定义div类的联动
--博客园不会怎么插入代码 直接在页面上面看效果--
标签:
原文地址:http://www.cnblogs.com/YangChengHu/p/5474997.html