PageSourceSearch

https://cmppj.org.tw/content/js/plugin/jquery.twzipcode-1.6.0.js

js cmppj.org.tw collected 2026-10-07 15:17:16 UTC 20,778 bytes, 424 lines download raw bytes

1/**
2 * 本著作係依據創用 姓名標示-相同方式分享 3.0 Unported (CC BY-SA 3.0) 授權條款進行授權。
3 * 如欲瀏覽本授權條款之副本,請造訪 http://creativecommons.org/licenses/by-sa/3.0/deed.zh_TW
4 *
5 * This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0).
6 * To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/deed.en
7 *
8 * jQuery TWzipcode 台灣郵遞區號 jQuery 擴充套件
9 * 輕鬆地建立多組台灣郵遞區號下拉清單,讀取快速、完全不需使用資料庫。
10 * http://app.essoduke.org/twzipcode/
11 *
12 * @author: Essoduke Chang
13 * @version: 1.6.0
14 *
15 * [Changelog]
16 * 程式碼重構,增加可讀性。
17 * 增加 data 方法可取得目前選取的縣市郵遞區號資料(若無選取則返回全部資料)。
18 * 暫時移除 detect 使用的 Geolocation API。
19 * 採用 Closure Compiler 製作 production 版本。
20 *
21 * Last Modify: Tue, 27 August 2013 10:23:56 GMT
22 */
23;(function ($, window, document, undefined) {
24
25    'use strict';
26
27    // Zipcode JSON data
28    var data = {
29        '基隆市': {'仁愛區': '200', '信義區': '201', '中正區': '202', '中山區': '203', '安樂區': '204', '暖暖區': '205', '七堵區': '206'},
30        '台北市': {'中正區': '100', '大同區': '103', '中山區': '104', '松山區': '105', '大安區': '106', '萬華區': '108', '信義區': '110', '士林區': '111', '北投區': '112', '內湖區': '114', '南港區': '115', '文山區': '116'},
31        '新北市': {
32          '萬里區': '207', '金山區': '208', '板橋區': '220', '汐止區': '221', '深坑區': '222', '石碇區': '223',
33          '瑞芳區': '224', '平溪區': '226', '雙溪區': '227', '貢寮區': '228', '新店區': '231', '坪林區': '232',
34          '烏來區': '233', '永和區': '234', '中和區': '235', '土城區': '236', '三峽區': '237', '樹林區': '238',
35          '鶯歌區': '239', '三重區': '241', '新莊區': '242', '泰山區': '243', '林口區': '244', '蘆洲區': '247',
36          '五股區': '248', '八里區': '249', '淡水區': '251', '三芝區': '252', '石門區': '253'
37        },
38        '宜蘭縣': {
39          '宜蘭市': '260', '頭城鎮': '261', '礁溪鄉': '262', '壯圍鄉': '263', '員山鄉': '264', '羅東鎮': '265',
40          '三星鄉': '266', '大同鄉': '267', '五結鄉': '268', '冬山鄉': '269', '蘇澳鎮': '270', '南澳鄉': '272',
41          '釣魚台列嶼': '290'
42        },
43        '新竹市': {'東區': '300', '北區': '300', '香山區': '300'},
44        '新竹縣': {
45          '竹北市': '302', '湖口鄉': '303', '新豐鄉': '304', '新埔鎮': '305', '關西鎮': '306', '芎林鄉': '307',
46          '寶山鄉': '308', '竹東鎮': '310', '五峰鄉': '311', '橫山鄉': '312', '尖石鄉': '313', '北埔鄉': '314',
47          '峨嵋鄉': '315'
48        },
49        '桃園縣': {
50          '中壢市': '320', '平鎮市': '324', '龍潭鄉': '325', '楊梅鎮': '326', '新屋鄉': '327', '觀音鄉': '328',
51          '桃園市': '330', '龜山鄉': '333', '八德市': '334', '大溪鎮': '335', '復興鄉': '336', '大園鄉': '337',
52          '蘆竹鄉': '338'
53        },
54        '苗栗縣': {
55          '竹南鎮': '350', '頭份鎮': '351', '三灣鄉': '352', '南庄鄉': '353', '獅潭鄉': '354', '後龍鎮': '356',
56          '通霄鎮': '357', '苑裡鎮': '358', '苗栗市': '360', '造橋鄉': '361', '頭屋鄉': '362', '公館鄉': '363',
57          '大湖鄉': '364', '泰安鄉': '365', '銅鑼鄉': '366', '三義鄉': '367', '西湖鄉': '368', '卓蘭鎮': '369'
58        },
59        '台中市': {
60          '中區': '400', '東區': '401', '南區': '402', '西區': '403', '北區': '404', '北屯區': '406', '西屯區': '407', '南屯區': '408',
61          '太平區': '411', '大里區': '412', '霧峰區': '413', '烏日區': '414', '豐原區': '420', '后里區': '421',
62          '石岡區': '422', '東勢區': '423', '和平區': '424', '新社區': '426', '潭子區': '427', '大雅區': '428',
63          '神岡區': '429', '大肚區': '432', '沙鹿區': '433', '龍井區': '434', '梧棲區': '435', '清水區': '436',
64          '大甲區': '437', '外埔區': '438', '大安區': '439'
65        },
66        '彰化縣': {
67          '彰化市': '500', '芬園鄉': '502', '花壇鄉': '503', '秀水鄉': '504', '鹿港鎮': '505', '福興鄉': '506',
68          '線西鄉': '507', '和美鎮': '508', '伸港鄉': '509', '員林鎮': '510', '社頭鄉': '511', '永靖鄉': '512',
69          '埔心鄉': '513', '溪湖鎮': '514', '大村鄉': '515', '埔鹽鄉': '516', '田中鎮': '520', '北斗鎮': '521',
70          '田尾鄉': '522', '埤頭鄉': '523', '溪州鄉': '524', '竹塘鄉': '525', '二林鎮': '526', '大城鄉': '527',
71          '芳苑鄉': '528', '二水鄉': '530'
72        },
73        '南投縣': {
74          '南投市': '540', '中寮鄉': '541', '草屯鎮': '542', '國姓鄉': '544', '埔里鎮': '545', '仁愛鄉': '546',
75          '名間鄉': '551', '集集鎮': '552', '水里鄉': '553', '魚池鄉': '555', '信義鄉': '556', '竹山鎮': '557',
76          '鹿谷鄉': '558'
77        },
78        '嘉義市': {'東區': '600', '西區': '600'},
79        '嘉義縣': {
80          '番路鄉': '602', '梅山鄉': '603', '竹崎鄉': '604', '阿里山': '605', '中埔鄉': '606', '大埔鄉': '607',
81          '水上鄉': '608', '鹿草鄉': '611', '太保市': '612', '朴子市': '613', '東石鄉': '614', '六腳鄉': '615',
82          '新港鄉': '616', '民雄鄉': '621', '大林鎮': '622', '溪口鄉': '623', '義竹鄉': '624', '布袋鎮': '625'
83        },
84        '雲林縣': {
85          '斗南鎮': '630', '大埤鄉': '631', '虎尾鎮': '632', '土庫鎮': '633', '褒忠鄉': '634', '東勢鄉': '635',
86          '臺西鄉': '636', '崙背鄉': '637', '麥寮鄉': '638', '斗六市': '640', '林內鄉': '643', '古坑鄉': '646',
87          '莿桐鄉': '647', '西螺鎮': '648', '二崙鄉': '649', '北港鎮': '651', '水林鄉': '652', '口湖鄉': '653',
88          '四湖鄉': '654', '元長鄉': '655'
89        },
90        '台南市': {
91          '中西區': '700', '東區': '701', '南區': '702', '北區': '704', '安å¹
91³å€': '708', '安南區': '709',
92          '永康區': '710', '歸仁區': '711', '新化區': '712', '左鎮區': '713', '玉井區': '714', '楠西區': '715',
93          '南化區': '716', '仁德區': '717', '關廟區': '718', '龍崎區': '719', '官田區': '720', '麻豆區': '721',
94          '佳里區': '722', '西港區': '723', '七股區': '724', '將軍區': '725', '學甲區': '726', '北門區': '727',
95          '新營區': '730', '後壁區': '731', '白河區': '732', '東山區': '733', '六甲區': '734', '下營區': '735',
96          '柳營區': '736', '鹽水區': '737', '善化區': '741', '大內區': '742', '山上區': '743', '新市區': '744',
97          '安定區': '745'
98        },
99        '高雄市': {
100          '新興區': '800', '前金區': '801', '苓雅區': '802', '鹽埕區': '803', '鼓山區': '804', '旗津區': '805',
101          '前鎮區': '806', '三民區': '807', '楠梓區': '811', '小港區': '812', '左營區': '813',
102          '仁武區': '814', '大社區': '815', '岡山區': '820', '路竹區': '821', '阿蓮區': '822', '田寮鄉': '823',
103          '燕巢區': '824', '橋頭區': '825', '梓官區': '826', '彌陀區': '827', '永安區': '828', '湖內鄉': '829',
104          '鳳山區': '830', '大寮區': '831', '林園區': '832', '鳥松區': '833', '大樹區': '840', '旗山區': '842',
105          '美濃區': '843', '六龜區': '844', '內門區': '845', '杉林區': '846', '甲仙區': '847', '桃源區': '848',
106          '那瑪夏區': '849', '茂林區': '851', '茄萣區': '852'
107        },
108        '屏東縣': {
109          '屏東市': '900', '三地門': '901', '霧臺鄉': '902', '瑪家鄉': '903', '九如鄉': '904', '里港鄉': '905',
110          '高樹鄉': '906', '鹽埔鄉': '907', '長治鄉': '908', '麟洛鄉': '909', '竹田鄉': '911', '內埔鄉': '912',
111          '萬丹鄉': '913', '潮州鎮': '920', '泰武鄉': '921', '來義鄉': '922', '萬巒鄉': '923', '崁頂鄉': '924',
112          '新埤鄉': '925', '南州鄉': '926', '林邊鄉': '927', '東港鎮': '928', '琉球鄉': '929', '佳冬鄉': '931',
113          '新園鄉': '932', '枋寮鄉': '940', '枋山鄉': '941', '春日鄉': '942', '獅子鄉': '943', '車城鄉': '944',
114          '牡丹鄉': '945', '恆春鎮': '946', '滿州鄉': '947'
115        },
116        '台東縣': {
117          '臺東市': '950', '綠島鄉': '951', '蘭嶼鄉': '952', '延平鄉': '953', '卑南鄉': '954', '鹿野鄉': '955',
118          '關山鎮': '956', '海端鄉': '957', '池上鄉': '958', '東河鄉': '959', '成功鎮': '961', '長濱鄉': '962',
119          '太麻里鄉': '963', '金峰鄉': '964', '大武鄉': '965', '達仁鄉': '966'
120        },
121        '花蓮縣': {
122          '花蓮市': '970', '新城鄉': '971', '秀林鄉': '972', '吉安鄉': '973', '壽豐鄉': '974', '鳳林鎮': '975',
123          '光復鄉': '976', '豐濱鄉': '977', '瑞穗鄉': '978', '萬榮鄉': '979', '玉里鎮': '981', '卓溪鄉': '982',
124          '富里鄉': '983'
125        },
126        '金門縣': {'金沙鎮': '890', '金湖鎮': '891', '金寧鄉': '892', '金城鎮': '893', '烈嶼鄉': '894', '烏坵鄉': '896'},
127        '連江縣': {'南竿鄉': '209', '北竿鄉': '210', '莒光鄉': '211', '東引鄉': '212'},
128        '澎湖縣': {'馬公市': '880', '西嶼鄉': '881', '望安鄉': '882', '七美鄉': '883', '白沙鄉': '884', '湖西鄉': '885'},
129        '南海諸島': {'東沙': '817', '南沙': '819'}
130    };
131    /**
132     * _hasOwnProperty for compatibility IE
133     * @param {Object} obj Object
134     * @param {string} property Property name
135     * @return {bool}
136     * @version 2.4.3
137     */
138    function _hasOwnProperty(obj, property) {
139        try {
140            return (!window.hasOwnProperty) ? Object.prototype.hasOwnProperty.call(obj, property.toString()) : obj.hasOwnProperty(property.toString());
141        } catch (ignore) {
142        }
143    }
144    /**
145     * twzipcode Constructor
146     * @param {Object} container HTML element
147     * @param {(Object|string)} options User settings
148     * @constructor
149     */
150    function twzipcode (container, options) {
151        /**
152         * Default settings
153         * @type {Object}
154         */
155        var defaults = {
156            detect: false, //v1.4
157            countyName: 'county',
158            districtName: 'district',
159            zipcodeName: 'zipcode',
160            countySel: '',
161            districtSel: '',
162            zipcodeSel: '',
163            readonly: false,
164            onCountySelect: null, //v1.5
165            onDistrictSelect: null, //v1.5
166            onZipcodeKeyUp: null,  //v1.5
167            css: []
168        };
169        /**
170         * DOM of selector
171         * @type {Object}
172         */
173        this.container = $(container);
174        /**
175         * Merge the options
176         * @type {Object}
177         */
178        this.options = $.extend({}, defaults, options);
179        // initialize
180        this.init();
181    }
182    /**
183     * tinyMap prototype
184     */
185    twzipcode.prototype = {
186        VERSION: '1.6.0',
187        /**
188         * Method: Get all post data
189         * @return {Object}
190         */
191        data: function () {
192            var wrap = this.wrap;
193            return _hasOwnProperty(data, wrap.county.val()) ? data[wrap.county.val()] : data;
194        },
195        /**
196         * Method: Serialize the data
197         * @return {string}
198         */
199        serialize: function () {
200            var result = [], obj = {}, s = {}, ele = {};
201            obj = this.container.find('select,input');
202            if (obj.length) {
203                obj.each(function () {
204                    ele = $(this);
205                    result.push(ele.attr('name') + '=' + ele.val());
206                });
207            } else {
208                $(this).children().each(function () {
209                    s = $(this);
210                    result.push(s.attr('name') + '=' + s.val());
211                });
212            }
213            return result.join('&');
214        },
215
216        /**
217         * Method: Destroy the container.
218         * @this {twzipcode}
219         */
220        destroy: function () {
221            $.data(this.container, 'twzipcode', null);
222            if (this.container.length) {
223                this.container.empty().off('change keyup blur').remove();
224            }
225        },
226
227        /**
228         * Method: Reset the selected items to default.
229         * @this {twzipcode}
230         */
231        reset: function (container, obj) {
232            var wrap = this.wrap,
233                def = ['<option value="">縣市</option>', '<option value="">鄉鎮市區</option>'],
234                tpl = [],
235                county;
236            switch (obj) {
237            case 'district':
238                wrap.district.empty().html(def[1]);
239                break;
240            default:
241                wrap.county.empty().html(def[0]);
242                wrap.district.empty().html(def[1]);
243                for (county in data) {
244                    if (_hasOwnProperty(data, county)) {
245                        tpl.push('<option value="');
246                        tpl.push(county);
247                        tpl.push('">');
248                        tpl.push(county);
249                        tpl.push('</option>');
250                    }
251                }
252                $(tpl.join('')).appendTo(wrap.county);
253                break;
254            }
255            wrap.zipcode.val('');
256        },
257        /**
258         * Binding the event of the elements
259         * @this {twzipcode}
260         */
261        bindings: function () {
262
263            var self = this,
264                opts = self.options,
265                wrap = self.wrap;
266
267            // county
268            wrap.county.on('change', function () {
269                var val = $(this).val(),
270                    tpl = [],
271                    district;
272                wrap.district.empty();
273                if (val) {
274                    for (district in data[val]) {
275                        if (_hasOwnProperty(data[val], district)) {
276                            tpl.push('<option value="');
277                            tpl.push(district);
278                            tpl.push('">');
279                            tpl.push(district);
280                            tpl.push('</option>');
281                        }
282                    }
283                    wrap.district.append(tpl.join('')).trigger('change');
284                } else {
285                    wrap.county.find('option:first').prop('selected', true);
286                    self.reset('district');
287
288                }
289                // callback binding
290                if ('function' === typeof opts.onCountySelect) {
291                    opts.onCountySelect.call(this, wrap.county);
292                }
293            });
294            // district
295            wrap.district.on('change', function () {
296                var val = $(this).val();
297                if (wrap.county.val()) {
298                    wrap.zipcode.val(data[wrap.county.val()][val]);
299                }
300                // callback binding
301                if ('function' === typeof opts.onDistrictSelect) {
302                    opts.onDistrictSelect.call(this, wrap.district);
303                }
304            });
305            // zipcode
306            wrap.zipcode.on('keyup blur', function () {
307                var obj = $(this), val = '', i, j;
308                obj.val(obj.val().replace(/[^0-9]/g, ''));
309                val = obj.val().toString();
310                if (3 === val.length) {
311                    for (i in data) {
312                        if (_hasOwnProperty(data, i)) {
313                            for (j in data[i]) {
314                                if (_hasOwnProperty(data[i], j)) {
315                                    if (val === data[i][j]) {
316                                        wrap.county.val(i).trigger('change');
317                                        wrap.district.val(j).trigger('change');
318                                        break;
319                                    }
320                                }
321                            }
322                        }
323                    }
324                }
325                // callback binding
326                if ('function' === typeof opts.onZipcodeKeyUp) {
327                    opts.onZipcodeKeyUp.call(this, wrap.zipcode);
328                }
329            });
330            // if pass the default value
331            if (_hasOwnProperty(data, opts.countySel)) {
332                this.wrap.county.val(opts.countySel).trigger('change');
333                if (_hasOwnProperty(data[opts.countySel], opts.districtSel)) {
334                    this.wrap.district.val(opts.districtSel).trigger('change');
335                }
336            }
337            if (opts.zipcodeSel) {
338                if (3 === (opts.zipcodeSel.toString()).length) {
339                    this.wrap.zipcode.val(opts.zipcodeSel).trigger('blur');
340                }
341            }
342        },
343        /**
344         * Geolocation detect
345         * @declare
346         * @this {twzipcode}
347         */
348        geolocation: function () {
349        },
350        /**
351         * twzipcode Initialize
352         * @this {twzipcode}
353         */
354        init: function () {
355
356            var self = this,
357                container = self.container,
358                opts = self.options,
359                role = {
360                    county: container.find('[data-role="county"]:first'),
361                    district: container.find('[data-role="district"]:first'),
362                    zipcode: container.find('[data-role="zipcode"]:first')
363                };
364
365            // Elements create
366            $('<select/>')
367                .attr('name', opts.countyName)
368                .addClass(role.county.data('style') || (undefined !== opts.css[0] ? opts.css[0] : ''))
369                .appendTo(role.county.length ? role.county : container);
370
371            $('<select/>')
372                .attr('name', opts.districtName)
373                .addClass(role.district.data('style') || (undefined !== opts.css[1] ? opts.css[1] : ''))
374                .appendTo(role.district.length ? role.district : container);
375
376            $('<input/>')
377                .attr({'type': 'text', 'name': opts.zipcodeName})
378                .prop('readonly', opts.readonly)
379                .addClass(role.zipcode.data('style') || (undefined !== opts.css[2] ? opts.css[2] : ''))
380                .appendTo(role.zipcode.length ? role.zipcode : container);
381
382            this.wrap = {
383                county: container.find('select[name="' + opts.countyName + '"]:first'),
384                district: container.find('select[name="' + opts.districtName + '"]:first'),
385                zipcode: container.find('input[type=text][name="' + opts.zipcodeName + '"]:first')
386            };
387
388            // reset the elements
389            this.reset();
390            // elements event bindings
391            this.bindings();
392            // geolocation API (declare)
393            this.geolocation();
394        }
395    };
396    /**
397     * jQuery twzipcode instance
398     * @param {Object} options Plugin settings
399     * @public
400     */
401    $.fn['twzipcode'] = function (options) {
402        if ('string' === typeof options) {
403            switch (options) {
404                case 'data': case 'destroy': case 'reset': case 'serialize':
405                    var result, instance;
406                    this.each(function () {
407                        instance = $.data(this, 'twzipcode');
408                        if (instance instanceof twzipcode && 'function' === typeof instance[options]) {
409                            result = instance[options].apply(instance, Array.prototype.slice.call(arguments, 1));
410                        }
411                    });
412                    break;
413            }
414            return undefined !== result ? result : this;
415        } else {
416            return this.each(function () {
417                if (!$.data(this, 'twzipcode')) {
418                    $.data(this, 'twzipcode', new twzipcode(this, options));
419                }
420            });
421        }
422    };
423
424}(jQuery, window, document));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.