jQuery省市联动下拉框插件

时间:2022-06-02 04:03:50

本文转自: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结构:

Shell
1 html:5>div#warp>((select#province>option[value="载入中"])+(select#city>option[value="载入中"]))


预览地址:http://thecdn.sinaapp.com/page/demo/jq-select/step-1.html

XHTML
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

XHTML
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实现。
首先我们要进行数据定义,就是这个省市联动的数据是如何的关系。
有许多的省份,那么省份是包含在一个数组中的,然后每个省份中的城市包含在这些省份中,所以获得包含关系。
定义结构如下:(为了简单的开发,我随意写的数据,真实上线用自己定义的数据来替换即可)

JavaScript
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:数据分别初始化到两个下拉列表中。

那么设计插件框架如下:

JavaScript
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();

JavaScript
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结构,添加一个元素作为合并输出数据的容器。可以这么做:

XHTML
12345 <divid="warp2">    <selectid="all">        <optionvalue="载入中">载入中</option>    </select></div>

当然,为了有较好的心情去写实现代码,我们需要把CSS也写一下:

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;        }

接着开始写实现代码:

JavaScript
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

XHTML
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