省市联动 js

在项目开发中我们可能会遇到需要选择省市的下拉框,上次在简明现代魔法中看到一篇感觉不错,所以拿过来记录一下:

 

city.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>省市联动</title>
<script src="js/jquery-1.4.4.js" type="text/javascript"></script>
<script src="js/Area_min.js" type="text/javascript"></script>
<script language=JavaScript>
	var locationList = new $.cnblogs.LocationList();
	$(function() {
		locationList.bind({
			pList : 'sel_province',
			cList : 'sel_city',
			defaultProvince : '',
			defaultCity : ''
		});
	});
</script>
</head>
<body>

	<p class="content">
		选择省份:<select id="sel_province" name="sel_province"></select>
	</p>
	<p class="content">
		选择城市: <select id="sel_city" name="sel_city">
		</select>
	</p>

</body>
</html>

 

 Area_min.js:

//创建命名空间
$.cnblogs = {};

//总基类
$.cnblogs.Extensible = function(options) {
    options = options || {};
    this.initialize(options);
};

//基类方法
$.extend($.cnblogs.Extensible, {
    //initialize方法用来代替构造函数
    initialize: function(options) {
        $.extend(this, options);
    }
});

//extend方法
//说明:
//  生成当前类的子类
//参数:
//  overrides: 用来重写基类的内容
//附加:
//  生成的子类同样有extend方法可再生成子类
//  生成的子类有baseClass成员表示其父类
//  子类的initialize方法最好先调用父类的initialize方法,调用方法如下
//  子类名.baseClass.initialize.call(this, options);
//示例:
//  var MyClass = Extensible.extend({
//      initialize: function(options) {
//          MyClass.baseClass.initialize.call(this, options);
//          alert(options.msg);
//      }
//  });
$.cnblogs.Extensible.extend = function(overrides) {
    var superClass = this;

    var subClass = function(options) {
        options = options || {};
        $.extend(this, subClass);
        this.initialize(options);
    };

    $.extend(subClass, superClass);
    $.extend(subClass, overrides);

    var p = function() { };
    p.prototype = superClass.prototype;
    subClass.prototype = new p();

    subClass.prototype.constructor = subClass;

    subClass.baseClass = superClass;

    return subClass;
};

//Control类
$.cnblogs.Control = $.cnblogs.Extensible.extend({
    //getContentObj方法
    //说明:
    //  生成并返回此控件html内容的jQuery对象
    //返回:
    //  此控件html内容的jQuery对象
    getContentObj: function() { },

    //cacheResult成员
    //说明:
    //  如果此值为true,则多次show方法的调用只会执行一次getContentObj方法
    //  如果为false则每次show都会调用getContentObj方法
    //  默认为true
    cacheResult: false,

    initialize: function(options) {
        this.container = options.container;
        $.cnblogs.Control.baseClass.initialize.call(this, options);
    },

    //render方法
    //说明:
    //  将此Control对象的内容显示在container中
    //参数:
    //  container: 显示此Control对象的容器
    //返回:
    //  无返回值
    //示例:
    //  var c = new $.cnblogs.Control();
    //  //c.show('#myDiv'); //可以使用ID直接传
    //  c.show($('#myDiv')); //推荐使用jQuery对象
    render: function() {
        var obj;
        if (!this.cacheResult || !this.contentObj) {
            obj = this.getContentObj();
            if (this.cacheResult) {
                this.contentObj = obj;
            }
        }
        else {
            obj = this.contentObj;
        }
        if (typeof this.container == 'string') {
            this.container = $('#' + this.container);
        }
        $(this.container).html('').append(obj);
    }
});

//BindingSource类
$.cnblogs.BindingSource = $.cnblogs.Extensible.extend({
    //clearHtml成员
    //说明:
    //  为true时在绑定前清除被绑定对象的innerHTMl
    clearHtml: true,

    //getDataObj方法
    //说明:
    //  获取每一个绑定数据经处理后的jQuery对象
    //参数:
    //  data: 待绑定的单条数据
    //  index: data在所有数据中的索引
    //返回:
    //  jQuery对象
    //示例:
    //  getDataObj : function(data, index) {
    //      return '#' + index.toString() + ': ' + data.toString();
    //  }
    getDataObj: function(data, index) {
        return data;
    },

    //bindTo方法
    //说明:
    //  将内容绑定到指定的html对象
    //参数:
    //  options: 绑定数据的参数,其中可包括一个或多个待绑定的对象
    //返回:
    //  无返回值
    bindTo: function(options) { }
});

