省市縣三級聯動(1)

itwangchen發表於2018-12-20

.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="select0">
        <select name="" id="p0" data-id="">
                <option value="">請選擇省份</option>
        </select>
        <select name="" id="c0" data-id="">
                <option value="">請選擇城市</option>            
        </select>
        <select name="" id="d0" data-id="">
                <option value="">請選擇區/縣</option>
        </select>
    </div>
    <div id="select1">
        <select name="" id="p1" data-id="">
                <option value="">請選擇省份</option>
        </select>
        <select name="" id="c1" data-id="">
                <option value="">請選擇城市</option>    
        </select>
        <select name="" id="d1" data-id="">
                <option value="">請選擇區/縣</option>
        </select>
    </div>
    <div id="select2">
        <select name="" id="p2" data-id="">
                <option value="">請選擇省份</option>
        </select>
        <select name="" id="c2" data-id="">
                <option value="">請選擇城市</option>
        </select>
        <select name="" id="d2" data-id="">
                <option value="">請選擇區/縣</option>
        </select>
    </div>

    <!-- 準備三個select 下拉框 -->
    <!-- 1 用一個div 包裹 -->
    <!-- 2 每一個select 都需要一個id -->
    <!-- 3 每一個select 都需要一個data-id -->
    <!-- 4 給每一個select 一個預設值 -->
    <script src="./jquery.min.js"></script>
    <script src="./jquery.region.js"></script>
    <script>
        function Region(el) {
            $(el).region({
                url: './region.json'
            })
        }
        Region('#select0')
        Region('#select1')
        Region('#select2')
    </script>
</body>

</html>
複製程式碼

jquery.region.js

/**
 * 省市縣聯動
 * @param  {[type]} $ [description]
 * @return {[type]}   [description]
 */

(function(factory) {

    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // CommonJS
        factory(require('jquery'));
    } else {
        // Browser globals
        factory(jQuery);
    }

}(function($) {

    $.fn.region = function(options) {

        if (!options) return;

        var parmas = [];

        $(this).find('select').each(function(key, val) {
            parmas.push($(this).attr('id') + '|' + $(this).attr('data-id'));
        });

        // 初始化引數
        var url = options.url || location.pathname,
            type = options.type || 'get',
            region = null,
            // map中的值要和region.json中的省/市/區縣key保持一致
            map = ['p', 'c', 'd'];

        // 獲取全部資料
        (function() {
            $.ajax({
                url: url,
                type: type,
                dataType: 'json',
                success: function(data) {
                    // var data = $.parseJSON(data);
                    if (!data) return;

                    // 將請求來的地區資料快取到本地變數中
                    region = data;
                },
                error: function() {
                    console.log('Region error!');
                }
            });
        })();

        // 定時監聽地區資料返回
        var t = setInterval(function() {
            // 資料未請求至本地
            if (!region) return;

            // 清除定時器
            clearInterval(t);

            var options = [];

            // 有預設值的狀態
            for (var i = 0; i < parmas.length; i++) {
                var tmp = parmas[i].split('|');
                var o = {};

                o['el'] = tmp[0];
                o['id'] = tmp[1];
                o['pid'] = '000000'; // 省級
                o['map'] = map[i];

                if (i > 0) {
                    // 查詢市/區縣的父級ID
                    o['pid'] = parmas[i - 1].split('|')[1];
                }

                options.push(o);
            }

            // 遍歷建立
            for (var k = 0; k < options.length; k++) {
                var curr = options[k],
                    next = options[k + 1];

                // 建立option選項
                if (region[curr['map']] && region[curr['map']][curr['pid']]) {
                    fill(curr['el'], region[curr['map']][curr['pid']], curr['id']);
                }

                // 切換選項 [快取next]
                (function(next, k) {
                    $('#' + curr['el']).on('change', function() {
                        var _this = $(this),
                            id = _this.val();

                        if (!next) return;

                        if (region[next['map']]) {
                            fill(next['el'], region[next['map']][id] || [], '');
                        }

                        $.each(options, function(key, val) {
                            if (key > k + 1) {
                                fill(val['el'], [], '');
                            }
                        });

                    });
                })(next, k);
            }

            // 填充選項
            function fill(el, arr, id) {
                var opt = '';
                $.each(arr, function(key, val) {
                    if (key == id) {
                        opt += '<option value="' + key + '" selected>';
                    } else {
                        opt += '<option value="' + key + '">';
                    }

                    opt += val + '</option>'
                });

                $('#' + el + ' option:gt(0)').remove();
                $('#' + el).append(opt);
            }

        }, 200);
    }
}));
複製程式碼

相關文章