本文转自:http://www.soulteary.com/2013/05/10/jquery-city-select.html
完成地址:http://thecdn.sinaapp.com/page/demo/jq-select/
GITHUB地址:https://github.com/soulteary/jquery-city-select
首先建立基础HTML结构:
1 | html:5>div#warp>((select#province>option[value="载入中"])+(select#city>option[value="载入中"])) |
预览地址:http://thecdn.sinaapp.com/page/demo/jq-select/step-1.html
1234567891011121314151617 | <!doctype html><htmllang="en"><head><metacharset="UTF-8"><title>省市下拉联动插件 @soulteary</title></head><body><divid="warp"><selectid="province"><optionvalue="载入中">载入中</option></select><selectid="city"><optionvalue="载入中">载入中</option></select></div></body></html> |
添加简单的样式。
地址:http://thecdn.sinaapp.com/page/demo/jq-select/step-2.html
12345678910111213141516171819202122232425262728293031323334353637383940 | <!doctype html><htmllang="en"><head><metacharset="UTF-8"><title>省市下拉联动插件 @soulteary</title><style>#warp{width:230px;height:80px;position:absolute;top:50%;left:50%;margin-left:-200px;margin-top:-130px;box-shadow:1px1px#3A393A;border:1pxsolid#222;font-size:13px;line-height:13px;}#province{margin:30px0030px;float:left;}#city{float:right;margin:30px30px00;}</style></head><body><divid="warp"><selectid="province"><optionvalue="载入中">载入中</option></select><selectid="city"><optionvalue="载入中">载入中</option></select></div></body></html> |
接着来写JS实现。
首先我们要进行数据定义,就是这个省市联动的数据是如何的关系。
有许多的省份,那么省份是包含在一个数组中的,然后每个省份中的城市包含在这些省份中,所以获得包含关系。
定义结构如下:(为了简单的开发,我随意写的数据,真实上线用自己定义的数据来替换即可)
123456789101112 | [ {'name':'北京市',id:100000,children:[ {'name':'海淀区',id:100003}, {'name':'西城区',id:100002}, {'name':'东城区',id:100001} ]}, {'name':'天津市',id:300000,children:[ {'name':'北辰区',id:300003}, {'name':'红桥区',id:300002}, {'name':'河西区',id:300001} ]} ]; |
简单的思考后,插件接受的参数为不定长,1~2个,为什么这么说呢。
场景A:数据要输出到一个下拉框中,即省份和城市输出一起。
场景B:数据分别初始化到两个下拉列表中。
那么设计插件框架如下:
12345678910111213141516171819202122232425 | ;(function($){ $.fn.extend({ "citylist":function(params){ params=$.extend({ param:'this is a param' },params); vartarget=$(this); if(!target.length){ returnthis; }elseif(target.length==1){ }else{ } console.log('PLUGN LOADED!:',target,params); returnthis; } });})(jQuery,'SOULTEARY.COM'); //USEAGE:$('#province').citylist();$('#province , #city').citylist(); |
接着来写实现代码:
地址:http://thecdn.sinaapp.com/page/demo/jq-select/step-3.html
首先是将省市数据初始化到两个不同的列表中的功能的实现,即:$('#province , #city').citylist();
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 | <scripttype="text/javascript"> //插件基础代码 ; (function($){ $.fn.extend({ "citylist":function(params){ params=$.extend({ param:'this is a param' },params); vartarget=$(this); if(!target.length){ returnthis; }elseif(target.length==1){ }else{ varprovince=target.eq(0); varcity=target.eq(1); varhtml=[],oItem; for(variteminparams.data){ oItem=params.data[item]; console.log(oItem) html.push('<option data-extra="'+oItem['id']+'">'+oItem['name']+'</option>'); } html=html.join(''); province.find('option').remove(); province.append(html); varprovinces=province.find('option'); province.on('change',function(){ varcurSelect=$(this).val(); provinces.each(function(k,v){ if($(v).val()==curSelect){ return(function(v){ varextra=$(v).attr('data-extra'); varhtml=[],oItem; for(variteminparams.data){ oItem=params.data[item]; if(oItem['id']==extra&&oItem.children){ oItem=oItem.children; for(varsIteminoItem){ html.push('<option data-extra="'+oItem[sItem]['id']+'">'+oItem[sItem]['name']+'</option>'); } break; } } html=html.join(''); city.find('option').remove(); city.append(html); }(v)); } }) }).trigger('change'); } returnthis; } }); })(jQuery,'SOULTEARY.COM'); //插件调用代码 ; $(function(){ vardata=[ {'name':'北京市',id:100000,children:[ {'name':'海淀区',id:100003}, {'name':'西城区',id:100002}, {'name':'东城区',id:100001} ]}, {'name':'天津市',id:300000,children:[ {'name':'北辰区',id:100003}, {'name':'红桥区',id:100002}, {'name':'河西区',id:100001} ]} ]; $('#province, #city').citylist({data:data}); });</script> |
接着我们继续写单独SELECT BOX的功能。
首先修改HTML结构,添加一个元素作为合并输出数据的容器。可以这么做:
12345 | <divid="warp2"> <selectid="all"> <optionvalue="载入中">载入中</option> </select></div> |
当然,为了有较好的心情去写实现代码,我们需要把CSS也写一下:
1234567891011121314151617 | #warp2{ width:230px; height:80px; position:absolute; top:50%; left:50%; margin-left:-200px; margin-top:0; box-shadow:1px1px#3A393A; border:1pxsolid#222; font-size:13px; line-height:13px; } #all{ margin:30px; } |
接着开始写实现代码:
12345678910111213 | varall=target;vardata=params.data;varhtml=[]; for(varooindata){ html.push('<option data-extra="'+data[oo]['id']+'">'+data[oo]['name']+'</option>'); for(varxxindata[oo].children){ html.push('<option data-extra="'+data[oo].children[xx]['id']+'">'+data[oo].children[xx]['name']+'</option>'); }}html=html.join('');all.find('option').remove();all.append(html); |
完整实现代码:
地址:http://thecdn.sinaapp.com/page/demo/jq-select/step-4.html
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 | <!doctype html><htmllang="en"><head> <metacharset="UTF-8"> <title>省市下拉联动插件 @soulteary</title> <style> #warp{ width:230px; height:80px; position:absolute; top:50%; left:50%; margin-left:-200px; margin-top:-130px; box-shadow:1px1px#3A393A; border:1pxsolid#222; font-size:13px; line-height:13px; } #province{ margin:30px0030px; float:left; } #city{ float:right; margin:30px30px00; } #warp2{ width:230px; height:80px; position:absolute; top:50%; left:50%; margin-left:-200px; margin-top:0; box-shadow:1px1px#3A393A; border:1pxsolid#222; font-size:13px; line-height:13px; } #all{ margin:30px; } </style> <scriptsrc="jquery-packed.ver.1.js"></script></head><body><divid="warp"> <selectid="province"> <optionvalue="载入中">载入中</option> </select> <selectid="city"> <optionvalue="载入中">载入中</option> </select></div> <divid="warp2"> <selectid="all"> <optionvalue="载入中">载入中</option> </select></div> <scripttype="text/javascript">/* SOULTEARY.COM _____ ____ __ ____ _______________ ______ __ / ___// __ \/ / / / / /_ __/ ____/ | / __ \ \/ / \__ \/ / / / / / / / / / / __/ / /| | / /_/ /\ / ___/ / /_/ / /_/ / /___/ / / /___/ ___ |/ _, _/ / //____/\____/\____/_____/_/ /_____/_/ |_/_/ |_| /_/ */;(function($){ $.fn.extend({ "citylist":function(params){ params=$.extend({ id:'id', //数据的ID名称 name:'name', //数据的VALUE名称 children:'children', //数据子元素的KEY的名称 metaTag:'data-extra', //将数据元素的ID存放到HTML元素的标签中 idVal:false, //使用ID做OPTION的VALUE data:false, //默认数据 selected:false //选中的元素eg: 14 / [14:1401] },params); vartarget=$(this); varhasSelected=' selected="selected"'; varhtml=[]; if(!target.length){ returnthis; }elseif(target.length==1){ varall=target; vardata=params.data; for(varooindata){ html.push('<option '+params.metaTag+'="'+data[oo][params.id]+'"'+((params.selected&&(params.selected==data[oo][params.id]))?hasSelected:'')+'>'+data[oo][params.name]+'</option>'); for(varxxindata[oo][params.children]){ if(params.idVal){ html.push('<option '+params.metaTag+'="'+data[oo][params.children][xx][params.id]+'" value="'+data[oo][params.children][xx][params.name]+'"'+((params.selected&&(params.selected==data[oo][params.children][xx][params.id]))?hasSelected:'')+'>'+data[oo][params.children][xx][params.name]+'</option>'); }else{ html.push('<option '+params.metaTag+'="'+data[oo][params.children][xx][params.id]+'" value="'+data[oo][params.children][xx][params.id]+'"'+((params.selected&&(params.selected==data[oo][params.children][xx][params.id]))?hasSelected:'')+'>'+data[oo][params.children][xx][params.name]+'</option>'); } } } html=html.join(''); all.find('option').remove(); all.append(html); }elseif(target.length==2){ varprovince=target.eq(0); varcity=target.eq(1); varhtml=[],oItem; for(variteminparams.data){ oItem=params.data[item]; if(params.idVal){ html.push('<option '+params.metaTag+'="'+oItem[params.id]+'" value="'+oItem[params.id]+'"'+((params.selected&&(params.selected[0]==oItem[params.id]))?hasSelected:'')+'>'+oItem[params.name]+'</option>'); }else{ html.push('<option '+params.metaTag+'="'+oItem[params.id]+'" value="'+oItem[params.name]+'"'+((params.selected&&(params.selected[0]==oItem[params.id]))?hasSelected:'')+'>'+oItem[params.name]+'</option>'); } } html=html.join(''); province.find('option').remove(); province.append(html); varprovinces=province.find('option'); province.on('change',function(){ varcurSelect=$(this).val(); provinces.each(function(k,v){ if($(v).val()==curSelect){ return(function(v){ varextra=$(v).attr(params.metaTag); varhtml=[],oItem; for(variteminparams.data){ oItem=params.data[item]; if(oItem[params.id]==extra&&oItem[params.children]){ oItem=oItem[params.children]; for(varsIteminoItem){ if(params.idVal){ html.push('<option '+params.metaTag+'="'+oItem[sItem][params.id]+'" value="'+oItem[sItem][params.id]+'"'+((params.selected&&(params.selected[1]==oItem[sItem][params.id]))?hasSelected:'')+'>'+oItem[sItem][params.name]+'</option>'); }else{ html.push('<option '+params.metaTag+'="'+oItem[sItem][params.id]+'" value="'+oItem[sItem][params.name]+'"'+((params.selected&&(params.selected[1]==oItem[sItem][params.id]))?hasSelected:'')+'>'+oItem[sItem][params.name]+'</option>'); } } break; } } html=html.join(''); city.find('option').remove(); city.append(html); }(v)); } }) }).trigger('change'); } returnthis; } });})(jQuery,'SOULTEARY.COM'); //插件调用代码 ; $(function(){ vardata=[ {'name':'北京市',id:100000,children:[ {'name':'海淀区',id:100003}, {'name':'西城区',id:100002}, {'name':'东城区',id:100001} ]}, {'name':'天津市',id:300000,children:[ {'name':'北辰区',id:100003}, {'name':'红桥区',id:100002}, {'name':'河西区',id:100001} ]} ]; $('#province, #city').citylist({data:data,id:'id',children:'citys',name:'name',metaTag:'name'}); $('#all').citylist({data:data,id:'id',children:'citys',name:'name',metaTag:'name'}); $('#pre-province, #pre-city').citylist({data:data,id:'id',children:'citys',name:'name',metaTag:'name',selected:[14,1401]}); $('#pre-all').citylist({data:data,id:'id',children:'citys',name:'name',metaTag:'name',idVal:true,selected:1401}); }); </script></body></html> |
最后,把CSS,JS独立出页面即可。
当然,这里多添加了一个小功能,如果使用者定义的数据不是id,name,children这样的键,或者不想使用DATA-EXTRA来保存数据,那么一样可以使用这个小插件。
完成地址:http://thecdn.sinaapp.com/page/demo/jq-select/
GITHUB地址:https://github.com/soulteary/jquery-city-select