$.cnblogs.AjaxBindingSource = $.cnblogs.BindingSource.extend({
    initialize: function(options) {
        $.cnblogs.AjaxBindingSource.baseClass.initialize.call(this, options); //调用基类

        this.url = options.url;
        this.method = options.method || 'post';
        this.contentType = options.contentType || 'application/json; charset=utf-8';
        this.data = options.data || {};
        this.isAsmx = (options.isAsmx == null) ? true : options.isAsmx;
        this.wrapper = options.wrapper;
        this.callback = options.callback || { scope: this, handler: function(data) { } };

        this.isPending = false;
    },

    prepareData: function(options) {
        var data = this.data;
        if (data) {
            if (this.isAsmx) {
                //如果是调用ASP.NET Web Service,需要将data格式化为json串
                data = JSON.stringify(data);
            }
            return data;
        }
        else {
            return null;
        }
    },

    bindTo: function(options) {
        //如果已经有AJAX请求则不再重复请求
        if (!this.isPending) {
            var target;
            target = options.target;
            if (typeof target == 'string') {
                target = $('#' + options.target);
            }
            var self = this; //保持this引用

            //根据要求清除target的innerHTML值
            if (this.clearHtml) {
                target.html('');
            }

            var data = this.prepareData(options);

            this.isPending = true;

            $.ajax({
                url: this.url || options.url,
                type: this.method,
                data: data,
                contentType: this.contentType,
                dataType: 'json',
                cache: false,

                success: function(data, status) {
                    self.isPending = false;
                    self.callback.handler.call(self.callback.scope, data);
                    if (self.wrapper) {
                        data = data[self.wrapper];
                    }
                    if (data.length) {
                        if (data.length > 1) {
                            for (var i = 0; i < data.length; i++) {
                                var obj = self.getDataObj(data[i], i);
                                target.append(obj);
                            }
                        }
                        else if (data.length == 1) {
                            var obj = self.getDataObj(data[0], 0);
                            target.append(obj);
                        }
                    }
                    else {
                        var obj = self.getDataObj(data[0], 0);
                        target.append(obj);
                    }
                },

                error: function(xhr, status, ex) {
                    self.isPending = false;
                    target.append(xhr.responseText);
                }
            });
        }
    }
});

$.cnblogs.PagedAjaxBindingSource = $.cnblogs.AjaxBindingSource.extend({
    prepareData: function(options) {
        var data = this.data || {};
        var pageIndex = options.pageIndex || 1;
        var pageSize = options.pageSize || 20;
        data['pageIndex'] = pageIndex;
        data['pageSize'] = pageSize;
        if (this.isAsmx) {
            //如果是调用ASP.NET Web Service,需要将data格式化为json串
            data = JSON.stringify(data);
        }
        return data;
    }
});

$.cnblogs.SimpleBindingSource = $.cnblogs.BindingSource.extend({
    initialize: function(options) {
        $.cnblogs.SimpleBindingSource.baseClass.initialize.call(this, options); //调用基类
        if (options.data) {
            this.data = options.data;
        }
        else {
            //初始化绑定数据
            //在子类中使用this.data.push方法添加数据
            this.data = new Array();
            this.initializeData(this.data);
        }
    },

    initializeData: function(data) {

    },

    bindTo: function(options) {
        var target = $('#' + options.target); //获取被绑定对象
        var self = this; //保持对this对象的引用

        //根据要求清除target的innerHTML值
        if (this.clearHtml) {
            target.html('');
        }

        $.each(this.data, function(index) {
            var obj = self.getDataObj(this, index); //this为循环中的元素值
            target.append(obj); //将内容追加到被绑定对象的innerHTML
        });
    }
});

$.cnblogs.Dialog = $.cnblogs.Extensible.extend({
    //getContentObj方法
    //说明:
    //  生成并返回此控件html内容的jQuery对象
    //返回:
    //  此控件html内容的jQuery对象
    getContentObj: function() { },

    //cacheResult成员
    //说明:
    //  如果此值为true,则多次show方法的调用只会执行一次getContentObj方法
    //  如果为false则每次show都会调用getContentObj方法
    //  默认为true
    cacheResult: true,

    isDialogWrapped: false,

    show: function() {
        if (!this.cacheResult || !this.contentObj) {
            this.contentObj = this.getContentObj();
        }

        if (this.isDialogWrapped) {
            this.contentObj.dialog('open');
        }
        else {
            this.isDialogWrapped = true;
            this.contentObj.dialog(this.dialogOptions);
        }
    },

    close: function(closing) {
        if (this.cacheResult) {
            if (!closing) {
                this.contentObj.dialog('close');
            }
        }
        else {
            this.contentObj.dialog('destroy').remove();
            this.isDialogWrapped = false;
            this.contentObj = null;
        }
    },

    initialize: function(options) {
        var self = this; //保持this引用

        this.dialogOptions = options.dialogOptions || {};
        if (options.cacheResult != null) {
            this.cacheResult = options.cacheResult;
        }
        $.extend(this.dialogOptions, {
            bgiframe: true,
            close: function() {
                self.close(true);
            }
        });
    }
});

$.cnblogs.GenericDialog = $.cnblogs.Dialog.extend({
    initialize: function(options) {
        $.cnblogs.GenericDialog.baseClass.initialize.call(this, options);
        this.getContentObj = options.getContentObj || function() { };
    }
});

//LocationList类
$.cnblogs.LocationList = $.cnblogs.BindingSource.extend({
    initialize: function(options) {
        $.cnblogs.LocationList.baseClass.initialize.call(this, options);
        this.data = [{ name: "北京", cities: ["西城", "东城", "崇文", "宣武", "朝阳", "海淀", "丰台", "石景山", "门头沟", "房山", "通州", "顺义", "大兴", "昌平", "平谷", "怀柔", "密云", "延庆"] }, { name: "天津", cities: ["青羊", "河东", "河西", "南开", "河北", "红桥", "塘沽", "汉沽", "大港", "东丽", "西青", "北辰", "津南", "武清", "宝坻", "静海", "宁河", "蓟县", "开发区"] }, { name: "河北", cities: ["石家庄", "秦皇岛", "廊坊", "保定", "邯郸", "唐山", "邢台", "衡水", "张家口", "承德", "沧州", "衡水"] }, { name: "山西", cities: ["太原", "大同", "长治", "晋中", "阳泉", "朔州", "运城", "临汾"] }, { name: "内蒙古", cities: ["呼和浩特", "赤峰", "通辽", "锡林郭勒", "兴安"] }, { name: "辽宁", cities: ["大连", "沈阳", "鞍山", "抚顺", "营口", "锦州", "丹东", "朝阳", "辽阳", "阜新", "铁岭", "盘锦", "本溪", "葫芦岛"] }, { name: "吉林", cities: ["长春", "吉林", "四平", "辽源", "通化", "延吉", "白城", "辽源", "松原", "临江", "珲春"] }, { name: "黑龙江", cities: ["哈尔滨", "齐齐哈尔", "大庆", "牡丹江", "鹤岗", "佳木斯", "绥化"] }, { name: "上海", cities: ["浦东", "杨浦", "徐汇", "静安", "卢湾", "黄浦", "普陀", "闸北", "虹口", "长宁", "宝山", "闵行", "嘉定", "金山", "松江", "青浦", "崇明", "奉贤", "南汇"] }, { name: "江苏", cities: ["南京", "苏州", "无锡", "常州", "扬州", "徐州", "南通", "镇江", "泰州", "淮安", "连云港", "宿迁", "盐城", "淮阴", "沐阳", "张家港"] }, { name: "浙江", cities: ["杭州", "金华", "宁波", "温州", "嘉兴", "绍兴", "丽水", "湖州", "台州", "舟山", "衢州"] }, { name: "安徽", cities: ["合肥", "马鞍山", "蚌埠", "黄山", "芜湖", "淮南", "铜陵", "阜阳", "宣城", "安庆"] }, { name: "福建", cities: ["福州", "厦门", "泉州", "漳州", "南平", "龙岩", "莆田", "三明", "宁德"] }, { name: "江西", cities: ["南昌", "景德镇", "上饶", "萍乡", "九江", "吉安", "宜春", "鹰潭", "新余", "赣州"] }, { name: "山东", cities: ["青岛", "济南", "淄博", "烟台", "泰安", "临沂", "日照", "德州", "威海", "东营", "荷泽", "济宁", "潍坊", "枣庄", "聊城"] }, { name: "河南", cities: ["郑州", "洛阳", "开封", "平顶山", "濮阳", "安阳", "许昌", "南阳", "信阳", "周口", "新乡", "焦作", "三门峡", "商丘"] }, { name: "湖北", cities: ["武汉", "襄樊", "孝感", "十堰", "荆州", "黄石", "宜昌", "黄冈", "恩施", "鄂州", "江汉", "随枣", "荆沙", "咸宁"] }, { name: "湖南", cities: ["长沙", "湘潭", "岳阳", "株洲", "怀化", "永州", "益阳", "张家界", "常德", "衡阳", "湘西", "邵阳", "娄底", "郴州"] }, { name: "广东", cities: ["广州", "深圳", "东莞", "佛山", "珠海", "汕头", "韶关", "江门", "梅州", "揭阳", "中山", "河源", "惠州", "茂名", "湛江", "阳江", "潮州", "云浮", "汕尾", "潮阳", "肇庆", "顺德", "清远"] }, { name: "广西", cities: ["南宁", "桂林", "柳州", "梧州", "来宾", "贵港", "玉林", "贺州"] }, { name: "海南", cities: ["海口", "三亚"] }, { name: "重庆", cities: ["渝中", "大渡口", "江北", "沙坪坝", "九龙坡", "南岸", "北碚", "万盛", "双桥", "渝北", "巴南", "万州", "涪陵", "黔江", "长寿"] }, { name: "四川", cities: ["成都", "达州", "南充", "乐山", "绵阳", "德阳", "内江", "遂宁", "宜宾", "巴中", "自贡", "康定", "攀枝花"] }, { name: "贵州", cities: ["贵阳", "遵义", "安顺", "黔西南", "都匀"] }, { name: "云南", cities: ["昆明", "丽江", "昭通", "玉溪", "临沧", "文山", "红河", "楚雄", "大理"] }, { name: "西藏", cities: ["拉萨", "林芝", "日喀则", "昌都"] }, { name: "陕西", cities: ["西安", "咸阳", "延安", "汉中", "榆林", "商南", "略阳", "宜君", "麟游", "白河"] }, { name: "甘肃", cities: ["兰州", "金昌", "天水", "武威", "张掖", "平凉", "酒泉"] }, { name: "青海", cities: ["黄南", "海南", "西宁", "海东", "海西", "海北", "果洛", "玉树"] }, { name: "宁夏", cities: ["银川", "吴忠"] }, { name: "新疆", cities: ["乌鲁木齐", "哈密", "喀什", "巴音郭楞", "昌吉", "伊犁", "阿勒泰", "克拉玛依", "博尔塔拉"]}]
    },

    getOptionHtml: function(value) {
        return '<option value="' + value + '">' + value + '</option>';
    },

    getProvinceHtml: function(selected) {
        var html = '';
        var value = '';
        var selText = '';
        if (selected == '') selText = ' selected="true"';
        html += '<option value="请选择"' + selText + '>请选择</option>';

        selText = '';
        for (var i = 0; i < this.data.length; i++) {
            value = this.data[i].name;
            if (selected != '' && value == selected) {
                selText = ' selected="true"';
            }
            else {
                selText = '';
            }
            html += '<option value="' + value + '"' + selText + '>' + value + '</option>';
        }
        return html;
    },

    getCityHtml: function(province, selected) {
        var html = '<option value="' + province + '">' + province + '</option>';
        var cities = this.getCities(province);
        var selText = '';
        for (var i = 0; i < cities.length; i++) {
            if (selected != '' && selected == cities[i]) {
                selText = " selected";
            }
            else {
            }
            html += '<option value="' + cities[i] + '"' + selText + '>' + cities[i] + '</option>';
        }
        return html;
    },

    getCities: function(province) {
        for (var i = 0; i < this.data.length; i++) {
            if (this.data[i].name == province) {
                return this.data[i].cities;
            }
        }
        return new Array();
    },

    bindTo: function(options) {
        options = options || {};
        this.pList = $('#' + options.pList);
        this.cList = $('#' + options.cList);

        this.pList.html('')
            .append($(this.getOptionHtml(options.defaultProvince)))
            .append($(this.getProvinceHtml()));

        var self = this;

        this.pList.bind('change', function(event) {
            var province = this.value;
            var cityObj = $(self.getCityHtml(province));
            self.cList.html('').append(cityObj);
        });

        this.select(options.selected);
    },

    bind: function(options) {
        options = options || {};
        this.pList = $('#' + options.pList);
        this.cList = $('#' + options.cList);

        this.pList.html('')
            .append($(this.getProvinceHtml(options.defaultProvince)));

        if (options.defaultCity != '') {
            this.cList.append('<option value="' + options.defaultCity + '" selected="true">' + options.defaultCity + '</option>');
        }

        var self = this;

        this.pList.bind('change', function(event) {
            var province = this.value;
            var cityObj = $(self.getCityHtml(province, options.defaultCity));
            self.cList.html('').append(cityObj);
        });

        this.select(options.selected);
    },

    select: function(value) {
        if (value && value.province) {
            this.pList.attr('value', value.province).change();
            this.cList.attr('value', value.city);
        }
    }
});

//debugger;

$.create = function(options, parent) {
    if (!options || !options.tag) {
        return;
    }
    var element;
    if (options.tag.toLowerCase() == 'input') {
        element = '<input type="' + options.type + '" />';
    }
    else {
        element = '<' + options.tag + ' />';
    }
    element = $(element);
    if (parent) {
        parent.append(element);
    }
    if (typeof options.attributes == 'object') {
        element.attr(options.attributes);
    }
    if (typeof options.style == 'object') {
        element.css(options.style);
    }
    if (typeof options.className == 'string') {
        element.addClass(options.className);
    }
    if (typeof options.text == 'string') {
        element.html(options.text);
    }
    if (typeof options.value == 'string') {
        element.val(options.value);
    }
    if (options.callback) {
        options.callback(element);
    }
    if (options.children) {
        if (options.children.length) {
            for (var i = 0; i < options.children.length; i++) {
                var child = $.create(options.children[i], element);
            }
        }
        else {
            var child = $.create(options.children);
            element.append(child);
        }
    }
    return element;
};

$.cnblogs.DoubleListBindingSource = $.cnblogs.BindingSource.extend({
    initialize: function(options) {
        $.cnblogs.DoubleListBindingSource.baseClass.initialize.call(this, options);
        this.data = options.data || new Array();
    },

    bindTo: function(options) {
        var self = this; //保持this引用

        var parent = options.parent;
        var child = options.child;
        if (typeof parent == 'string') {
            parent = $('#' + parent);
        }
        if (typeof child == 'string') {
            child = $('#' + child);
        }
        var defaultItem = options.defaultItem;

        //填充父列表
        if (defaultItem) {
            parent.append(
                $.create({ tag: 'option', value: defaultItem.value, text: defaultItem.text })
            );
            child.append(
                $.create({ tag: 'option', value: defaultItem.value, text: defaultItem.text })
            );
        }
        $.each(this.data, function() {
            parent.append(
                $.create({ tag: 'option', value: this.value, text: this.text })
            );
        });
        //绑定父列表事件
        parent.change(function() {
            //值有效,绑定子列表
            child.html('');
            if (defaultItem) {
                child.append(
                    $.create({ tag: 'option', value: defaultItem.value, text: defaultItem.text })
                );
            }
            var value = parent.val();
            if (!defaultItem || value != defaultItem.value) {
                var subArr = $.grep(self.data, function(item) { return (item.value == value); });
                if (subArr.length > 0) {
                    var items = subArr[0].items;
                    $.each(items, function() {
                        child.append(
                            $.create({ tag: 'option', value: this.value, text: this.text })
                        );
                    });
                }
            }
        });
    }
});

你可能感兴趣的:(js,省市联动)