├── bower.json ├── LICENSE.md ├── .github └── workflows │ └── blank.yml ├── CHANGELOG.md ├── README.md ├── old ├── jquery.twzipcode-1.4.1.min.js └── jquery.twzipcode-1.4.1.js ├── jquery.twzipcode.min.js ├── jquery.twzipcode.js └── twzipcode.js /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-TWzipcode", 3 | "homepage": "https://code.essoduke.org/twzipcode/", 4 | "version": "1.7.12", 5 | "repository": { 6 | "type": "git", 7 | "url": "git://github.com/essoduke/jQuery-TWzipcode.git" 8 | }, 9 | "authors": [ 10 | "Essoduke Chang " 11 | ], 12 | "description": "建立三碼臺灣郵遞區號下拉清單的 jQuery Plugin — 讀取快速、不需資料庫。", 13 | "main": "jquery.twzipcode.min.js", 14 | "keywords": [ 15 | "jquery", 16 | "plugins", 17 | "taiwan", 18 | "zipcode" 19 | ], 20 | "license": "MIT", 21 | "ignore": [ 22 | "**/.*", 23 | "node_modules", 24 | "bower_components", 25 | "test", 26 | "demo", 27 | "lib" 28 | ], 29 | "dependencies": { 30 | "jquery": ">= 1.7.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2012-present essoduke.org 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /.github/workflows/blank.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: CI 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the "master" branch 8 | push: 9 | branches: [ "master" ] 10 | pull_request: 11 | branches: [ "master" ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | # This workflow contains a single job called "build" 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v4 27 | 28 | # Runs a single command using the runners shell 29 | - name: Run a one-line script 30 | run: echo Hello, world! 31 | 32 | # Runs a set of commands using the runners shell 33 | - name: Run a multi-line script 34 | run: | 35 | echo Add other actions to build, 36 | echo test, and deploy your project. 37 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # jQuery TWzipcode Changelog 2 | ### 1.7.14 3 | * 修正新竹縣「峨嵋鄉」為「峨眉鄉」 4 | 5 | ### 1.7.13 6 | * 新增 `afterZipcodeSetup` 事件於初始化後觸發 7 | 8 | ### 1.7.12 9 | * 新增 html5 [data-*] 新增為元素屬性的功能。 10 | 11 | ### 1.7.11 12 | * 修正 get 方法,若第二個參數傳入 county, district, zipcode 將會直接返回值而不是 DOM 物件。 13 | * 修正 detect 方法,現在可以除了 true|false 也可以傳入 callback funciotn。 14 | 15 | ### 1.7.10 16 | * 修正異體字「台」為正體字「臺」 17 | 18 | ### 1.7.9 19 | * 新增 hideCounty, hideDistrict 屬性,可控制隱藏符合的縣市或鄉鎮市區名稱。 20 | 21 | ### 1.7.8 22 | * 修正使用 html data-value 的方式傳入預設值無效的錯誤。 23 | 24 | ### 1.7.7 25 | * 修正 readonly 會造成 keyup, blur 無法被 detect 觸發的錯誤。 26 | 27 | ### 1.7.6 28 | * 修正高雄市田寮鄉為田寮區,湖內鄉為湖內區(By kevin50406418) 29 | 30 | ### 1.7.5 31 | * 加入 zipcode input placeholder 的支援(By visioncan) 32 | 33 | ### 1.7.4 34 | * 鄉鎮市區修正: 東沙、南沙編在高雄市轄區內、三地門補上鄉字 35 | 36 | ### 1.7.3 37 | * 新增 get 方法,可取得元素 DOM。 38 | * 取消 onCountySelect, onDistrictSelect, onZipcodeKeyUp 返回的參數,this 即為元素本身。 39 | 40 | ### 1.7.2 41 | * 新增 set 方法,可設置縣市、鄉鎮市區。 42 | 43 | ### 1.7.1 44 | * 因應員林鎮改制為員林市、頭份鎮改制為頭份市。 45 | 46 | ### 1.7.0 47 | * 修正 html5 data-value 優先於 countySel, districtSel, zipcodeSel 的問題。 48 | 49 | ### 1.6.9 50 | * 增加 googleMapsKey 參數,可設置 Google Maps Geolocation API 的金鑰,以能透過購買用量來解決 API 用量限制。(By Patrick Wang) 51 | * 修正了無法於 Safari 8.0.5 (OS X) 上定位的問題。(By Patrick Wang) 52 | 53 | ### 1.6.8 54 | * 更改桃園縣升格後行政區域的名稱。(By syj610226) 55 | 56 | ### 1.6.7 57 | * 恢復 detect(bool) 參數的支援,可設置是否自動讀取用戶的位置(瀏覽器需 GeoLocation API 支援) 58 | 59 | ### 1.6.6 60 | * 新增 zipcodeIntoDistrict 參數,可隱藏郵遞區號輸入框,並顯示於鄉鎮市區清單內。 61 | 62 | ### 1.6.5 63 | * 新增 data-name, data-readonly 設置元素名稱及是否唯讀。(By Wake Liu) 64 | 65 | ### 1.6.4 66 | * 修正預設值無法傳入的問題 67 | 68 | ### 1.6.3 69 | * HTML5 自訂容器加入 data-value 可傳入預設值 70 | 71 | ### 1.6.2 72 | * 修正 destroy 方法註銷 plugin 後不回傳物件導致無法 chain 的錯誤。 73 | * 轉換至 MIT 授權 74 | 75 | ### 1.6.0 76 | * 程式碼重構,增加可讀性。 77 | * 增加 data 方法可取得目前選取的縣市郵遞區號資料(若無選取則返回全部資料)。 78 | * 暫時移除 detect 使用的 Geolocation API。 79 | * 採用 Closure Compiler 製作 production 版本。 80 | 81 | ### 1.5.2 82 | * 修正資料 (Hsinchu, Chiayi) 83 | 84 | ### 1.5.1 85 | * 修正 callback 綁定錯誤 86 | 87 | ### 1.5.0 88 | * 支援 jQuery 2.0 89 | 90 | ### 1.4 91 | * 改寫原始碼以符合 jslint.com 92 | * 修改參數名稱以更符合語意 areaName => districtName, zipName => zipcodeName, areaSel => districtSel, zipSel => zipcodeSel 93 | * 加入 destroy, reset, serialize 等方法 94 | * 修正當指定元素名稱時,若名稱內包含 [] 會發生錯誤的情形。 95 | * 更新 Creative Commons 至 3.0 96 | 97 | ### 1.3.1 98 | * 因應五都改制,修正為合併後的行政區劃。 99 | 100 | ### 1.3.0 101 | * 新增輸入郵遞區號取得縣市名稱的功能。(意見提供:ileadu) 102 | 103 | ### 1.2.0 104 | * 修正 IE6 鄉鎮市區選單只顯示一個以及清單過長的問題 105 | 106 | ### 1.1.0 107 | * 修正 form reset 時,鄉鎮市區選單無法重置的錯誤 108 | * 加入css參數以套用樣式: $(element).twzipcode({ css:[select1, select2, select3] }); 109 | * 改寫成更簡潔的源碼以增進效能 110 | * 使用自訂表單元件名稱 111 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jQuery-TWzipcode 2 | 3 | 在網頁建立多組 3 碼臺灣郵遞區號表單元素的 jQuery Plugin ─ 讀取快速、不需使用資料庫。 4 | 5 | \* **jQuery-TWzipcode v1.5 以後版本需 jQuery v1.6(支援 2.0)** 6 | 7 | # TWzipcode.js 8 | 免 jQuery 並支援 AMD 的純 JS 版本 9 | [twzipcode.js](https://code.essoduke.org/twzipcode) 10 | 11 | 新增參數 12 | 13 | ```javascript 14 | language: 'language file path' //預設自動判斷 15 | ``` 16 | 17 | Example 18 | ```javascript 19 | $(selector).twzipcode({ 20 | language: 'lang/zh-tw' //不需加上 .js 21 | }); 22 | ``` 23 | ## 安裝 Install 24 | ### bower 25 | ``` 26 | $bower install jquery-TWzipcode 27 | ``` 28 | 29 | ## 使用 Usage 30 | 31 | HTML 32 | ```html 33 | ... 34 | 35 | 36 | 37 | 38 |
39 | 40 | 41 | 42 |
43 |
44 |
45 |
46 |
47 | ``` 48 | 49 | Javascript 50 | ```javascript 51 | $('#twzipcode').twzipcode(); 52 | ``` 53 | 54 | ## 選項 Options 55 | 56 | ### css (Array) 57 | 設置元素的樣式名稱,依序為 `['縣市清單', '鄉鎮市區清單', '郵遞區號輸入框']` 58 | 59 | ### googleMapsKey (string) 60 | `v1.6.9` Google Maps Geolocation API 金鑰。若您達到 Geocoder 的每日限制用量,可透過購買來提高用量,同時需設置金鑰。 61 | _預設值: ''_ 62 | 63 | ### detect (boolean|Function) 64 | `v1.6.7` 是否自動偵測用戶位置。不需引入 Google Maps API。 65 | _預設值: false_ 66 | 67 | ### countyName (string) 68 | 指定縣市下拉清單元素的表單名稱。 69 | _預設值: county_ 70 | 71 | ### countySel (string) 72 | 縣市清單的預設值 73 | 74 | ### districtName (string) 75 | 鄉鎮市區下拉清單的表單名稱。 76 | _預設值: district_ 77 | 78 | ### districtSel (string) 79 | 鄉鎮市區的預設值 80 | 81 | ### zipcodeName (string) 82 | 郵遞區號輸入框的表單名稱。 83 | _預設值: zipcode_ 84 | 85 | ### zipcodeSel (string) 86 | 郵遞區號輸入框的預設值(此選項優先於 countySel, districtSel) 87 | 88 | ### zipcodeIntoDistrict (bool) 89 | `v1.6.6` 是否隱藏郵遞區號輸入框並顯示於鄉鎮市區清單內? 90 | _預設值: false_ 91 | 92 | ### onCountySelect (function) 93 | `v1.5` 綁定縣市選單 Change 事件。 94 | 95 | ### onDistrictSelect (function) 96 | `v1.5` 綁定鄉鎮市區選單 Change 事件。 97 | 98 | ### onZipcodeKeyUp (function) 99 | `v1.5` 綁定郵遞區號輸入框 keyUp 事件(readonly 必須為 false)。 100 | 101 | ### readonly (boolean) 102 | 郵遞區號輸入框是否唯讀? 103 | _預設值: true_ 104 | 105 | ### hideCounty (array) 106 | `v1.7.9` 要隱藏的縣市名稱,例如 ['臺北市', '宜蘭縣'...] 107 | _預設值: []_ 108 | 109 | ### hideDistrict (array) 110 | `v1.7.9` 要隱藏的鄉鎮市區,可以是名稱或三碼郵遞區號例如 ['大安區', '110'...] 111 | _預設值: []_ 112 | 113 | 114 | ## 方法 Methods 115 | 116 | ### data 117 | 取得已選取縣市的郵遞區號資料 118 | ```javascript 119 | var data = $(selector).twzipcode('data'); 120 | console.log(data); 121 | ``` 122 | 123 | ### destroy 124 | 從指定的元素移除 Plugin 125 | ```javascript 126 | $(selector).twzipcode('destroy'); 127 | ``` 128 | 129 | ### get 130 | ```javascript 131 | // 取得縣市 county(返回字串) 132 | var county = $(selector).twzipcode('get', 'county'); 133 | 134 | // 取得縣市 county 以及鄉鎮市區 district(返回陣列) 135 | var result = $(selector).twzipcode('get', 'county,district'); // 以 , 字串傳入 136 | var result = $(selector).twzipcode('get', ['county', 'district']); // 以陣列傳入 137 | 138 | // Callback 139 | $(selector).twzipcode('get', function (county, district, zipcode) { 140 |    console.log(county); // 縣市 141 |    console.log(district); // 鄉鎮市區 142 |    console.log(zipcode); // 郵遞區號 143 | }); 144 | ``` 145 | 146 | ### set 147 | ```javascript 148 | // 直接設置郵遞區號 149 | $(selector).twzipcode('set', 110); 150 | // 傳入縣市、鄉鎮市區 151 | $(selector).twzipcode('set', { 152 | 'county': '臺北市', 153 | 'district': '信義區', 154 | 'zipcode': 110 155 | }); 156 | ``` 157 | 158 | ### reset 159 | 將指定的元素恢復未選狀態 160 | ```javascript 161 | $(selector).twzipcode('reset'); 162 | ``` 163 | 164 | ### serialize 165 | 將指定的元素輸出為 URL QueryString。 166 | ```javascript 167 | var qs = $(selector).twzipcode('serialize'); 168 | console.log(qs); 169 | // output: 170 | // county=AAA&district=BBB&zipcode=999 171 | ``` 172 | 173 | ## 範例 174 | ### 加入郵遞區號預設值,並可輸入郵遞區號取得縣市名稱 175 | ```javascript 176 | $('selector').twzipcode({ 177 | 'zipcodeSel': 110, 178 | 'readonly': false 179 | }); 180 | ``` 181 | ### 加入縣市預設值 182 | ```javascript 183 | $('selector').twzipcode({ 184 | 'countySel': '高雄市', 185 | 'districtSel': '那瑪夏區' 186 | }); 187 | ``` 188 | 189 | ### 指定 CSS 樣式名稱 190 | ```css 191 | .addr-county{background:#4169E1;color:#fff} 192 | .addr-district{background:#008000;color:#fff} 193 | .addr-zip{background:#c00;color:#fff;border:1px solid #666} 194 | ``` 195 | ```javascript 196 | $('#container').twzipcode({ 197 | 'css': [ 198 | 'addr-county', //縣市 199 | 'addr-distrcit', // 鄉鎮市區 200 | 'addr-zip' // 郵遞區號 201 | ] 202 | }); 203 | ``` 204 | 205 | 或是直接使用 HTML5 data-* 套用樣式 206 | 207 | ```html 208 |
209 |
210 |
211 |
212 |
213 | ``` 214 | ## 支援 215 | 216 | 請拜訪 https://code.essoduke.org/twzipcode/ 取得支援。 217 | 218 | ## 授權 219 | 220 | v1.6.2 開始採用 [MIT License](http://opensource.org/licenses/MIT) 221 | v1.6.1 及更早版本採用 [創用 CC 姓名標示-相同方式分享 3.0 台灣授權條款](http://creativecommons.org/licenses/by-sa/3.0/deed.zh_TW)。 222 | -------------------------------------------------------------------------------- /old/jquery.twzipcode-1.4.1.min.js: -------------------------------------------------------------------------------- 1 | eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(q($){\'46 64\';r m={\'基隆市\':{\'仁愛區\':\'65\',\'信義區\':\'66\',\'中正區\':\'67\',\'中山區\':\'68\',\'安樂區\':\'69\',\'暖暖區\':\'6a\',\'七堵區\':\'6c\'},\'台北市\':{\'中正區\':\'6d\',\'大同區\':\'6e\',\'中山區\':\'6f\',\'松山區\':\'6g\',\'大安區\':\'6h\',\'萬華區\':\'6i\',\'信義區\':\'6j\',\'士林區\':\'6k\',\'北投區\':\'6l\',\'內湖區\':\'6m\',\'南港區\':\'6n\',\'文山區\':\'6o\'},\'新北市\':{\'萬里區\':\'6p\',\'金山區\':\'6r\',\'板橋區\':\'6s\',\'汐止區\':\'6t\',\'深坑區\':\'6u\',\'石碇區\':\'6v\',\'瑞芳區\':\'6w\',\'平溪區\':\'6x\',\'雙溪區\':\'6y\',\'貢寮區\':\'6z\',\'新店區\':\'6A\',\'坪林區\':\'6B\',\'烏來區\':\'6C\',\'永和區\':\'6D\',\'中和區\':\'6E\',\'土城區\':\'6F\',\'三峽區\':\'6G\',\'樹林區\':\'6H\',\'鶯歌區\':\'6I\',\'三重區\':\'6J\',\'新莊區\':\'6K\',\'泰山區\':\'6L\',\'林口區\':\'6M\',\'蘆洲區\':\'6N\',\'五股區\':\'6O\',\'八里區\':\'6P\',\'淡水區\':\'6Q\',\'三芝區\':\'6R\',\'石門區\':\'6S\'},\'宜蘭縣\':{\'宜蘭市\':\'6T\',\'頭城鎮\':\'6U\',\'礁溪鄉\':\'6V\',\'壯圍鄉\':\'6W\',\'員山鄉\':\'6X\',\'羅東鎮\':\'6Y\',\'三星鄉\':\'6Z\',\'大同鄉\':\'70\',\'五結鄉\':\'71\',\'冬山鄉\':\'72\',\'蘇澳鎮\':\'73\',\'南澳鄉\':\'75\',\'釣魚台列嶼\':\'78\'},\'新竹市\':{\'新竹市\':\'79\'},\'新竹縣\':{\'竹北市\':\'7b\',\'湖口鄉\':\'7c\',\'新豐鄉\':\'7d\',\'新埔鎮\':\'7e\',\'關西鎮\':\'7f\',\'芎林鄉\':\'7i\',\'寶山鄉\':\'7k\',\'竹東鎮\':\'7m\',\'五峰鄉\':\'7n\',\'橫山鄉\':\'7o\',\'尖石鄉\':\'7p\',\'北埔鄉\':\'7r\',\'峨嵋鄉\':\'7s\'},\'桃園縣\':{\'中壢市\':\'7t\',\'平鎮市\':\'7v\',\'龍潭鄉\':\'7A\',\'楊梅鎮\':\'7D\',\'新屋鄉\':\'7Q\',\'觀音鄉\':\'7V\',\'桃園市\':\'81\',\'龜山鄉\':\'86\',\'八德市\':\'1s\',\'大溪鎮\':\'1t\',\'復興鄉\':\'1u\',\'大園鄉\':\'1v\',\'蘆竹鄉\':\'1w\'},\'苗栗縣\':{\'竹南鎮\':\'1x\',\'頭份鎮\':\'1y\',\'三灣鄉\':\'1z\',\'南庄鄉\':\'1A\',\'獅潭鄉\':\'1B\',\'後龍鎮\':\'1C\',\'通霄鎮\':\'1D\',\'苑裡鎮\':\'1E\',\'苗栗市\':\'1F\',\'造橋鄉\':\'1G\',\'頭屋鄉\':\'1H\',\'公館鄉\':\'1I\',\'大湖鄉\':\'1J\',\'泰安鄉\':\'1K\',\'銅鑼鄉\':\'1L\',\'三義鄉\':\'1M\',\'西湖鄉\':\'1N\',\'卓蘭鎮\':\'1O\'},\'台中市\':{\'中區\':\'1P\',\'東區\':\'1Q\',\'南區\':\'1R\',\'西區\':\'1S\',\'北區\':\'1T\',\'北屯區\':\'1U\',\'西屯區\':\'1V\',\'南屯區\':\'1W\',\'太平區\':\'1X\',\'大里區\':\'1Y\',\'霧峰區\':\'1Z\',\'烏日區\':\'20\',\'豐原區\':\'21\',\'后里區\':\'22\',\'石岡區\':\'23\',\'東勢區\':\'24\',\'和平區\':\'25\',\'新社區\':\'26\',\'潭子區\':\'27\',\'大雅區\':\'28\',\'神岡區\':\'29\',\'大肚區\':\'2a\',\'沙鹿區\':\'2b\',\'龍井區\':\'2c\',\'梧棲區\':\'2d\',\'清水區\':\'2e\',\'大甲區\':\'2f\',\'外埔區\':\'2g\',\'大安區\':\'2h\'},\'彰化縣\':{\'彰化市\':\'2i\',\'芬園鄉\':\'2j\',\'花壇鄉\':\'2k\',\'秀水鄉\':\'2l\',\'鹿港鎮\':\'2m\',\'福興鄉\':\'2n\',\'線西鄉\':\'2o\',\'和美鎮\':\'2p\',\'伸港鄉\':\'2q\',\'員林鎮\':\'2r\',\'社頭鄉\':\'2s\',\'永靖鄉\':\'2t\',\'埔心鄉\':\'2u\',\'溪湖鎮\':\'2v\',\'大村鄉\':\'2w\',\'埔鹽鄉\':\'2x\',\'田中鎮\':\'2y\',\'北斗鎮\':\'2z\',\'田尾鄉\':\'2A\',\'埤頭鄉\':\'2B\',\'溪州鄉\':\'2C\',\'竹塘鄉\':\'2D\',\'二林鎮\':\'2E\',\'大城鄉\':\'2F\',\'芳苑鄉\':\'2G\',\'二水鄉\':\'2H\'},\'南投縣\':{\'南投市\':\'2I\',\'中寮鄉\':\'2J\',\'草屯鎮\':\'2K\',\'國姓鄉\':\'2L\',\'埔里鎮\':\'2M\',\'仁愛鄉\':\'2N\',\'名間鄉\':\'2O\',\'集集鎮\':\'2P\',\'水里鄉\':\'2Q\',\'魚池鄉\':\'2R\',\'信義鄉\':\'2S\',\'竹山鎮\':\'2T\',\'鹿谷鄉\':\'2U\'},\'嘉義市\':{\'嘉義市\':\'2V\'},\'嘉義縣\':{\'番路鄉\':\'2W\',\'梅山鄉\':\'2X\',\'竹崎鄉\':\'2Y\',\'阿里山\':\'2Z\',\'中埔鄉\':\'30\',\'大埔鄉\':\'31\',\'水上鄉\':\'32\',\'鹿草鄉\':\'33\',\'太保市\':\'34\',\'朴子市\':\'35\',\'東石鄉\':\'36\',\'六腳鄉\':\'37\',\'新港鄉\':\'38\',\'民雄鄉\':\'39\',\'大林鎮\':\'3a\',\'溪口鄉\':\'3b\',\'義竹鄉\':\'3c\',\'布袋鎮\':\'3d\'},\'雲林縣\':{\'斗南鎮\':\'3e\',\'大埤鄉\':\'3f\',\'虎尾鎮\':\'3g\',\'土庫鎮\':\'3h\',\'褒忠鄉\':\'3i\',\'東勢鄉\':\'3j\',\'臺西鄉\':\'3k\',\'崙背鄉\':\'3l\',\'麥寮鄉\':\'3m\',\'斗六市\':\'3n\',\'林內鄉\':\'3o\',\'古坑鄉\':\'3p\',\'莿桐鄉\':\'3q\',\'西螺鎮\':\'3r\',\'二崙鄉\':\'3s\',\'北港鎮\':\'3t\',\'水林鄉\':\'3u\',\'口湖鄉\':\'3v\',\'四湖鄉\':\'3w\',\'元長鄉\':\'3x\'},\'台南市\':{\'中西區\':\'3y\',\'東區\':\'3z\',\'南區\':\'3A\',\'北區\':\'3B\',\'安平區\':\'3C\',\'安南區\':\'3D\',\'永康區\':\'3E\',\'歸仁區\':\'3F\',\'新化區\':\'3G\',\'左鎮區\':\'3H\',\'玉井區\':\'3I\',\'楠西區\':\'3J\',\'南化區\':\'3K\',\'仁德區\':\'3L\',\'關廟區\':\'3M\',\'龍崎區\':\'3N\',\'官田區\':\'3O\',\'麻豆區\':\'3P\',\'佳里區\':\'3Q\',\'西港區\':\'3R\',\'七股區\':\'3S\',\'將軍區\':\'3T\',\'學甲區\':\'3U\',\'北門區\':\'3V\',\'新營區\':\'3W\',\'後壁區\':\'3X\',\'白河區\':\'3Y\',\'東山區\':\'3Z\',\'六甲區\':\'40\',\'下營區\':\'41\',\'柳營區\':\'42\',\'鹽水區\':\'43\',\'善化區\':\'44\',\'大內區\':\'45\',\'山上區\':\'87\',\'新市區\':\'47\',\'安定區\':\'48\'},\'高雄市\':{\'新興區\':\'49\',\'前金區\':\'4a\',\'苓雅區\':\'4b\',\'鹽埕區\':\'4c\',\'鼓山區\':\'4d\',\'旗津區\':\'4e\',\'前鎮區\':\'4f\',\'三民區\':\'4g\',\'楠梓區\':\'4h\',\'小港區\':\'4i\',\'左營區\':\'4j\',\'仁武區\':\'4k\',\'大社區\':\'4l\',\'岡山區\':\'4m\',\'路竹區\':\'4n\',\'阿蓮區\':\'4o\',\'田寮鄉\':\'4p\',\'燕巢區\':\'4q\',\'橋頭區\':\'4r\',\'梓官區\':\'4s\',\'彌陀區\':\'4t\',\'永安區\':\'4u\',\'湖內鄉\':\'4v\',\'鳳山區\':\'4w\',\'大寮區\':\'4x\',\'林園區\':\'4y\',\'鳥松區\':\'4z\',\'大樹區\':\'4A\',\'旗山區\':\'4B\',\'美濃區\':\'4C\',\'六龜區\':\'4D\',\'內門區\':\'4E\',\'杉林區\':\'4F\',\'甲仙區\':\'4G\',\'桃源區\':\'4H\',\'那瑪夏區\':\'4I\',\'茂林區\':\'4J\',\'茄萣區\':\'4K\'},\'屏東縣\':{\'屏東市\':\'4L\',\'三地門\':\'4M\',\'霧臺鄉\':\'4N\',\'瑪家鄉\':\'4O\',\'九如鄉\':\'4P\',\'里港鄉\':\'4Q\',\'高樹鄉\':\'4R\',\'鹽埔鄉\':\'4S\',\'長治鄉\':\'4T\',\'麟洛鄉\':\'4U\',\'竹田鄉\':\'4V\',\'內埔鄉\':\'4W\',\'萬丹鄉\':\'4X\',\'潮州鎮\':\'4Y\',\'泰武鄉\':\'4Z\',\'來義鄉\':\'50\',\'萬巒鄉\':\'51\',\'崁頂鄉\':\'52\',\'新埤鄉\':\'53\',\'南州鄉\':\'54\',\'林邊鄉\':\'55\',\'東港鎮\':\'56\',\'琉球鄉\':\'57\',\'佳冬鄉\':\'58\',\'新園鄉\':\'59\',\'枋寮鄉\':\'5a\',\'枋山鄉\':\'5b\',\'春日鄉\':\'5c\',\'獅子鄉\':\'5d\',\'車城鄉\':\'5e\',\'牡丹鄉\':\'5f\',\'恆春鎮\':\'5g\',\'滿州鄉\':\'5h\'},\'台東縣\':{\'臺東市\':\'5i\',\'綠島鄉\':\'5j\',\'蘭嶼鄉\':\'5k\',\'延平鄉\':\'5l\',\'卑南鄉\':\'5m\',\'鹿野鄉\':\'5n\',\'關山鎮\':\'5o\',\'海端鄉\':\'5p\',\'池上鄉\':\'5q\',\'東河鄉\':\'5r\',\'成功鎮\':\'5s\',\'長濱鄉\':\'5t\',\'太麻里鄉\':\'5u\',\'金峰鄉\':\'5v\',\'大武鄉\':\'5w\',\'達仁鄉\':\'5x\'},\'花蓮縣\':{\'花蓮市\':\'5y\',\'新城鄉\':\'5z\',\'秀林鄉\':\'5A\',\'吉安鄉\':\'5B\',\'壽豐鄉\':\'5C\',\'鳳林鎮\':\'5D\',\'光復鄉\':\'5E\',\'豐濱鄉\':\'5F\',\'瑞穗鄉\':\'5G\',\'萬榮鄉\':\'5H\',\'玉里鎮\':\'5I\',\'卓溪鄉\':\'5J\',\'富里鄉\':\'5K\'},\'金門縣\':{\'金沙鎮\':\'5L\',\'金湖鎮\':\'5M\',\'金寧鄉\':\'5N\',\'金城鎮\':\'5O\',\'烈嶼鄉\':\'5P\',\'烏坵鄉\':\'5Q\'},\'連江縣\':{\'南竿鄉\':\'5R\',\'北竿鄉\':\'5S\',\'莒光鄉\':\'5T\',\'東引鄉\':\'5U\'},\'澎湖縣\':{\'馬公市\':\'5V\',\'西嶼鄉\':\'5W\',\'望安鄉\':\'5X\',\'七美鄉\':\'5Y\',\'白沙鄉\':\'5Z\',\'湖西鄉\':\'60\'},\'南海諸島\':{\'東沙\':\'61\',\'南沙\':\'62\'}};r n={1r:q(l){x 7.E(q(){r f={1n:6b,W:\'8\',U:\'6\',T:\'v\',1m:\'\',12:\'\',1i:\'\',11:F,M:[]};r g=$(7),p=$.6q(f,l),t=[],i=0,4={},8,J=[\'縣市\',\'鄉鎮市區\'];g.Z();$(\'\').L({\'A\':p.W}).D(7);$(\'\').L({\'A\':p.U}).D(7);$(\'\').L({\'18\':\'1f\',\'A\':p.T,\'11\':p.11}).D(7);4.z={8:\'C[A="\'+p.W+\'"]\',6:\'C[A="\'+p.U+\'"]\',v:\'S[18=1f][A="\'+p.T+\'"]\'};4.8=g.B(4.z.8);4.6=g.B(4.z.6);4.v=g.B(4.z.v);1p{4.8.V(p.M[0]);4.6.V(p.M[1]);4.v.V(p.M[2])}1b(e){}$(J[0]).D(4.8);$(J[1]).D(4.6);P(8 H m){o(m.I(8)){t[i++]=\'\';t[i++]=8;t[i++]=\'\'}}$(t.14(\'\')).D(4.8);g.15(4.z.8,\'w\',q(){r a=$(7).5(),i=0,t=[],6;4.6.Z();o(a){P(6 H m[a]){o(m[a].I(6)){t[i++]=\'\';t[i++]=6;t[i++]=\'\'}}4.6.1c(t.14(\'\')).y(\'w\')}G{4.8.B(\'u:N\').X(\'Y\',F);4.6.Z().1c(J[1]);4.v.5(\'\')}});g.15(4.z.6,\'w\',q(){r a=$(7).5();4.v.5(m[4.8.5()][a])});g.15(4.z.v,\'16 O\',q(e){r a=$(7),74=[],5=\'\',i,j;a.5(a.5().76(/[^0-9]/g,\'\'));5=a.5().77();o(3===5.19){P(i H m){o(m.I(i)){P(j H m[i]){o(m[i].I(j)){o(5===m[i][j]){4.8.5(i).y(\'w\');4.6.5(j).y(\'w\');7a}}}}}}});4.8.5(p.1m).y(\'w\');o(0!==p.12.19){4.6.5(p.12).y(\'w\')}G{4.6.B(\'u:N\').X(\'Y\',F)}4.v.5(p.1i).y(\'O\');o(F===p.1n){o(\'1a\'!==10 Q.R){13(\'7g 7h 1d 7j 1e 7l.\');x}1p{r h;r k=!!(1g.1h);o(k){1g.1h.7q(q(d){o(d){h=1j Q.R.1k();r e=1j Q.R.7u(d.1l.7w,d.1l.7x);h.7y({\'7z\':e},q(a,b){o(b==Q.R.7B.7C){o(a[1]){r c=a[1].7E.7F(0,3);o(0!==c){4.v.5(c).y(\'O\')}}}G{13(\'1k 7G 7H 7I: \'+b)}})}})}G{13(\'7J 7K 7L 1e 7M 7N 7O 1d.\');x}}1b(e){x}}})},7P:q(){x 7.E(q(){$(7).1o(\'C\',\'w\').1o(\'S\',\'16 O\').7R()})},7S:q(){x 7.E(q(){$(7).7T(\'C:N\').B(\'u:N\').X(\'Y\',F).y(\'w\')})},7U:q(){r b=[];7.E(q(){r a=$(7);a.B().E(q(){r s=$(7);b.7W(s.L(\'A\')+\'=\'+s.5())})});x b.14(\'&\')}};$.7X.7Y=q(a){r b=7,7Z={};o(\'80\'===10 a){x n[a].1q(7,82.83.84.85(17,1))}G o(\'1a\'===10 a||!a){x n.1r.1q(7,17)}}}(63));',62,504,'||||wrap|val|district|this|county||||||||||||||||if|opts|function|var||tpl|option|zipcode|change|return|trigger|selector|name|children|select|appendTo|each|true|else|in|hasOwnProperty|opt|value|attr|css|first|blur|for|google|maps|input|zipcodeName|districtName|addClass|countyName|prop|selected|empty|typeof|readonly|districtSel|alert|join|delegate|keyup|arguments|type|length|object|catch|append|API|not|text|navigator|geolocation|zipcodeSel|new|Geocoder|coords|countySel|detect|undelegate|try|apply|init|334|335|336|337|338|350|351|352|353|354|356|357|358|360|361|362|363|364|365|366|367|368|369|400|401|402|403|404|406|407|408|411|412|413|414|420|421|422|423|424|426|427|428|429|432|433|434|435|436|437|438|439|500|502|503|504|505|506|507|508|509|510|511|512|513|514|515|516|520|521|522|523|524|525|526|527|528|530|540|541|542|544|545|546|551|552|553|555|556|557|558|600|602|603|604|605|606|607|608|611|612|613|614|615|616|621|622|623|624|625|630|631|632|633|634|635|636|637|638|640|643|646|647|648|649|651|652|653|654|655|700|701|702|704|708|709|710|711|712|713|714|715|716|717|718|719|720|721|722|723|724|725|726|727|730|731|732|733|734|735|736|737|741|742|use|744|745|800|801|802|803|804|805|806|807|811|812|813|814|815|820|821|822|823|824|825|826|827|828|829|830|831|832|833|840|842|843|844|845|846|847|848|849|851|852|900|901|902|903|904|905|906|907|908|909|911|912|913|920|921|922|923|924|925|926|927|928|929|931|932|940|941|942|943|944|945|946|947|950|951|952|953|954|955|956|957|958|959|961|962|963|964|965|966|970|971|972|973|974|975|976|977|978|979|981|982|983|890|891|892|893|894|896|209|210|211|212|880|881|882|883|884|885|817|819|jQuery|strict|200|201|202|203|204|205|false|206|100|103|104|105|106|108|110|111|112|114|115|116|207|extend|208|220|221|222|223|224|226|227|228|231|232|233|234|235|236|237|238|239|241|242|243|244|247|248|249|251|252|253|260|261|262|263|264|265|266|267|268|269|270|result|272|replace|toString|290|300|break|302|303|304|305|306|Google|Maps|307|was|308|reloaded|310|311|312|313|getCurrentPosition|314|315|320|LatLng|324|latitude|longitude|geocode|latLng|325|GeocoderStatus|OK|326|formatted_address|substring|failed|due|to|Your|browser|is|supported|W3C|Geolocation|destroy|327|remove|reset|find|serialize|328|push|fn|twzipcode|container|string|330|Array|prototype|slice|call|333|743'.split('|'),0,{})) 2 | -------------------------------------------------------------------------------- /jquery.twzipcode.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery TWzipcode v1.7.15 , Licensed MIT (c) essoduke.org | https://code.essoduke.org/twzipcode/ */ 2 | (function(g,p,q,r){function n(a){return"string"===typeof a?a.replace(/[\u53f0]+/gi,"\u81fa"):a}function m(a,b){this.container=g(a);this.options=g.extend({},{countyName:"county",css:[],detect:!1,districtName:"district",googleMapsKey:"",hideCounty:[],hideDistrict:[],onCountySelect:null,onDistrictSelect:null,onZipcodeKeyUp:null,readonly:!1,zipcodeName:"zipcode",zipcodePlaceholder:"\u90f5\u905e\u5340\u865f",zipcodeIntoDistrict:!1},b);this.init()}var f={"\u57fa\u9686\u5e02":{"\u4ec1\u611b\u5340":"200", 3 | "\u4fe1\u7fa9\u5340":"201","\u4e2d\u6b63\u5340":"202","\u4e2d\u5c71\u5340":"203","\u5b89\u6a02\u5340":"204","\u6696\u6696\u5340":"205","\u4e03\u5835\u5340":"206"},"\u81fa\u5317\u5e02":{"\u4e2d\u6b63\u5340":"100","\u5927\u540c\u5340":"103","\u4e2d\u5c71\u5340":"104","\u677e\u5c71\u5340":"105","\u5927\u5b89\u5340":"106","\u842c\u83ef\u5340":"108","\u4fe1\u7fa9\u5340":"110","\u58eb\u6797\u5340":"111","\u5317\u6295\u5340":"112","\u5167\u6e56\u5340":"114","\u5357\u6e2f\u5340":"115","\u6587\u5c71\u5340":"116"}, 4 | "\u65b0\u5317\u5e02":{"\u842c\u91cc\u5340":"207","\u91d1\u5c71\u5340":"208","\u677f\u6a4b\u5340":"220","\u6c50\u6b62\u5340":"221","\u6df1\u5751\u5340":"222","\u77f3\u7887\u5340":"223","\u745e\u82b3\u5340":"224","\u5e73\u6eaa\u5340":"226","\u96d9\u6eaa\u5340":"227","\u8ca2\u5bee\u5340":"228","\u65b0\u5e97\u5340":"231","\u576a\u6797\u5340":"232","\u70cf\u4f86\u5340":"233","\u6c38\u548c\u5340":"234","\u4e2d\u548c\u5340":"235","\u571f\u57ce\u5340":"236","\u4e09\u5cfd\u5340":"237","\u6a39\u6797\u5340":"238", 5 | "\u9daf\u6b4c\u5340":"239","\u4e09\u91cd\u5340":"241","\u65b0\u838a\u5340":"242","\u6cf0\u5c71\u5340":"243","\u6797\u53e3\u5340":"244","\u8606\u6d32\u5340":"247","\u4e94\u80a1\u5340":"248","\u516b\u91cc\u5340":"249","\u6de1\u6c34\u5340":"251","\u4e09\u829d\u5340":"252","\u77f3\u9580\u5340":"253"},"\u5b9c\u862d\u7e23":{"\u5b9c\u862d\u5e02":"260","\u982d\u57ce\u93ae":"261","\u7901\u6eaa\u9109":"262","\u58ef\u570d\u9109":"263","\u54e1\u5c71\u9109":"264","\u7f85\u6771\u93ae":"265","\u4e09\u661f\u9109":"266", 6 | "\u5927\u540c\u9109":"267","\u4e94\u7d50\u9109":"268","\u51ac\u5c71\u9109":"269","\u8607\u6fb3\u93ae":"270","\u5357\u6fb3\u9109":"272","\u91e3\u9b5a\u81fa\u5217\u5dbc":"290"},"\u65b0\u7af9\u5e02":{"\u6771\u5340":"300","\u5317\u5340":"300","\u9999\u5c71\u5340":"300"},"\u65b0\u7af9\u7e23":{"\u7af9\u5317\u5e02":"302","\u6e56\u53e3\u9109":"303","\u65b0\u8c50\u9109":"304","\u65b0\u57d4\u93ae":"305","\u95dc\u897f\u93ae":"306","\u828e\u6797\u9109":"307","\u5bf6\u5c71\u9109":"308","\u7af9\u6771\u93ae":"310", 7 | "\u4e94\u5cf0\u9109":"311","\u6a6b\u5c71\u9109":"312","\u5c16\u77f3\u9109":"313","\u5317\u57d4\u9109":"314","\u5ce8\u7709\u9109":"315"},"\u6843\u5712\u5e02":{"\u4e2d\u58e2\u5340":"320","\u5e73\u93ae\u5340":"324","\u9f8d\u6f6d\u5340":"325","\u694a\u6885\u5340":"326","\u65b0\u5c4b\u5340":"327","\u89c0\u97f3\u5340":"328","\u6843\u5712\u5340":"330","\u9f9c\u5c71\u5340":"333","\u516b\u5fb7\u5340":"334","\u5927\u6eaa\u5340":"335","\u5fa9\u8208\u5340":"336","\u5927\u5712\u5340":"337","\u8606\u7af9\u5340":"338"}, 8 | "\u82d7\u6817\u7e23":{"\u7af9\u5357\u93ae":"350","\u982d\u4efd\u5e02":"351","\u4e09\u7063\u9109":"352","\u5357\u5e84\u9109":"353","\u7345\u6f6d\u9109":"354","\u5f8c\u9f8d\u93ae":"356","\u901a\u9704\u93ae":"357","\u82d1\u88e1\u93ae":"358","\u82d7\u6817\u5e02":"360","\u9020\u6a4b\u9109":"361","\u982d\u5c4b\u9109":"362","\u516c\u9928\u9109":"363","\u5927\u6e56\u9109":"364","\u6cf0\u5b89\u9109":"365","\u9285\u947c\u9109":"366","\u4e09\u7fa9\u9109":"367","\u897f\u6e56\u9109":"368","\u5353\u862d\u93ae":"369"}, 9 | "\u81fa\u4e2d\u5e02":{"\u4e2d\u5340":"400","\u6771\u5340":"401","\u5357\u5340":"402","\u897f\u5340":"403","\u5317\u5340":"404","\u5317\u5c6f\u5340":"406","\u897f\u5c6f\u5340":"407","\u5357\u5c6f\u5340":"408","\u592a\u5e73\u5340":"411","\u5927\u91cc\u5340":"412","\u9727\u5cf0\u5340":"413","\u70cf\u65e5\u5340":"414","\u8c50\u539f\u5340":"420","\u540e\u91cc\u5340":"421","\u77f3\u5ca1\u5340":"422","\u6771\u52e2\u5340":"423","\u548c\u5e73\u5340":"424","\u65b0\u793e\u5340":"426","\u6f6d\u5b50\u5340":"427", 10 | "\u5927\u96c5\u5340":"428","\u795e\u5ca1\u5340":"429","\u5927\u809a\u5340":"432","\u6c99\u9e7f\u5340":"433","\u9f8d\u4e95\u5340":"434","\u68a7\u68f2\u5340":"435","\u6e05\u6c34\u5340":"436","\u5927\u7532\u5340":"437","\u5916\u57d4\u5340":"438","\u5927\u5b89\u5340":"439"},"\u5f70\u5316\u7e23":{"\u5f70\u5316\u5e02":"500","\u82ac\u5712\u9109":"502","\u82b1\u58c7\u9109":"503","\u79c0\u6c34\u9109":"504","\u9e7f\u6e2f\u93ae":"505","\u798f\u8208\u9109":"506","\u7dda\u897f\u9109":"507","\u548c\u7f8e\u93ae":"508", 11 | "\u4f38\u6e2f\u9109":"509","\u54e1\u6797\u5e02":"510","\u793e\u982d\u9109":"511","\u6c38\u9756\u9109":"512","\u57d4\u5fc3\u9109":"513","\u6eaa\u6e56\u93ae":"514","\u5927\u6751\u9109":"515","\u57d4\u9e7d\u9109":"516","\u7530\u4e2d\u93ae":"520","\u5317\u6597\u93ae":"521","\u7530\u5c3e\u9109":"522","\u57e4\u982d\u9109":"523","\u6eaa\u5dde\u9109":"524","\u7af9\u5858\u9109":"525","\u4e8c\u6797\u93ae":"526","\u5927\u57ce\u9109":"527","\u82b3\u82d1\u9109":"528","\u4e8c\u6c34\u9109":"530"},"\u5357\u6295\u7e23":{"\u5357\u6295\u5e02":"540", 12 | "\u4e2d\u5bee\u9109":"541","\u8349\u5c6f\u93ae":"542","\u570b\u59d3\u9109":"544","\u57d4\u91cc\u93ae":"545","\u4ec1\u611b\u9109":"546","\u540d\u9593\u9109":"551","\u96c6\u96c6\u93ae":"552","\u6c34\u91cc\u9109":"553","\u9b5a\u6c60\u9109":"555","\u4fe1\u7fa9\u9109":"556","\u7af9\u5c71\u93ae":"557","\u9e7f\u8c37\u9109":"558"},"\u5609\u7fa9\u5e02":{"\u6771\u5340":"600","\u897f\u5340":"600"},"\u5609\u7fa9\u7e23":{"\u756a\u8def\u9109":"602","\u6885\u5c71\u9109":"603","\u7af9\u5d0e\u9109":"604","\u963f\u91cc\u5c71":"605", 13 | "\u4e2d\u57d4\u9109":"606","\u5927\u57d4\u9109":"607","\u6c34\u4e0a\u9109":"608","\u9e7f\u8349\u9109":"611","\u592a\u4fdd\u5e02":"612","\u6734\u5b50\u5e02":"613","\u6771\u77f3\u9109":"614","\u516d\u8173\u9109":"615","\u65b0\u6e2f\u9109":"616","\u6c11\u96c4\u9109":"621","\u5927\u6797\u93ae":"622","\u6eaa\u53e3\u9109":"623","\u7fa9\u7af9\u9109":"624","\u5e03\u888b\u93ae":"625"},"\u96f2\u6797\u7e23":{"\u6597\u5357\u93ae":"630","\u5927\u57e4\u9109":"631","\u864e\u5c3e\u93ae":"632","\u571f\u5eab\u93ae":"633", 14 | "\u8912\u5fe0\u9109":"634","\u6771\u52e2\u9109":"635","\u81fa\u897f\u9109":"636","\u5d19\u80cc\u9109":"637","\u9ea5\u5bee\u9109":"638","\u6597\u516d\u5e02":"640","\u6797\u5167\u9109":"643","\u53e4\u5751\u9109":"646","\u83bf\u6850\u9109":"647","\u897f\u87ba\u93ae":"648","\u4e8c\u5d19\u9109":"649","\u5317\u6e2f\u93ae":"651","\u6c34\u6797\u9109":"652","\u53e3\u6e56\u9109":"653","\u56db\u6e56\u9109":"654","\u5143\u9577\u9109":"655"},"\u81fa\u5357\u5e02":{"\u4e2d\u897f\u5340":"700","\u6771\u5340":"701", 15 | "\u5357\u5340":"702","\u5317\u5340":"704","\u5b89\u5e73\u5340":"708","\u5b89\u5357\u5340":"709","\u6c38\u5eb7\u5340":"710","\u6b78\u4ec1\u5340":"711","\u65b0\u5316\u5340":"712","\u5de6\u93ae\u5340":"713","\u7389\u4e95\u5340":"714","\u6960\u897f\u5340":"715","\u5357\u5316\u5340":"716","\u4ec1\u5fb7\u5340":"717","\u95dc\u5edf\u5340":"718","\u9f8d\u5d0e\u5340":"719","\u5b98\u7530\u5340":"720","\u9ebb\u8c46\u5340":"721","\u4f73\u91cc\u5340":"722","\u897f\u6e2f\u5340":"723","\u4e03\u80a1\u5340":"724", 16 | "\u5c07\u8ecd\u5340":"725","\u5b78\u7532\u5340":"726","\u5317\u9580\u5340":"727","\u65b0\u71df\u5340":"730","\u5f8c\u58c1\u5340":"731","\u767d\u6cb3\u5340":"732","\u6771\u5c71\u5340":"733","\u516d\u7532\u5340":"734","\u4e0b\u71df\u5340":"735","\u67f3\u71df\u5340":"736","\u9e7d\u6c34\u5340":"737","\u5584\u5316\u5340":"741","\u5927\u5167\u5340":"742","\u5c71\u4e0a\u5340":"743","\u65b0\u5e02\u5340":"744","\u5b89\u5b9a\u5340":"745"},"\u9ad8\u96c4\u5e02":{"\u65b0\u8208\u5340":"800","\u524d\u91d1\u5340":"801", 17 | "\u82d3\u96c5\u5340":"802","\u9e7d\u57d5\u5340":"803","\u9f13\u5c71\u5340":"804","\u65d7\u6d25\u5340":"805","\u524d\u93ae\u5340":"806","\u4e09\u6c11\u5340":"807","\u6960\u6893\u5340":"811","\u5c0f\u6e2f\u5340":"812","\u5de6\u71df\u5340":"813","\u4ec1\u6b66\u5340":"814","\u5927\u793e\u5340":"815","\u6771\u6c99\u7fa4\u5cf6":"817","\u5357\u6c99\u7fa4\u5cf6":"819","\u5ca1\u5c71\u5340":"820","\u8def\u7af9\u5340":"821","\u963f\u84ee\u5340":"822","\u7530\u5bee\u5340":"823","\u71d5\u5de2\u5340":"824","\u6a4b\u982d\u5340":"825", 18 | "\u6893\u5b98\u5340":"826","\u5f4c\u9640\u5340":"827","\u6c38\u5b89\u5340":"828","\u6e56\u5167\u5340":"829","\u9cf3\u5c71\u5340":"830","\u5927\u5bee\u5340":"831","\u6797\u5712\u5340":"832","\u9ce5\u677e\u5340":"833","\u5927\u6a39\u5340":"840","\u65d7\u5c71\u5340":"842","\u7f8e\u6fc3\u5340":"843","\u516d\u9f9c\u5340":"844","\u5167\u9580\u5340":"845","\u6749\u6797\u5340":"846","\u7532\u4ed9\u5340":"847","\u6843\u6e90\u5340":"848","\u90a3\u746a\u590f\u5340":"849","\u8302\u6797\u5340":"851","\u8304\u8423\u5340":"852"}, 19 | "\u5c4f\u6771\u7e23":{"\u5c4f\u6771\u5e02":"900","\u4e09\u5730\u9580\u9109":"901","\u9727\u81fa\u9109":"902","\u746a\u5bb6\u9109":"903","\u4e5d\u5982\u9109":"904","\u91cc\u6e2f\u9109":"905","\u9ad8\u6a39\u9109":"906","\u9e7d\u57d4\u9109":"907","\u9577\u6cbb\u9109":"908","\u9e9f\u6d1b\u9109":"909","\u7af9\u7530\u9109":"911","\u5167\u57d4\u9109":"912","\u842c\u4e39\u9109":"913","\u6f6e\u5dde\u93ae":"920","\u6cf0\u6b66\u9109":"921","\u4f86\u7fa9\u9109":"922","\u842c\u5dd2\u9109":"923","\u5d01\u9802\u9109":"924", 20 | "\u65b0\u57e4\u9109":"925","\u5357\u5dde\u9109":"926","\u6797\u908a\u9109":"927","\u6771\u6e2f\u93ae":"928","\u7409\u7403\u9109":"929","\u4f73\u51ac\u9109":"931","\u65b0\u5712\u9109":"932","\u678b\u5bee\u9109":"940","\u678b\u5c71\u9109":"941","\u6625\u65e5\u9109":"942","\u7345\u5b50\u9109":"943","\u8eca\u57ce\u9109":"944","\u7261\u4e39\u9109":"945","\u6046\u6625\u93ae":"946","\u6eff\u5dde\u9109":"947"},"\u81fa\u6771\u7e23":{"\u81fa\u6771\u5e02":"950","\u7da0\u5cf6\u9109":"951","\u862d\u5dbc\u9109":"952", 21 | "\u5ef6\u5e73\u9109":"953","\u5351\u5357\u9109":"954","\u9e7f\u91ce\u9109":"955","\u95dc\u5c71\u93ae":"956","\u6d77\u7aef\u9109":"957","\u6c60\u4e0a\u9109":"958","\u6771\u6cb3\u9109":"959","\u6210\u529f\u93ae":"961","\u9577\u6ff1\u9109":"962","\u592a\u9ebb\u91cc\u9109":"963","\u91d1\u5cf0\u9109":"964","\u5927\u6b66\u9109":"965","\u9054\u4ec1\u9109":"966"},"\u82b1\u84ee\u7e23":{"\u82b1\u84ee\u5e02":"970","\u65b0\u57ce\u9109":"971","\u79c0\u6797\u9109":"972","\u5409\u5b89\u9109":"973","\u58fd\u8c50\u9109":"974", 22 | "\u9cf3\u6797\u93ae":"975","\u5149\u5fa9\u9109":"976","\u8c50\u6ff1\u9109":"977","\u745e\u7a57\u9109":"978","\u842c\u69ae\u9109":"979","\u7389\u91cc\u93ae":"981","\u5353\u6eaa\u9109":"982","\u5bcc\u91cc\u9109":"983"},"\u91d1\u9580\u7e23":{"\u91d1\u6c99\u93ae":"890","\u91d1\u6e56\u93ae":"891","\u91d1\u5be7\u9109":"892","\u91d1\u57ce\u93ae":"893","\u70c8\u5dbc\u9109":"894","\u70cf\u5775\u9109":"896"},"\u9023\u6c5f\u7e23":{"\u5357\u7aff\u9109":"209","\u5317\u7aff\u9109":"210","\u8392\u5149\u9109":"211", 23 | "\u6771\u5f15\u9109":"212"},"\u6f8e\u6e56\u7e23":{"\u99ac\u516c\u5e02":"880","\u897f\u5dbc\u9109":"881","\u671b\u5b89\u9109":"882","\u4e03\u7f8e\u9109":"883","\u767d\u6c99\u9109":"884","\u6e56\u897f\u9109":"885"}};m.prototype={VERSION:"1.7.15",data:function(){var a=this.wrap;return"undefined"!==typeof f[a.county.val()]?f[a.county.val()]:f},serialize:function(){var a=[],b={},c={},e={};b=this.container.find("select,input");b.length?b.each(function(){c=g(this);a.push(c.attr("name")+"="+c.val())}):g(this).children().each(function(){e= 24 | g(this);a.push(e.attr("name")+"="+e.val())});return a.join("&")},destroy:function(){g.data(this.container.get(0),"twzipcode",null);if(this.container.length)return this.container.empty().off("change.twzipcode keyup.twzipcode blur.twzipcode")},get:function(a){function b(a){"undefined"!==typeof c.wrap[a]&&e.push(c.wrap[a].val())}var c=this,e=[];"function"===typeof a?a.call(this,this.wrap.county.val(),this.wrap.district.val(),this.wrap.zipcode.val()):"string"===typeof a?a.split(",").forEach(b):Array.isArray(a)? 25 | a.forEach(b):e=this.wrap;return e},set:function(a){var b=g.extend({},{county:"",district:"",zipcode:""},a);try{"string"===typeof a||"number"===typeof a?this.wrap.zipcode.val(a).trigger("blur.twzipcode"):(b.zipcode&&this.wrap.zipcode.val(b.zipcode).trigger("blur.twzipcode"),b.county&&this.wrap.county.val(b.county).trigger("change.twzipcode"),b.district&&this.wrap.district.val(b.district).trigger("change.twzipcode"))}catch(c){console.warn(c.message)}finally{return this.container}},reset:function(a, 26 | b){var c=this.wrap,e=this.options,d="",l=[];switch(b){case "district":c.district.html('');break;default:c.county.html('');c.district.html('');for(d in f)"undefined"!==typeof f[d]&&-1===e.hideCounty.indexOf(d)&&l.push('");g(l.join("")).appendTo(c.county)}c.zipcode.val("")},bindings:function(){var a=this,b=a.options,c=a.wrap,e= 27 | "",d="",l="";c.county.on("change.twzipcode",function(){var k=g(this).val(),h="",d=[];c.district.empty();if(k){if(!0===b.zipcodeIntoDistrict)for(h in f[k])"undefined"!==typeof f[k][h]&&-1===b.hideDistrict.indexOf(h)&&-1===b.hideDistrict.indexOf(f[k][h])&&(d.push('"));else for(h in f[k])"undefined"!==typeof f[k][h]&&-1===b.hideDistrict.indexOf(h)&&-1===b.hideDistrict.indexOf(f[k][h])&&(d.push('")); 28 | c.district.append(d.join("")).trigger("change.twzipcode")}else c.county.find("option:first").prop("selected",!0),a.reset("district");"function"===typeof b.onCountySelect&&b.onCountySelect.call(this)});c.district.on("change.twzipcode",function(){var a=g(this).val(),d=n(c.county.val());d&&c.zipcode.val(f[d][a]);"function"===typeof b.onDistrictSelect&&b.onDistrictSelect.call(this)});c.zipcode.on("keyup.twzipcode blur.twzipcode",function(){var a=g(this),d="",e="";a.val(a.val().replace(/[^0-9]/g,"")); 29 | a=a.val().toString();if(3===a.length)for(d in f)if("undefined"!==typeof f[d])for(e in f[d])if("undefined"!==typeof f[d][e]&&a===f[d][e]){c.county.val(d).trigger("change.twzipcode");c.district.val(e).trigger("change.twzipcode");break}"function"===typeof b.onZipcodeKeyUp&&b.onZipcodeKeyUp.call(this)});(function(){var b=a.role.zipcode.data(),c=a.role.county.data(),d=a.role.district.data(),e;for(e in b)"role"!==e&&a.role.zipcode.find(":input").attr(e,b[e]);for(e in c)"role"!==e&&a.role.county.find("select").attr(e, 30 | c[e]);for(e in d)"role"!==e&&a.role.district.find("select").attr(e,d[e])})();e="undefined"!==typeof b.zipcodeSel?b.zipcodeSel:"undefined"!==typeof a.role.zipcode.data("value")?a.role.zipcode.data("value"):b.zipcodeSel;d="undefined"!==typeof b.countySel?b.countySel:"undefined"!==typeof a.role.county.data("value")?a.role.county.data("value"):b.countySel;l="undefined"!==typeof b.districtSel?b.districtSel:"undefined"!==typeof a.role.district.data("value")?a.role.district.data("value"):b.districtSel;d&& 31 | (d=n(d),a.wrap.county.val(d).trigger("change.twzipcode"),"undefined"!==typeof f[d]&&"undefined"!==typeof f[d][l]&&a.wrap.district.val(l).trigger("change.twzipcode"));e&&3===e.toString().length&&a.wrap.zipcode.val(e).trigger("blur.twzipcode")},geoLocation:function(a){var b=this,c=navigator.geolocation,e=b.options;c&&a&&c.getCurrentPosition(function(c){var d={};"coords"in c&&"latitude"in c.coords&&"longitude"in c.coords&&(d=[c.coords.latitude,c.coords.longitude],g.getJSON("https://maps.googleapis.com/maps/api/geocode/json", 32 | {key:e.googleMapsKey,sensor:!1,latlng:d.join(",")},function(d){d&&"undefined"!==typeof d.results&&"undefined"!==typeof d.results[0].address_components&&"undefined"!==typeof d.results[0].address_components[0]&&(d=d.results[0].address_components[d.results[0].address_components.length-1].long_name)&&b.wrap.zipcode.val(d.toString()).trigger("blur.twzipcode");"function"===typeof a&&a.call(b,c)}))},function(a){console.error(a)},{maximumAge:6E5,timeout:3E3,enableHighAccuracy:!1})},init:function(){var a= 33 | this.container,b=this.options,c={county:a.find("[data-role=county]:first"),district:a.find("[data-role=district]:first"),zipcode:a.find("[data-role=zipcode]:first")},e=c.county.data("name")||b.countyName,d=c.district.data("name")||b.districtName,f=c.zipcode.data("name")||b.zipcodeName,k=c.zipcode.data("placeholder")||b.zipcodePlaceholder,h=c.zipcode.data("readonly")||b.readonly;g("").attr("name",d).addClass(c.district.data("style")||("undefined"!==typeof b.css[1]?b.css[1]:"")).appendTo(c.district.length?c.district:a);g("").attr({type:"text",name:f,placeholder:k}).prop("readonly",h).addClass(c.zipcode.data("style")||("undefined"!==typeof b.css[2]?b.css[2]:"")).appendTo(c.zipcode.length?c.zipcode:a);this.wrap={county:a.find('select[name="'+e+'"]:first'),district:a.find('select[name="'+d+'"]:first'),zipcode:a.find('input[type=text][name="'+f+'"]:first')}; 35 | !0===b.zipcodeIntoDistrict&&this.wrap.zipcode.hide();this.role=c;this.reset();this.bindings();this.geoLocation(b.detect)}};g.fn.twzipcode=function(a){var b={},c=[],e=arguments;return"string"===typeof a?(this.each(function(){b=g.data(this,"twzipcode");b instanceof m&&"function"===typeof b[a]&&(c=b[a].apply(b,Array.prototype.slice.call(e,1)))}),"undefined"!==typeof c?c:this):this.each(function(){g.data(this,"twzipcode")||g.data(this,"twzipcode",new m(this,a))})}})(window.jQuery||{},window,document); 36 | -------------------------------------------------------------------------------- /old/jquery.twzipcode-1.4.1.js: -------------------------------------------------------------------------------- 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 | * 台灣郵遞區號外掛 / Taiwan Zip Code Plugin of jQuery 9 | * http://app.essoduke.org/twzipcode/ 10 | * 11 | * Wed, 27 April 2011 10:34:53 GMT 12 | */ 13 | 14 | (function ($) { 15 | 16 | 'use strict'; 17 | 18 | var data = { 19 | '基隆市': {'仁愛區': '200', '信義區': '201', '中正區': '202', '中山區': '203', '安樂區': '204', '暖暖區': '205', '七堵區': '206'}, 20 | '台北市': {'中正區': '100', '大同區': '103', '中山區': '104', '松山區': '105', '大安區': '106', '萬華區': '108', '信義區': '110', '士林區': '111', '北投區': '112', '內湖區': '114', '南港區': '115', '文山區': '116'}, 21 | '新北市': { 22 | '萬里區': '207', '金山區': '208', '板橋區': '220', '汐止區': '221', '深坑區': '222', '石碇區': '223', 23 | '瑞芳區': '224', '平溪區': '226', '雙溪區': '227', '貢寮區': '228', '新店區': '231', '坪林區': '232', 24 | '烏來區': '233', '永和區': '234', '中和區': '235', '土城區': '236', '三峽區': '237', '樹林區': '238', 25 | '鶯歌區': '239', '三重區': '241', '新莊區': '242', '泰山區': '243', '林口區': '244', '蘆洲區': '247', 26 | '五股區': '248', '八里區': '249', '淡水區': '251', '三芝區': '252', '石門區': '253' 27 | }, 28 | '宜蘭縣': { 29 | '宜蘭市': '260', '頭城鎮': '261', '礁溪鄉': '262', '壯圍鄉': '263', '員山鄉': '264', '羅東鎮': '265', 30 | '三星鄉': '266', '大同鄉': '267', '五結鄉': '268', '冬山鄉': '269', '蘇澳鎮': '270', '南澳鄉': '272', 31 | '釣魚台列嶼': '290' 32 | }, 33 | '新竹市': {'新竹市': '300'}, 34 | '新竹縣': { 35 | '竹北市': '302', '湖口鄉': '303', '新豐鄉': '304', '新埔鎮': '305', '關西鎮': '306', '芎林鄉': '307', 36 | '寶山鄉': '308', '竹東鎮': '310', '五峰鄉': '311', '橫山鄉': '312', '尖石鄉': '313', '北埔鄉': '314', 37 | '峨嵋鄉': '315' 38 | }, 39 | '桃園縣': { 40 | '中壢市': '320', '平鎮市': '324', '龍潭鄉': '325', '楊梅鎮': '326', '新屋鄉': '327', '觀音鄉': '328', 41 | '桃園市': '330', '龜山鄉': '333', '八德市': '334', '大溪鎮': '335', '復興鄉': '336', '大園鄉': '337', 42 | '蘆竹鄉': '338' 43 | }, 44 | '苗栗縣': { 45 | '竹南鎮': '350', '頭份鎮': '351', '三灣鄉': '352', '南庄鄉': '353', '獅潭鄉': '354', '後龍鎮': '356', 46 | '通霄鎮': '357', '苑裡鎮': '358', '苗栗市': '360', '造橋鄉': '361', '頭屋鄉': '362', '公館鄉': '363', 47 | '大湖鄉': '364', '泰安鄉': '365', '銅鑼鄉': '366', '三義鄉': '367', '西湖鄉': '368', '卓蘭鎮': '369' 48 | }, 49 | '台中市': { 50 | '中區': '400', '東區': '401', '南區': '402', '西區': '403', '北區': '404', '北屯區': '406', '西屯區': '407', '南屯區': '408', 51 | '太平區': '411', '大里區': '412', '霧峰區': '413', '烏日區': '414', '豐原區': '420', '后里區': '421', 52 | '石岡區': '422', '東勢區': '423', '和平區': '424', '新社區': '426', '潭子區': '427', '大雅區': '428', 53 | '神岡區': '429', '大肚區': '432', '沙鹿區': '433', '龍井區': '434', '梧棲區': '435', '清水區': '436', 54 | '大甲區': '437', '外埔區': '438', '大安區': '439' 55 | }, 56 | '彰化縣': { 57 | '彰化市': '500', '芬園鄉': '502', '花壇鄉': '503', '秀水鄉': '504', '鹿港鎮': '505', '福興鄉': '506', 58 | '線西鄉': '507', '和美鎮': '508', '伸港鄉': '509', '員林鎮': '510', '社頭鄉': '511', '永靖鄉': '512', 59 | '埔心鄉': '513', '溪湖鎮': '514', '大村鄉': '515', '埔鹽鄉': '516', '田中鎮': '520', '北斗鎮': '521', 60 | '田尾鄉': '522', '埤頭鄉': '523', '溪州鄉': '524', '竹塘鄉': '525', '二林鎮': '526', '大城鄉': '527', 61 | '芳苑鄉': '528', '二水鄉': '530' 62 | }, 63 | '南投縣': { 64 | '南投市': '540', '中寮鄉': '541', '草屯鎮': '542', '國姓鄉': '544', '埔里鎮': '545', '仁愛鄉': '546', 65 | '名間鄉': '551', '集集鎮': '552', '水里鄉': '553', '魚池鄉': '555', '信義鄉': '556', '竹山鎮': '557', 66 | '鹿谷鄉': '558' 67 | }, 68 | '嘉義市': {'嘉義市': '600'}, 69 | '嘉義縣': { 70 | '番路鄉': '602', '梅山鄉': '603', '竹崎鄉': '604', '阿里山': '605', '中埔鄉': '606', '大埔鄉': '607', 71 | '水上鄉': '608', '鹿草鄉': '611', '太保市': '612', '朴子市': '613', '東石鄉': '614', '六腳鄉': '615', 72 | '新港鄉': '616', '民雄鄉': '621', '大林鎮': '622', '溪口鄉': '623', '義竹鄉': '624', '布袋鎮': '625' 73 | }, 74 | '雲林縣': { 75 | '斗南鎮': '630', '大埤鄉': '631', '虎尾鎮': '632', '土庫鎮': '633', '褒忠鄉': '634', '東勢鄉': '635', 76 | '臺西鄉': '636', '崙背鄉': '637', '麥寮鄉': '638', '斗六市': '640', '林內鄉': '643', '古坑鄉': '646', 77 | '莿桐鄉': '647', '西螺鎮': '648', '二崙鄉': '649', '北港鎮': '651', '水林鄉': '652', '口湖鄉': '653', 78 | '四湖鄉': '654', '元長鄉': '655' 79 | }, 80 | '台南市': { 81 | '中西區': '700', '東區': '701', '南區': '702', '北區': '704', '安平區': '708', '安南區': '709', 82 | '永康區': '710', '歸仁區': '711', '新化區': '712', '左鎮區': '713', '玉井區': '714', '楠西區': '715', 83 | '南化區': '716', '仁德區': '717', '關廟區': '718', '龍崎區': '719', '官田區': '720', '麻豆區': '721', 84 | '佳里區': '722', '西港區': '723', '七股區': '724', '將軍區': '725', '學甲區': '726', '北門區': '727', 85 | '新營區': '730', '後壁區': '731', '白河區': '732', '東山區': '733', '六甲區': '734', '下營區': '735', 86 | '柳營區': '736', '鹽水區': '737', '善化區': '741', '大內區': '742', '山上區': '743', '新市區': '744', 87 | '安定區': '745' 88 | }, 89 | '高雄市': { 90 | '新興區': '800', '前金區': '801', '苓雅區': '802', '鹽埕區': '803', '鼓山區': '804', '旗津區': '805', 91 | '前鎮區': '806', '三民區': '807', '楠梓區': '811', '小港區': '812', '左營區': '813', 92 | '仁武區': '814', '大社區': '815', '岡山區': '820', '路竹區': '821', '阿蓮區': '822', '田寮鄉': '823', 93 | '燕巢區': '824', '橋頭區': '825', '梓官區': '826', '彌陀區': '827', '永安區': '828', '湖內鄉': '829', 94 | '鳳山區': '830', '大寮區': '831', '林園區': '832', '鳥松區': '833', '大樹區': '840', '旗山區': '842', 95 | '美濃區': '843', '六龜區': '844', '內門區': '845', '杉林區': '846', '甲仙區': '847', '桃源區': '848', 96 | '那瑪夏區': '849', '茂林區': '851', '茄萣區': '852' 97 | }, 98 | '屏東縣': { 99 | '屏東市': '900', '三地門': '901', '霧臺鄉': '902', '瑪家鄉': '903', '九如鄉': '904', '里港鄉': '905', 100 | '高樹鄉': '906', '鹽埔鄉': '907', '長治鄉': '908', '麟洛鄉': '909', '竹田鄉': '911', '內埔鄉': '912', 101 | '萬丹鄉': '913', '潮州鎮': '920', '泰武鄉': '921', '來義鄉': '922', '萬巒鄉': '923', '崁頂鄉': '924', 102 | '新埤鄉': '925', '南州鄉': '926', '林邊鄉': '927', '東港鎮': '928', '琉球鄉': '929', '佳冬鄉': '931', 103 | '新園鄉': '932', '枋寮鄉': '940', '枋山鄉': '941', '春日鄉': '942', '獅子鄉': '943', '車城鄉': '944', 104 | '牡丹鄉': '945', '恆春鎮': '946', '滿州鄉': '947' 105 | }, 106 | '台東縣': { 107 | '臺東市': '950', '綠島鄉': '951', '蘭嶼鄉': '952', '延平鄉': '953', '卑南鄉': '954', '鹿野鄉': '955', 108 | '關山鎮': '956', '海端鄉': '957', '池上鄉': '958', '東河鄉': '959', '成功鎮': '961', '長濱鄉': '962', 109 | '太麻里鄉': '963', '金峰鄉': '964', '大武鄉': '965', '達仁鄉': '966' 110 | }, 111 | '花蓮縣': { 112 | '花蓮市': '970', '新城鄉': '971', '秀林鄉': '972', '吉安鄉': '973', '壽豐鄉': '974', '鳳林鎮': '975', 113 | '光復鄉': '976', '豐濱鄉': '977', '瑞穗鄉': '978', '萬榮鄉': '979', '玉里鎮': '981', '卓溪鄉': '982', 114 | '富里鄉': '983' 115 | }, 116 | '金門縣': {'金沙鎮': '890', '金湖鎮': '891', '金寧鄉': '892', '金城鎮': '893', '烈嶼鄉': '894', '烏坵鄉': '896'}, 117 | '連江縣': {'南竿鄉': '209', '北竿鄉': '210', '莒光鄉': '211', '東引鄉': '212'}, 118 | '澎湖縣': {'馬公市': '880', '西嶼鄉': '881', '望安鄉': '882', '七美鄉': '883', '白沙鄉': '884', '湖西鄉': '885'}, 119 | '南海諸島': {'東沙': '817', '南沙': '819'} 120 | }; 121 | 122 | //public function 123 | var methods = { 124 | 125 | //initialize 126 | init: function (options) { 127 | 128 | return this.each(function () { 129 | 130 | //default settings 131 | var settings = { 132 | detect: false, 133 | countyName: 'county', 134 | districtName: 'district', 135 | zipcodeName: 'zipcode', 136 | countySel: '', 137 | districtSel: '', 138 | zipcodeSel: '', 139 | readonly: true, 140 | css: [] 141 | }; 142 | 143 | var self = $(this), opts = $.extend(settings, options), tpl = [], i = 0, wrap = {}, county, 144 | opt = ['', '']; 145 | 146 | self.empty(); 147 | 148 | $('').attr({'name': opts.districtName}).appendTo(this); 150 | $('').attr({'type': 'text', 'name': opts.zipcodeName, 'readonly': opts.readonly}).appendTo(this); 151 | 152 | //DOM collections 153 | wrap.selector = { 154 | county: 'select[name="' + opts.countyName + '"]', 155 | district: 'select[name="' + opts.districtName + '"]', 156 | zipcode: 'input[type=text][name="' + opts.zipcodeName + '"]' 157 | }; 158 | 159 | wrap.county = self.children(wrap.selector.county); 160 | wrap.district = self.children(wrap.selector.district); 161 | wrap.zipcode = self.children(wrap.selector.zipcode); 162 | 163 | //add css classname 164 | try { 165 | wrap.county.addClass(opts.css[0]); 166 | wrap.district.addClass(opts.css[1]); 167 | wrap.zipcode.addClass(opts.css[2]); 168 | } catch (e) { 169 | } 170 | 171 | /* 172 | * append select elements 173 | * You could change the sort of elements here. 174 | */ 175 | $(opt[0]).appendTo(wrap.county); 176 | $(opt[1]).appendTo(wrap.district); 177 | 178 | for (county in data) { 179 | if (data.hasOwnProperty(county)) { 180 | tpl[i++] = ''; 185 | } 186 | } 187 | 188 | $(tpl.join('')).appendTo(wrap.county); 189 | 190 | //county change event 191 | self.delegate(wrap.selector.county, 'change', function () { 192 | var val = $(this).val(), i = 0, tpl = [], district; 193 | wrap.district.empty(); 194 | 195 | if (val) { 196 | for (district in data[val]) { 197 | if (data[val].hasOwnProperty(district)) { 198 | tpl[i++] = ''; 203 | } 204 | } 205 | wrap.district.append(tpl.join('')).trigger('change'); 206 | } else { 207 | wrap.county.children('option:first').prop('selected', true); 208 | wrap.district.empty().append(opt[1]); 209 | wrap.zipcode.val(''); 210 | } 211 | } 212 | ); 213 | 214 | //district change event 215 | self.delegate(wrap.selector.district, 'change', function () { 216 | var val = $(this).val(); 217 | wrap.zipcode.val(data[wrap.county.val()][val]); 218 | } 219 | ); 220 | 221 | //zipcode keyup, blur event 222 | self.delegate(wrap.selector.zipcode, 'keyup blur', function (e) { 223 | var me = $(this), result = [], val = '', i, j; 224 | me.val(me.val().replace(/[^0-9]/g, '')); 225 | val = me.val().toString(); 226 | 227 | if (3 === val.length) { 228 | for (i in data) { 229 | if (data.hasOwnProperty(i)) { 230 | for (j in data[i]) { 231 | if (data[i].hasOwnProperty(j)) { 232 | if (val === data[i][j]) { 233 | wrap.county.val(i).trigger('change'); 234 | wrap.district.val(j).trigger('change'); 235 | break; 236 | } 237 | } 238 | } 239 | } 240 | } 241 | } 242 | } 243 | ); 244 | 245 | //After DOM created success then trigger the events. 246 | wrap.county.val(opts.countySel).trigger('change'); 247 | 248 | if (0 !== opts.districtSel.length) { 249 | wrap.district.val(opts.districtSel).trigger('change'); 250 | } else{ 251 | wrap.district.children('option:first').prop('selected', true); 252 | } 253 | 254 | wrap.zipcode.val(opts.zipcodeSel).trigger('blur'); 255 | 256 | /* 257 | * location detect by W3C Geolocation API HTML5 258 | * version: 1.4.1 259 | * essoduke [at] Wed, 12 October 2011 09:46:19 GMT 260 | */ 261 | if (true === opts.detect) { 262 | 263 | //ensure the google maps api was loaded. 264 | if ('object' !== typeof google.maps) { 265 | alert('Google Maps API was not reloaded.'); 266 | return; 267 | } 268 | 269 | try { 270 | var geocoder; 271 | var hasGeolocation = !!(navigator.geolocation); 272 | 273 | //browser supported 274 | if (hasGeolocation) { 275 | navigator.geolocation.getCurrentPosition(function (loc) { 276 | if (loc) { 277 | geocoder = new google.maps.Geocoder(); 278 | var latlng = new google.maps.LatLng(loc.coords.latitude, loc.coords.longitude); 279 | geocoder.geocode({'latLng': latlng}, function(results, status) { 280 | if (status == google.maps.GeocoderStatus.OK) { 281 | if (results[1]) { 282 | var zipcode = results[1].formatted_address.substring(0, 3); 283 | if (0 !== zipcode) { 284 | //opts.zipcodeSel = zipcode; 285 | wrap.zipcode.val(zipcode).trigger('blur'); 286 | } 287 | } 288 | } else { 289 | alert('Geocoder failed due to: ' + status); 290 | } 291 | }); 292 | } 293 | }); 294 | } else { 295 | alert('Your browser is not supported W3C Geolocation API.'); 296 | return; 297 | } 298 | } catch (e) { 299 | //alert(e.description); 300 | //console.log(e); 301 | return; 302 | } 303 | } 304 | }); 305 | }, 306 | 307 | //destroy 308 | destroy: function () { 309 | return this.each(function () { 310 | //unbind and destroy 311 | $(this).undelegate('select', 'change') 312 | .undelegate('input', 'keyup blur') 313 | .remove(); 314 | }); 315 | }, 316 | //reset values 317 | reset: function () { 318 | return this.each(function () { 319 | $(this).find('select:first').children('option:first').prop('selected', true).trigger('change'); 320 | }); 321 | }, 322 | 323 | //serialize result 324 | serialize: function () { 325 | var result = []; 326 | this.each(function () { 327 | var obj = $(this); 328 | obj.children().each(function () { 329 | var s = $(this); 330 | result.push(s.attr('name') + '=' + s.val()); 331 | }); 332 | }); 333 | return result.join('&'); 334 | } 335 | }; 336 | 337 | //main 338 | $.fn.twzipcode = function (method) { 339 | var wrap = this, container = {}; 340 | if ('string' === typeof method) { 341 | return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 342 | } else if ('object' === typeof method || !method) { 343 | return methods.init.apply(this, arguments); 344 | } 345 | }; 346 | 347 | }(jQuery)); 348 | -------------------------------------------------------------------------------- /jquery.twzipcode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery TWzipcode plugin 3 | * https://code.essoduke.org/twzipcode/ 4 | * Copyright 2018 essoduke.org, Licensed MIT. 5 | * 6 | * Changelog 7 | * ------------------------------- 8 | * 縣市自動轉換簡化字「台/臺」 9 | * 10 | * @author essoduke.org 11 | * @license MIT License 12 | */ 13 | ;(function ($, window, document, undefined) { 14 | 15 | 'use strict'; 16 | 17 | // Zipcode JSON data 18 | var data = { 19 | '基隆市': {'仁愛區': '200', '信義區': '201', '中正區': '202', '中山區': '203', '安樂區': '204', '暖暖區': '205', '七堵區': '206'}, 20 | '臺北市': {'中正區': '100', '大同區': '103', '中山區': '104', '松山區': '105', '大安區': '106', '萬華區': '108', '信義區': '110', '士林區': '111', '北投區': '112', '內湖區': '114', '南港區': '115', '文山區': '116'}, 21 | '新北市': { 22 | '萬里區': '207', '金山區': '208', '板橋區': '220', '汐止區': '221', '深坑區': '222', '石碇區': '223', 23 | '瑞芳區': '224', '平溪區': '226', '雙溪區': '227', '貢寮區': '228', '新店區': '231', '坪林區': '232', 24 | '烏來區': '233', '永和區': '234', '中和區': '235', '土城區': '236', '三峽區': '237', '樹林區': '238', 25 | '鶯歌區': '239', '三重區': '241', '新莊區': '242', '泰山區': '243', '林口區': '244', '蘆洲區': '247', 26 | '五股區': '248', '八里區': '249', '淡水區': '251', '三芝區': '252', '石門區': '253' 27 | }, 28 | '宜蘭縣': { 29 | '宜蘭市': '260', '頭城鎮': '261', '礁溪鄉': '262', '壯圍鄉': '263', '員山鄉': '264', '羅東鎮': '265', 30 | '三星鄉': '266', '大同鄉': '267', '五結鄉': '268', '冬山鄉': '269', '蘇澳鎮': '270', '南澳鄉': '272', 31 | '釣魚臺列嶼': '290' 32 | }, 33 | '新竹市': {'東區': '300', '北區': '300', '香山區': '300'}, 34 | '新竹縣': { 35 | '竹北市': '302', '湖口鄉': '303', '新豐鄉': '304', '新埔鎮': '305', '關西鎮': '306', '芎林鄉': '307', 36 | '寶山鄉': '308', '竹東鎮': '310', '五峰鄉': '311', '橫山鄉': '312', '尖石鄉': '313', '北埔鄉': '314', 37 | '峨眉鄉': '315' 38 | }, 39 | '桃園市': { 40 | '中壢區': '320', '平鎮區': '324', '龍潭區': '325', '楊梅區': '326', '新屋區': '327', '觀音區': '328', 41 | '桃園區': '330', '龜山區': '333', '八德區': '334', '大溪區': '335', '復興區': '336', '大園區': '337', 42 | '蘆竹區': '338' 43 | }, 44 | '苗栗縣': { 45 | '竹南鎮': '350', '頭份市': '351', '三灣鄉': '352', '南庄鄉': '353', '獅潭鄉': '354', '後龍鎮': '356', 46 | '通霄鎮': '357', '苑裡鎮': '358', '苗栗市': '360', '造橋鄉': '361', '頭屋鄉': '362', '公館鄉': '363', 47 | '大湖鄉': '364', '泰安鄉': '365', '銅鑼鄉': '366', '三義鄉': '367', '西湖鄉': '368', '卓蘭鎮': '369' 48 | }, 49 | '臺中市': { 50 | '中區': '400', '東區': '401', '南區': '402', '西區': '403', '北區': '404', '北屯區': '406', '西屯區': '407', '南屯區': '408', 51 | '太平區': '411', '大里區': '412', '霧峰區': '413', '烏日區': '414', '豐原區': '420', '后里區': '421', 52 | '石岡區': '422', '東勢區': '423', '和平區': '424', '新社區': '426', '潭子區': '427', '大雅區': '428', 53 | '神岡區': '429', '大肚區': '432', '沙鹿區': '433', '龍井區': '434', '梧棲區': '435', '清水區': '436', 54 | '大甲區': '437', '外埔區': '438', '大安區': '439' 55 | }, 56 | '彰化縣': { 57 | '彰化市': '500', '芬園鄉': '502', '花壇鄉': '503', '秀水鄉': '504', '鹿港鎮': '505', '福興鄉': '506', 58 | '線西鄉': '507', '和美鎮': '508', '伸港鄉': '509', '員林市': '510', '社頭鄉': '511', '永靖鄉': '512', 59 | '埔心鄉': '513', '溪湖鎮': '514', '大村鄉': '515', '埔鹽鄉': '516', '田中鎮': '520', '北斗鎮': '521', 60 | '田尾鄉': '522', '埤頭鄉': '523', '溪州鄉': '524', '竹塘鄉': '525', '二林鎮': '526', '大城鄉': '527', 61 | '芳苑鄉': '528', '二水鄉': '530' 62 | }, 63 | '南投縣': { 64 | '南投市': '540', '中寮鄉': '541', '草屯鎮': '542', '國姓鄉': '544', '埔里鎮': '545', '仁愛鄉': '546', 65 | '名間鄉': '551', '集集鎮': '552', '水里鄉': '553', '魚池鄉': '555', '信義鄉': '556', '竹山鎮': '557', 66 | '鹿谷鄉': '558' 67 | }, 68 | '嘉義市': {'東區': '600', '西區': '600'}, 69 | '嘉義縣': { 70 | '番路鄉': '602', '梅山鄉': '603', '竹崎鄉': '604', '阿里山': '605', '中埔鄉': '606', '大埔鄉': '607', 71 | '水上鄉': '608', '鹿草鄉': '611', '太保市': '612', '朴子市': '613', '東石鄉': '614', '六腳鄉': '615', 72 | '新港鄉': '616', '民雄鄉': '621', '大林鎮': '622', '溪口鄉': '623', '義竹鄉': '624', '布袋鎮': '625' 73 | }, 74 | '雲林縣': { 75 | '斗南鎮': '630', '大埤鄉': '631', '虎尾鎮': '632', '土庫鎮': '633', '褒忠鄉': '634', '東勢鄉': '635', 76 | '臺西鄉': '636', '崙背鄉': '637', '麥寮鄉': '638', '斗六市': '640', '林內鄉': '643', '古坑鄉': '646', 77 | '莿桐鄉': '647', '西螺鎮': '648', '二崙鄉': '649', '北港鎮': '651', '水林鄉': '652', '口湖鄉': '653', 78 | '四湖鄉': '654', '元長鄉': '655' 79 | }, 80 | '臺南市': { 81 | '中西區': '700', '東區': '701', '南區': '702', '北區': '704', '安平區': '708', '安南區': '709', 82 | '永康區': '710', '歸仁區': '711', '新化區': '712', '左鎮區': '713', '玉井區': '714', '楠西區': '715', 83 | '南化區': '716', '仁德區': '717', '關廟區': '718', '龍崎區': '719', '官田區': '720', '麻豆區': '721', 84 | '佳里區': '722', '西港區': '723', '七股區': '724', '將軍區': '725', '學甲區': '726', '北門區': '727', 85 | '新營區': '730', '後壁區': '731', '白河區': '732', '東山區': '733', '六甲區': '734', '下營區': '735', 86 | '柳營區': '736', '鹽水區': '737', '善化區': '741', '大內區': '742', '山上區': '743', '新市區': '744', 87 | '安定區': '745' 88 | }, 89 | '高雄市': { 90 | '新興區': '800', '前金區': '801', '苓雅區': '802', '鹽埕區': '803', '鼓山區': '804', '旗津區': '805', 91 | '前鎮區': '806', '三民區': '807', '楠梓區': '811', '小港區': '812', '左營區': '813', 92 | '仁武區': '814', '大社區': '815', '東沙群島': '817', '南沙群島': '819', '岡山區': '820', '路竹區': '821', 93 | '阿蓮區': '822', '田寮區': '823', 94 | '燕巢區': '824', '橋頭區': '825', '梓官區': '826', '彌陀區': '827', '永安區': '828', '湖內區': '829', 95 | '鳳山區': '830', '大寮區': '831', '林園區': '832', '鳥松區': '833', '大樹區': '840', '旗山區': '842', 96 | '美濃區': '843', '六龜區': '844', '內門區': '845', '杉林區': '846', '甲仙區': '847', '桃源區': '848', 97 | '那瑪夏區': '849', '茂林區': '851', '茄萣區': '852' 98 | }, 99 | '屏東縣': { 100 | '屏東市': '900', '三地門鄉': '901', '霧臺鄉': '902', '瑪家鄉': '903', '九如鄉': '904', '里港鄉': '905', 101 | '高樹鄉': '906', '鹽埔鄉': '907', '長治鄉': '908', '麟洛鄉': '909', '竹田鄉': '911', '內埔鄉': '912', 102 | '萬丹鄉': '913', '潮州鎮': '920', '泰武鄉': '921', '來義鄉': '922', '萬巒鄉': '923', '崁頂鄉': '924', 103 | '新埤鄉': '925', '南州鄉': '926', '林邊鄉': '927', '東港鎮': '928', '琉球鄉': '929', '佳冬鄉': '931', 104 | '新園鄉': '932', '枋寮鄉': '940', '枋山鄉': '941', '春日鄉': '942', '獅子鄉': '943', '車城鄉': '944', 105 | '牡丹鄉': '945', '恆春鎮': '946', '滿州鄉': '947' 106 | }, 107 | '臺東縣': { 108 | '臺東市': '950', '綠島鄉': '951', '蘭嶼鄉': '952', '延平鄉': '953', '卑南鄉': '954', '鹿野鄉': '955', 109 | '關山鎮': '956', '海端鄉': '957', '池上鄉': '958', '東河鄉': '959', '成功鎮': '961', '長濱鄉': '962', 110 | '太麻里鄉': '963', '金峰鄉': '964', '大武鄉': '965', '達仁鄉': '966' 111 | }, 112 | '花蓮縣': { 113 | '花蓮市': '970', '新城鄉': '971', '秀林鄉': '972', '吉安鄉': '973', '壽豐鄉': '974', '鳳林鎮': '975', 114 | '光復鄉': '976', '豐濱鄉': '977', '瑞穗鄉': '978', '萬榮鄉': '979', '玉里鎮': '981', '卓溪鄉': '982', 115 | '富里鄉': '983' 116 | }, 117 | '金門縣': {'金沙鎮': '890', '金湖鎮': '891', '金寧鄉': '892', '金城鎮': '893', '烈嶼鄉': '894', '烏坵鄉': '896'}, 118 | '連江縣': {'南竿鄉': '209', '北竿鄉': '210', '莒光鄉': '211', '東引鄉': '212'}, 119 | '澎湖縣': {'馬公市': '880', '西嶼鄉': '881', '望安鄉': '882', '七美鄉': '883', '白沙鄉': '884', '湖西鄉': '885'} 120 | }; 121 | 122 | /** 123 | * 轉換異體字 [台]為 [臺] 124 | * 125 | * @param {string} value 126 | * @return {string} 127 | */ 128 | function transfer (value) { 129 | return 'string' === typeof value ? value.replace(/[台]+/gi, '臺') : value; 130 | } 131 | 132 | /** 133 | * twzipcode Constructor 134 | * @param {Object} container HTML element 135 | * @param {(Object|string)} options User settings 136 | * @constructor 137 | */ 138 | function TWzipcode (container, options) { 139 | /** 140 | * Default settings 141 | * @type {Object} 142 | */ 143 | var defaults = { 144 | 'countyName' : 'county', 145 | 'css' : [], 146 | 'detect' : false, // v1.6.7 147 | 'districtName' : 'district', 148 | 'googleMapsKey' : '', // v1.6.9 149 | 'hideCounty' : [], // v1.7.9 150 | 'hideDistrict' : [], // v1.7.9 151 | 'onCountySelect' : null, // v1.5 152 | 'onDistrictSelect' : null, // v1.5 153 | 'onZipcodeKeyUp' : null, // v1.5 154 | 'readonly' : false, 155 | 'zipcodeName' : 'zipcode', 156 | 'zipcodePlaceholder' : '郵遞區號', 157 | 'zipcodeIntoDistrict' : false, // v1.6.6 158 | }; 159 | /** 160 | * DOM of selector 161 | * @type {Object} 162 | */ 163 | this.container = $(container); 164 | /** 165 | * Merge the options 166 | * @type {Object} 167 | */ 168 | this.options = $.extend({}, defaults, options); 169 | // initialize 170 | this.init(); 171 | } 172 | /** 173 | * TWzipcode prototype 174 | */ 175 | TWzipcode.prototype = { 176 | 177 | VERSION: '1.7.15', 178 | 179 | /** 180 | * Method: Get all post data 181 | * @return {Object} 182 | */ 183 | data: function () { 184 | var wrap = this.wrap; 185 | return 'undefined' !== typeof data[wrap.county.val()] ? 186 | data[wrap.county.val()] : 187 | data; 188 | }, 189 | /** 190 | * Method: Serialize the data 191 | * @return {string} 192 | */ 193 | serialize: function () { 194 | var result = [], 195 | obj = {}, 196 | ele = {}, 197 | s = {}; 198 | obj = this.container.find('select,input'); 199 | if (obj.length) { 200 | obj.each(function () { 201 | ele = $(this); 202 | result.push(ele.attr('name') + '=' + ele.val()); 203 | }); 204 | } else { 205 | $(this).children().each(function () { 206 | s = $(this); 207 | result.push(s.attr('name') + '=' + s.val()); 208 | }); 209 | } 210 | return result.join('&'); 211 | }, 212 | /** 213 | * Method: Destroy the container. 214 | * @this {TWzipcode} 215 | */ 216 | destroy: function () { 217 | $.data(this.container.get(0), 'twzipcode', null); 218 | if (this.container.length) { 219 | return this.container.empty().off('change.twzipcode keyup.twzipcode blur.twzipcode'); 220 | } 221 | }, 222 | /** 223 | * Method: Get elements of instance 224 | * @param {(string|Array)} opts Type name 225 | * @param {Function} callback Function callback 226 | */ 227 | get: function (callback) { 228 | 229 | var self = this, 230 | result = [], 231 | n; 232 | 233 | function putin (o) { 234 | if ('undefined' !== typeof self.wrap[o]) { 235 | result.push(self.wrap[o].val()); 236 | } 237 | } 238 | 239 | if ('function' === typeof callback) { 240 | callback.call(this, this.wrap.county.val(), this.wrap.district.val(), this.wrap.zipcode.val()); 241 | } else if ('string' === typeof callback) { 242 | callback.split(',').forEach(putin); 243 | } else if (Array.isArray(callback)) { 244 | callback.forEach(putin); 245 | } else { 246 | result = this.wrap; 247 | } 248 | return result; 249 | }, 250 | /** 251 | * Method: Set value for elements. 252 | * @param {(string|number|Object)} opts Input value 253 | */ 254 | set: function (opts) { 255 | 256 | var self = this, 257 | def = { 258 | 'county' : '', 259 | 'district' : '', 260 | 'zipcode' : '' 261 | }, 262 | opt = $.extend({}, def, opts); 263 | 264 | try { 265 | if ('string' === typeof opts || 'number' === typeof opts) { 266 | self.wrap.zipcode.val(opts).trigger('blur.twzipcode'); 267 | } else { 268 | if (opt.zipcode) { 269 | self.wrap.zipcode.val(opt.zipcode).trigger('blur.twzipcode'); 270 | } 271 | if (opt.county) { 272 | self.wrap.county.val(opt.county).trigger('change.twzipcode'); 273 | } 274 | if (opt.district) { 275 | self.wrap.district.val(opt.district).trigger('change.twzipcode'); 276 | } 277 | } 278 | } catch (ignore) { 279 | console.warn(ignore.message); 280 | } finally { 281 | return self.container; 282 | } 283 | }, 284 | /** 285 | * Method: Reset the selected items to default. 286 | * @this {TWzipcode} 287 | */ 288 | reset: function (container, obj) { 289 | var self = this, 290 | wrap = self.wrap, 291 | opts = self.options, 292 | county = '', 293 | list = { 294 | 'county': '', 295 | 'district': '' 296 | }, 297 | tpl = []; 298 | 299 | switch (obj) { 300 | case 'district': 301 | wrap.district.html(list.district); 302 | break; 303 | default: 304 | wrap.county.html(list.county); 305 | wrap.district.html(list.district); 306 | for (county in data) { 307 | if ('undefined' !== typeof data[county] && -1 === opts.hideCounty.indexOf(county)) { 308 | tpl.push(''); 309 | } 310 | } 311 | $(tpl.join('')).appendTo(wrap.county); 312 | break; 313 | } 314 | wrap.zipcode.val(''); 315 | }, 316 | /** 317 | * Binding the event of the elements 318 | * @this {TWzipcode} 319 | */ 320 | bindings: function () { 321 | 322 | var self = this, 323 | opts = self.options, 324 | wrap = self.wrap, 325 | dz = '', 326 | dc = '', 327 | dd = ''; 328 | 329 | // county 330 | wrap.county.on('change.twzipcode', function () { 331 | var val = $(this).val(), 332 | district = '', 333 | tpl = []; 334 | 335 | wrap.district.empty(); 336 | 337 | if (val) { 338 | if (true === opts.zipcodeIntoDistrict) { 339 | for (district in data[val]) { 340 | if ('undefined' !== typeof data[val][district] && 341 | (-1 === opts.hideDistrict.indexOf(district) && -1 === opts.hideDistrict.indexOf(data[val][district])) 342 | ) { 343 | tpl.push(''); 346 | } 347 | } 348 | } else { 349 | for (district in data[val]) { 350 | if ('undefined' !== typeof data[val][district] && 351 | (-1 === opts.hideDistrict.indexOf(district) && -1 === opts.hideDistrict.indexOf(data[val][district])) 352 | ) { 353 | tpl.push(''); 356 | } 357 | } 358 | } 359 | wrap.district.append(tpl.join('')).trigger('change.twzipcode'); 360 | } else { 361 | wrap.county.find('option:first').prop('selected', true); 362 | self.reset('district'); 363 | } 364 | // County callback binding 365 | if ('function' === typeof opts.onCountySelect) { 366 | opts.onCountySelect.call(this); 367 | } 368 | }); 369 | // District 370 | wrap.district.on('change.twzipcode', function () { 371 | var val = $(this).val(), 372 | cv = transfer(wrap.county.val()); 373 | if (cv) { 374 | wrap.zipcode.val(data[cv][val]); 375 | } 376 | // District callback binding 377 | if ('function' === typeof opts.onDistrictSelect) { 378 | opts.onDistrictSelect.call(this); 379 | } 380 | }); 381 | // Zipcode 382 | wrap.zipcode.on('keyup.twzipcode blur.twzipcode', function () { 383 | 384 | var obj = $(this), 385 | val = '', 386 | i = '', 387 | j = ''; 388 | obj.val(obj.val().replace(/[^0-9]/g, '')); 389 | val = obj.val().toString(); 390 | 391 | if (3 === val.length) { 392 | for (i in data) { 393 | if ('undefined' !== typeof data[i]) { 394 | for (j in data[i]) { 395 | if ('undefined' !== typeof data[i][j] && 396 | val === data[i][j] 397 | ) { 398 | wrap.county.val(i).trigger('change.twzipcode'); 399 | wrap.district.val(j).trigger('change.twzipcode'); 400 | break; 401 | } 402 | } 403 | } 404 | } 405 | } 406 | // Zipcode callback binding 407 | if ('function' === typeof opts.onZipcodeKeyUp) { 408 | opts.onZipcodeKeyUp.call(this); 409 | } 410 | }); 411 | 412 | // Put [data-*] into attributes of element 413 | (function () { 414 | var zip = self.role.zipcode.data(), 415 | county = self.role.county.data(), 416 | district = self.role.district.data(), 417 | n; 418 | for (n in zip) { 419 | if ('role' !== n) { 420 | self.role.zipcode.find(':input').attr(n, zip[n]); 421 | } 422 | } 423 | for (n in county) { 424 | if ('role' !== n) { 425 | self.role.county.find('select').attr(n, county[n]); 426 | } 427 | } 428 | for (n in district) { 429 | if ('role' !== n) { 430 | self.role.district.find('select').attr(n, district[n]); 431 | } 432 | } 433 | }()); 434 | 435 | dz = 'undefined' !== typeof opts.zipcodeSel ? 436 | opts.zipcodeSel : 437 | ( 438 | 'undefined' !== typeof self.role.zipcode.data('value') ? 439 | self.role.zipcode.data('value') : 440 | opts.zipcodeSel 441 | ); 442 | 443 | dc = 'undefined' !== typeof opts.countySel ? 444 | opts.countySel : 445 | ( 446 | 'undefined' !== typeof self.role.county.data('value') ? 447 | self.role.county.data('value') : 448 | opts.countySel 449 | ); 450 | 451 | dd = 'undefined' !== typeof opts.districtSel ? 452 | opts.districtSel : 453 | ( 454 | 'undefined' !== typeof self.role.district.data('value') ? 455 | self.role.district.data('value') : 456 | opts.districtSel 457 | ); 458 | 459 | // Default value 460 | if (dc) { 461 | dc = transfer(dc); 462 | self.wrap.county.val(dc).trigger('change.twzipcode'); 463 | if ('undefined' !== typeof data[dc] && 'undefined' !== typeof data[dc][dd]) { 464 | self.wrap.district.val(dd).trigger('change.twzipcode'); 465 | } 466 | } 467 | if (dz && 3 === dz.toString().length) { 468 | self.wrap.zipcode.val(dz).trigger('blur.twzipcode'); 469 | } 470 | }, 471 | /** 472 | * Geolocation detect 473 | * @this {TWzipcode} 474 | */ 475 | geoLocation: function (callback) { 476 | 477 | var self = this, 478 | geolocation = navigator.geolocation, 479 | options = { 480 | 'maximumAge': 600000, 481 | 'timeout': 3000, 482 | 'enableHighAccuracy': false 483 | }, 484 | opts = self.options; 485 | 486 | if (!geolocation || !callback) { 487 | return; 488 | } 489 | 490 | geolocation.getCurrentPosition( 491 | function (loc) { 492 | 493 | var latlng = {}; 494 | if (('coords' in loc) && 495 | ('latitude' in loc.coords) && 496 | ('longitude' in loc.coords) 497 | ) { 498 | latlng = [loc.coords.latitude, loc.coords.longitude]; 499 | $.getJSON( 500 | 'https://maps.googleapis.com/maps/api/geocode/json', 501 | { 502 | 'key': opts.googleMapsKey, 503 | 'sensor': false, 504 | 'latlng': latlng.join(',') 505 | }, 506 | function (data) { 507 | var postal = ''; 508 | if (data && 509 | 'undefined' !== typeof data.results && 510 | 'undefined' !== typeof data.results[0].address_components && 511 | 'undefined' !== typeof data.results[0].address_components[0] 512 | ) { 513 | postal = data.results[0] 514 | .address_components[data.results[0].address_components.length - 1] 515 | .long_name; 516 | if (postal) { 517 | self.wrap.zipcode.val(postal.toString()).trigger('blur.twzipcode'); 518 | } 519 | } 520 | if ('function' === typeof callback) { 521 | callback.call(self, loc); 522 | } 523 | }); 524 | } 525 | }, 526 | function (error) { 527 | console.error(error); 528 | }, 529 | options 530 | ); 531 | }, 532 | /** 533 | * twzipcode Initialize 534 | * @this {TWzipcode} 535 | */ 536 | init: function () { 537 | 538 | var self = this, 539 | container = self.container, 540 | opts = self.options, 541 | role = { 542 | county: container.find('[data-role=county]:first'), 543 | district: container.find('[data-role=district]:first'), 544 | zipcode: container.find('[data-role=zipcode]:first') 545 | }, 546 | countyName = role.county.data('name') || opts.countyName, 547 | districtName = role.district.data('name') || opts.districtName, 548 | zipcodeName = role.zipcode.data('name') || opts.zipcodeName, 549 | zipcodePlaceholder = role.zipcode.data('placeholder') || opts.zipcodePlaceholder, 550 | readonly = role.zipcode.data('readonly') || opts.readonly; 551 | 552 | // Elements create 553 | $('') 559 | .attr('name', districtName) 560 | .addClass(role.district.data('style') || ('undefined' !== typeof opts.css[1] ? opts.css[1] : '')) 561 | .appendTo(role.district.length ? role.district : container); 562 | 563 | $('') 564 | .attr({'type': 'text', 'name': zipcodeName, 'placeholder': zipcodePlaceholder}) 565 | .prop('readonly', readonly) 566 | .addClass(role.zipcode.data('style') || ('undefined' !== typeof opts.css[2] ? opts.css[2] : '')) 567 | .appendTo(role.zipcode.length ? role.zipcode : container); 568 | 569 | self.wrap = { 570 | 'county': container.find('select[name="' + countyName + '"]:first'), 571 | 'district': container.find('select[name="' + districtName + '"]:first'), 572 | 'zipcode': container.find('input[type=text][name="' + zipcodeName + '"]:first') 573 | }; 574 | 575 | if (true === opts.zipcodeIntoDistrict) { 576 | self.wrap.zipcode.hide(); 577 | } 578 | 579 | self.role = role; 580 | // Reset the elements 581 | self.reset(); 582 | // Elements events binding 583 | self.bindings(); 584 | // Geolocation 585 | self.geoLocation(opts.detect); 586 | } 587 | }; 588 | /** 589 | * jQuery twzipcode instance 590 | * @param {Object} options Plugin settings 591 | * @public 592 | */ 593 | $.fn.twzipcode = function (options) { 594 | var instance = {}, 595 | result = [], 596 | args = arguments, 597 | id = 'twzipcode'; 598 | if ('string' === typeof options) { 599 | this.each(function () { 600 | instance = $.data(this, id); 601 | if (instance instanceof TWzipcode && 'function' === typeof instance[options]) { 602 | result = instance[options].apply(instance, Array.prototype.slice.call(args, 1)); 603 | } 604 | }); 605 | return 'undefined' !== typeof result ? result : this; 606 | } else { 607 | return this.each(function () { 608 | if (!$.data(this, id)) { 609 | $.data(this, id, new TWzipcode(this, options)); 610 | } 611 | }); 612 | } 613 | }; 614 | 615 | })(window.jQuery || {}, window, document); 616 | //#EOF 617 | -------------------------------------------------------------------------------- /twzipcode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * TWzipcode 3 | * https://code.essoduke.org/twzipcode/nojquery 4 | * Copyright 2019 essoduke.org, Licensed MIT. 5 | * 6 | * 7 | * @author Essoduke Chang 8 | * @license MIT License 9 | */ 10 | (function (root, factory) { 11 | 12 | 'use strict'; 13 | 14 | if (typeof define === 'function' && define.amd) { 15 | define(factory); 16 | } 17 | else if (typeof module != 'undefined' && typeof module.exports != 'undefined') { 18 | module.exports = factory(); 19 | } 20 | else { 21 | /* jshint sub:true */ 22 | window['TWzipcode'] = factory(); 23 | } 24 | 25 | }(this, function TWzipcodeFactory () { 26 | 27 | 'use strict'; 28 | 29 | // Zipcode JSON data 30 | var database = { 31 | '基隆市': {'仁愛區': '200', '信義區': '201', '中正區': '202', '中山區': '203', '安樂區': '204', '暖暖區': '205', '七堵區': '206'}, 32 | '臺北市': {'中正區': '100', '大同區': '103', '中山區': '104', '松山區': '105', '大安區': '106', '萬華區': '108', '信義區': '110', '士林區': '111', '北投區': '112', '內湖區': '114', '南港區': '115', '文山區': '116'}, 33 | '新北市': { 34 | '萬里區': '207', '金山區': '208', '板橋區': '220', '汐止區': '221', '深坑區': '222', '石碇區': '223', 35 | '瑞芳區': '224', '平溪區': '226', '雙溪區': '227', '貢寮區': '228', '新店區': '231', '坪林區': '232', 36 | '烏來區': '233', '永和區': '234', '中和區': '235', '土城區': '236', '三峽區': '237', '樹林區': '238', 37 | '鶯歌區': '239', '三重區': '241', '新莊區': '242', '泰山區': '243', '林口區': '244', '蘆洲區': '247', 38 | '五股區': '248', '八里區': '249', '淡水區': '251', '三芝區': '252', '石門區': '253' 39 | }, 40 | '宜蘭縣': { 41 | '宜蘭市': '260', '頭城鎮': '261', '礁溪鄉': '262', '壯圍鄉': '263', '員山鄉': '264', '羅東鎮': '265', 42 | '三星鄉': '266', '大同鄉': '267', '五結鄉': '268', '冬山鄉': '269', '蘇澳鎮': '270', '南澳鄉': '272', 43 | '釣魚臺列嶼': '290' 44 | }, 45 | '新竹市': {'東區': '300', '北區': '300', '香山區': '300'}, 46 | '新竹縣': { 47 | '竹北市': '302', '湖口鄉': '303', '新豐鄉': '304', '新埔鎮': '305', '關西鎮': '306', '芎林鄉': '307', 48 | '寶山鄉': '308', '竹東鎮': '310', '五峰鄉': '311', '橫山鄉': '312', '尖石鄉': '313', '北埔鄉': '314', 49 | '峨眉鄉': '315' 50 | }, 51 | '桃園市': { 52 | '中壢區': '320', '平鎮區': '324', '龍潭區': '325', '楊梅區': '326', '新屋區': '327', '觀音區': '328', 53 | '桃園區': '330', '龜山區': '333', '八德區': '334', '大溪區': '335', '復興區': '336', '大園區': '337', 54 | '蘆竹區': '338' 55 | }, 56 | '苗栗縣': { 57 | '竹南鎮': '350', '頭份市': '351', '三灣鄉': '352', '南庄鄉': '353', '獅潭鄉': '354', '後龍鎮': '356', 58 | '通霄鎮': '357', '苑裡鎮': '358', '苗栗市': '360', '造橋鄉': '361', '頭屋鄉': '362', '公館鄉': '363', 59 | '大湖鄉': '364', '泰安鄉': '365', '銅鑼鄉': '366', '三義鄉': '367', '西湖鄉': '368', '卓蘭鎮': '369' 60 | }, 61 | '臺中市': { 62 | '中區': '400', '東區': '401', '南區': '402', '西區': '403', '北區': '404', '北屯區': '406', '西屯區': '407', '南屯區': '408', 63 | '太平區': '411', '大里區': '412', '霧峰區': '413', '烏日區': '414', '豐原區': '420', '后里區': '421', 64 | '石岡區': '422', '東勢區': '423', '和平區': '424', '新社區': '426', '潭子區': '427', '大雅區': '428', 65 | '神岡區': '429', '大肚區': '432', '沙鹿區': '433', '龍井區': '434', '梧棲區': '435', '清水區': '436', 66 | '大甲區': '437', '外埔區': '438', '大安區': '439' 67 | }, 68 | '彰化縣': { 69 | '彰化市': '500', '芬園鄉': '502', '花壇鄉': '503', '秀水鄉': '504', '鹿港鎮': '505', '福興鄉': '506', 70 | '線西鄉': '507', '和美鎮': '508', '伸港鄉': '509', '員林市': '510', '社頭鄉': '511', '永靖鄉': '512', 71 | '埔心鄉': '513', '溪湖鎮': '514', '大村鄉': '515', '埔鹽鄉': '516', '田中鎮': '520', '北斗鎮': '521', 72 | '田尾鄉': '522', '埤頭鄉': '523', '溪州鄉': '524', '竹塘鄉': '525', '二林鎮': '526', '大城鄉': '527', 73 | '芳苑鄉': '528', '二水鄉': '530' 74 | }, 75 | '南投縣': { 76 | '南投市': '540', '中寮鄉': '541', '草屯鎮': '542', '國姓鄉': '544', '埔里鎮': '545', '仁愛鄉': '546', 77 | '名間鄉': '551', '集集鎮': '552', '水里鄉': '553', '魚池鄉': '555', '信義鄉': '556', '竹山鎮': '557', 78 | '鹿谷鄉': '558' 79 | }, 80 | '嘉義市': {'東區': '600', '西區': '600'}, 81 | '嘉義縣': { 82 | '番路鄉': '602', '梅山鄉': '603', '竹崎鄉': '604', '阿里山鄉': '605', '中埔鄉': '606', '大埔鄉': '607', 83 | '水上鄉': '608', '鹿草鄉': '611', '太保市': '612', '朴子市': '613', '東石鄉': '614', '六腳鄉': '615', 84 | '新港鄉': '616', '民雄鄉': '621', '大林鎮': '622', '溪口鄉': '623', '義竹鄉': '624', '布袋鎮': '625' 85 | }, 86 | '雲林縣': { 87 | '斗南鎮': '630', '大埤鄉': '631', '虎尾鎮': '632', '土庫鎮': '633', '褒忠鄉': '634', '東勢鄉': '635', 88 | '臺西鄉': '636', '崙背鄉': '637', '麥寮鄉': '638', '斗六市': '640', '林內鄉': '643', '古坑鄉': '646', 89 | '莿桐鄉': '647', '西螺鎮': '648', '二崙鄉': '649', '北港鎮': '651', '水林鄉': '652', '口湖鄉': '653', 90 | '四湖鄉': '654', '元長鄉': '655' 91 | }, 92 | '臺南市': { 93 | '中西區': '700', '東區': '701', '南區': '702', '北區': '704', '安平區': '708', '安南區': '709', 94 | '永康區': '710', '歸仁區': '711', '新化區': '712', '左鎮區': '713', '玉井區': '714', '楠西區': '715', 95 | '南化區': '716', '仁德區': '717', '關廟區': '718', '龍崎區': '719', '官田區': '720', '麻豆區': '721', 96 | '佳里區': '722', '西港區': '723', '七股區': '724', '將軍區': '725', '學甲區': '726', '北門區': '727', 97 | '新營區': '730', '後壁區': '731', '白河區': '732', '東山區': '733', '六甲區': '734', '下營區': '735', 98 | '柳營區': '736', '鹽水區': '737', '善化區': '741', '大內區': '742', '山上區': '743', '新市區': '744', 99 | '安定區': '745' 100 | }, 101 | '高雄市': { 102 | '新興區': '800', '前金區': '801', '苓雅區': '802', '鹽埕區': '803', '鼓山區': '804', '旗津區': '805', 103 | '前鎮區': '806', '三民區': '807', '楠梓區': '811', '小港區': '812', '左營區': '813', 104 | '仁武區': '814', '大社區': '815', '東沙群島': '817', '南沙群島': '819', '岡山區': '820', '路竹區': '821', 105 | '阿蓮區': '822', '田寮區': '823', 106 | '燕巢區': '824', '橋頭區': '825', '梓官區': '826', '彌陀區': '827', '永安區': '828', '湖內區': '829', 107 | '鳳山區': '830', '大寮區': '831', '林園區': '832', '鳥松區': '833', '大樹區': '840', '旗山區': '842', 108 | '美濃區': '843', '六龜區': '844', '內門區': '845', '杉林區': '846', '甲仙區': '847', '桃源區': '848', 109 | '那瑪夏區': '849', '茂林區': '851', '茄萣區': '852' 110 | }, 111 | '屏東縣': { 112 | '屏東市': '900', '三地門鄉': '901', '霧臺鄉': '902', '瑪家鄉': '903', '九如鄉': '904', '里港鄉': '905', 113 | '高樹鄉': '906', '鹽埔鄉': '907', '長治鄉': '908', '麟洛鄉': '909', '竹田鄉': '911', '內埔鄉': '912', 114 | '萬丹鄉': '913', '潮州鎮': '920', '泰武鄉': '921', '來義鄉': '922', '萬巒鄉': '923', '崁頂鄉': '924', 115 | '新埤鄉': '925', '南州鄉': '926', '林邊鄉': '927', '東港鎮': '928', '琉球鄉': '929', '佳冬鄉': '931', 116 | '新園鄉': '932', '枋寮鄉': '940', '枋山鄉': '941', '春日鄉': '942', '獅子鄉': '943', '車城鄉': '944', 117 | '牡丹鄉': '945', '恆春鎮': '946', '滿州鄉': '947' 118 | }, 119 | '臺東縣': { 120 | '臺東市': '950', '綠島鄉': '951', '蘭嶼鄉': '952', '延平鄉': '953', '卑南鄉': '954', '鹿野鄉': '955', 121 | '關山鎮': '956', '海端鄉': '957', '池上鄉': '958', '東河鄉': '959', '成功鎮': '961', '長濱鄉': '962', 122 | '太麻里鄉': '963', '金峰鄉': '964', '大武鄉': '965', '達仁鄉': '966' 123 | }, 124 | '花蓮縣': { 125 | '花蓮市': '970', '新城鄉': '971', '秀林鄉': '972', '吉安鄉': '973', '壽豐鄉': '974', '鳳林鎮': '975', 126 | '光復鄉': '976', '豐濱鄉': '977', '瑞穗鄉': '978', '萬榮鄉': '979', '玉里鎮': '981', '卓溪鄉': '982', 127 | '富里鄉': '983' 128 | }, 129 | '金門縣': {'金沙鎮': '890', '金湖鎮': '891', '金寧鄉': '892', '金城鎮': '893', '烈嶼鄉': '894', '烏坵鄉': '896'}, 130 | '連江縣': {'南竿鄉': '209', '北竿鄉': '210', '莒光鄉': '211', '東引鄉': '212'}, 131 | '澎湖縣': {'馬公市': '880', '西嶼鄉': '881', '望安鄉': '882', '七美鄉': '883', '白沙鄉': '884', '湖西鄉': '885'} 132 | }; 133 | 134 | /** 135 | * Get or Set data-attribute 136 | */ 137 | var data = (function () { 138 | 139 | var db = {}; 140 | 141 | return { 142 | /** 143 | * Get attribute 144 | * 145 | * @param {Object} elem Element object 146 | * @param {string} key Key name 147 | */ 148 | 'get': function (elem, key) { 149 | 150 | if (!elem) { 151 | return false; 152 | } 153 | 154 | [].forEach.call(elem.attributes, function (attr) { 155 | if (/^data-/.test(attr.name)) { 156 | var camelCaseName = attr.name.substr(5).replace(/-(.)/g, function ($0, $1) { 157 | return $1.toUpperCase(); 158 | }); 159 | db[camelCaseName] = attr.value; 160 | } 161 | }); 162 | if ('string' === typeof key && (key in db)) { 163 | return JSON.parse(['"', htmldecode(db[key]), '"'].join('')); 164 | } else if ('undefined' === typeof key) { 165 | return db; 166 | } 167 | }, 168 | /** 169 | * Set data-attribute 170 | * 171 | * @param {Object} elem Element object 172 | * @param {string} key Key name 173 | * @param {string} val Key value 174 | */ 175 | 'set': function (elem, key, val) { 176 | 177 | if (!elem) { 178 | return false; 179 | } 180 | 181 | if ('string' === typeof key) { 182 | db[key] = val; 183 | } 184 | 185 | Object.keys(db).forEach(function (k) { 186 | var attrName = 'data-' + k.replace(/[A-Z]/g, function ($0) { 187 | return '-' + $0.toLowerCase(); 188 | }), 189 | attrValue = htmlencode(JSON.stringify(db[k]).slice(1, -1)); 190 | elem.setAttribute(attrName, attrValue); 191 | }); 192 | } 193 | }; 194 | }()); 195 | 196 | function htmlencode (s) { 197 | var div = document.createElement('div'); 198 | div.appendChild(document.createTextNode(s)); 199 | return div.innerHTML; 200 | } 201 | function htmldecode (s) { 202 | var div = document.createElement('div'); 203 | div.innerHTML = s; 204 | return div.innerText || div.textContent; 205 | } 206 | 207 | /** 208 | * 轉換異體字 [台]為 [臺] 209 | * 210 | * @param {string} value 211 | * @return {string} 212 | */ 213 | function transfer (value) { 214 | return 'string' === typeof value ? value.replace(/[台]+/gi, '臺') : value; 215 | } 216 | 217 | // unbind event 218 | function on (el, event, fn) { 219 | el.addEventListener(event, fn, false); 220 | } 221 | 222 | // bind event 223 | function off (el, event, fn) { 224 | el.removeEventListener(event, fn, false); 225 | } 226 | 227 | // getJSON 228 | function getJSON (url, params, success, error) { 229 | 230 | var request = new XMLHttpRequest(); 231 | 232 | function serialize (obj) { 233 | var str = [], p; 234 | for (p in obj) { 235 | if (obj.hasOwnProperty(p)) { 236 | str.push([encodeURIComponent(p), encodeURIComponent(obj[p])].join('=')); 237 | } 238 | } 239 | return str.join('&'); 240 | } 241 | 242 | request.open('GET', [url, serialize(params)].join('?') , true); 243 | 244 | request.onload = function () { 245 | if (request.status >= 200 && request.status < 400) { 246 | // Success! 247 | var data = JSON.parse(request.responseText); 248 | if ('function' === typeof success) { 249 | success.call(this, data); 250 | } 251 | } else { 252 | // We reached our target server, but it returned an error 253 | } 254 | }; 255 | request.onerror = 'function' === typeof error ? error : function () {}; 256 | request.send(); 257 | } 258 | 259 | /** 260 | * 261 | */ 262 | function deepExtend () { 263 | 264 | // Variables 265 | var extended = {}, 266 | deep = false, 267 | i = 0, 268 | length = arguments.length; 269 | 270 | // Check if a deep merge 271 | if ( Object.prototype.toString.call( arguments[0] ) === '[object Boolean]' ) { 272 | deep = arguments[0]; 273 | i += 1; 274 | } 275 | 276 | // Merge the object into the extended object 277 | var merge = function (obj) { 278 | for ( var prop in obj ) { 279 | if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) { 280 | // If deep merge and property is an object, merge properties 281 | extended[prop] = deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ? 282 | deepExtend( true, extended[prop], obj[prop] ) : 283 | obj[prop]; 284 | } 285 | } 286 | }; 287 | 288 | // Loop through each object and conduct a merge 289 | for (; i < length; i++ ) { 290 | var obj = arguments[i]; 291 | merge(obj); 292 | } 293 | 294 | return extended; 295 | }; 296 | 297 | /** 298 | * 299 | */ 300 | function trigger (el, eventName) { 301 | 302 | var event; 303 | 304 | // Namespace 305 | if (-1 !== eventName.indexOf('.')) { 306 | if (window.CustomEvent) { 307 | event = new CustomEvent(eventName); 308 | } else { 309 | event = document.createEvent('CustomEvent'); 310 | event.initCustomEvent(eventName, true, true); 311 | } 312 | } else { 313 | if (document.createEvent) { 314 | event = document.createEvent('HTMLEvents'); 315 | event.initEvent(eventName, true, true); 316 | } else { 317 | event = document.createEventObject(); 318 | event.eventType = eventName; 319 | } 320 | } 321 | 322 | event.eventName = eventName; 323 | 324 | if (document.createEvent) { 325 | el.dispatchEvent(event); 326 | } else { 327 | el.fireEvent('on' + event.eventType, event); 328 | } 329 | } 330 | 331 | /** 332 | * 333 | */ 334 | function isElement (obj) { 335 | try { 336 | //Using W3 DOM2 (works for FF, Opera and Chrome) 337 | return obj instanceof HTMLElement; 338 | } catch (ignore) { 339 | //Browsers not supporting W3 DOM2 don't have HTMLElement and 340 | //an exception is thrown and we end up here. Testing some 341 | //properties that all elements have. (works on IE7) 342 | return (typeof obj === 'object') && 343 | (obj.nodeType===1) && (typeof obj.style === 'object') && 344 | (typeof obj.ownerDocument === 'object'); 345 | } 346 | } 347 | 348 | /** 349 | * 350 | */ 351 | function TWzipcode (container, options) { 352 | 353 | /** 354 | * Default options of Plugin 355 | * @type {Object} 356 | */ 357 | var twzipcodeOpts = { 358 | 'county': { 359 | 'label' : '縣市', 360 | 'name' : 'county', //表單名稱 361 | 'value' : '', //預設值 362 | 'css' : '', //樣式名稱 363 | 'hidden' : false, //要隱藏的縣市 364 | 'required' : true, 365 | 'onSelect' : null 366 | }, 367 | 'district': { 368 | 'label' : '鄉鎮市區', 369 | 'name' : 'district', //表單名稱 370 | 'value' : '', //預設值 371 | 'css' : '', //樣式名稱 372 | 'hidden' : false, //要隱藏的鄉鎮市區 373 | 'required' : true, 374 | 'onSelect' : null 375 | }, 376 | 'zipcode': { 377 | 'name' : 'zipcode', //表單名稱 378 | 'value' : '', //預設值 379 | 'css' : '', //樣式名稱 380 | 'hidden' : false, //要隱藏的鄉鎮市區 381 | 'type' : 'text', 382 | 'min' : 0, 383 | 'max' : 0, 384 | 'step' : 1, 385 | 'placeholder': '', 386 | 'maxlength' : 3, 387 | 'pattern' : '\\d+', 388 | 'readonly' : false, 389 | 'required' : true, 390 | 'onKeyUp' : null, 391 | 'onFocus' : null, 392 | 'onBlur' : null 393 | }, 394 | 'GMAP_KEY' : '', // 395 | 'detect' : false, 396 | 'combine' : false, 397 | 'island' : true, 398 | 'database' : {} 399 | }; 400 | 401 | /** 402 | * 離島縣市、鄉鎮市區 403 | * @type {Array} 404 | */ 405 | this.islands = [ 406 | '釣魚臺列嶼', '東沙群島', '南沙群島', '綠島鄉', '蘭嶼鄉', 407 | '金門縣', '連江縣', '澎湖縣' 408 | ]; 409 | 410 | /** 411 | * Plugin Namespace 412 | * @type {string} 413 | */ 414 | this.namespace = 'twzipcode'; 415 | 416 | /** 417 | * DOM of selector 418 | * @type {Object} 419 | */ 420 | //this.container = $(container); 421 | this.container = 'string' === typeof container ? 422 | document.querySelectorAll(container) : 423 | isElement(container) ? container : false; 424 | 425 | 426 | if (false === this.container) { 427 | throw 'Initialize failed'; 428 | return false; 429 | } 430 | 431 | /** 432 | * Merge the options 433 | * @type {Object} 434 | */ 435 | //this.options = $.extend(true, {}, twzipcodeOpts, options); 436 | this.options = deepExtend(true, twzipcodeOpts, options); 437 | 438 | // 外部 data JSON 439 | if (this.options.database && Object.keys(this.options.database).length !== 0) { 440 | database = this.options.database; 441 | delete this.options.database; 442 | } 443 | 444 | /** 445 | * Zipcode data JSON 446 | * @type {Object} 447 | */ 448 | this.database = database; 449 | 450 | // Initialize 451 | this.init(); 452 | } 453 | 454 | // 取得指定的選項 455 | TWzipcode.prototype.getOpt = function () { 456 | 457 | var opt = this.options, 458 | args = Array.prototype.slice.call(arguments, 0), 459 | i = 0, 460 | v, 461 | obj; 462 | 463 | args.forEach(function (arg, i) { 464 | if (obj && obj.hasOwnProperty(arg)) { 465 | v = obj[arg]; 466 | } else if (opt.hasOwnProperty(arg)) { 467 | obj = opt[arg]; 468 | v = obj; 469 | } else { 470 | v = obj; 471 | return; 472 | } 473 | }); 474 | return v; 475 | }; 476 | 477 | // 建立 select dropdown list 478 | TWzipcode.prototype.createDropdownList = function (el, id, role, opt) { 479 | 480 | var self = this, 481 | opts = deepExtend(true, opt, data.get(el)), 482 | dom = document.createElement('select'), 483 | label = opts.hasOwnProperty('label') ? opts.label : opt.label, 484 | defItem = [''], 485 | html = [], 486 | hide = [], 487 | event = 'change', 488 | nv = transfer(opts.value), 489 | selected, 490 | o, 491 | c; 492 | 493 | if (false === self.getOpt('island')) { 494 | hide = hide.concat(self.islands); 495 | } 496 | 497 | if (opts.hidden) { 498 | if (Array.isArray(opts.hidden)) { 499 | hide.concat(opts.hidden); 500 | } else if ('string' === typeof opts.hidden) { 501 | hide.concat(opts.hidden.toString().split(',')); 502 | } 503 | hide = hide.map(function (item) { 504 | return transfer(item.trim()); 505 | }); 506 | } 507 | 508 | html.push(defItem.join('')); 509 | 510 | // if (opts.hasOwnProperty('value') && opts.value) { 511 | // nv = opts.value; 512 | // } 513 | 514 | if ('county' === role) { 515 | for (c in self.database) { 516 | if ('undefined' !== typeof self.database[c]) { 517 | if (-1 === hide.indexOf(c)) { 518 | selected = nv === c ? ' selected="selected"' : ''; 519 | html.push([''].join('')); 520 | } 521 | } 522 | } 523 | } 524 | 525 | dom.setAttribute('name', opts.name); 526 | dom.setAttribute('id', [role, '-', id].join('')); 527 | dom.className += [opts.css].join(''); 528 | dom.innerHTML = html.join(''); 529 | 530 | data.set(dom, 'default', defItem.join('')); 531 | 532 | dom.removeAttribute('data-role'); 533 | 534 | if (opts.required) { 535 | dom.setAttribute('required', true); 536 | } 537 | 538 | // County onchange 539 | function onCountyChange (evt) { 540 | 541 | var district = self.getEl(id, 'district'), 542 | zipcode = self.getEl(id, 'zipcode'), 543 | //value = transfer(this.value), 544 | value = transfer(this.options[this.selectedIndex].value), 545 | sv = data.get(district, 'value'), 546 | hide = [], 547 | sub = [], 548 | combine = '', 549 | selected, 550 | cn; 551 | 552 | district.innerHTML = data.get(district, 'default'); 553 | 554 | if (zipcode && opts.hasOwnProperty('onSelect') && 'function' === typeof opts.onSelect) { 555 | opts.onSelect.call(this, evt); 556 | } 557 | 558 | if (false === self.getOpt('island')) { 559 | hide = hide.concat(self.islands); 560 | } 561 | 562 | if (opts.hasOwnProperty('hidden')) { 563 | if ('string' === typeof opts.hidden) { 564 | hide.concat(opts.hidden.split(',')); 565 | } else if (Array.isArray(opts.hidden)) { 566 | hide.concat(opts.hidden); 567 | } 568 | 569 | hide = hide.map(function (item) { 570 | return transfer(item.trim()); 571 | }); 572 | } 573 | 574 | if (district.length) { 575 | if (self.database.hasOwnProperty(value)) { 576 | for (cn in self.database[value]) { 577 | if (Array.isArray(hide) && (!hide.length) || (hide.length && -1 === hide.indexOf(cn))) { 578 | selected = cn === nv || cn === sv ? ' selected="selected"' : ''; 579 | combine = self.getOpt('combine') ? (self.database[value][cn] + ' ') : ''; 580 | sub.push([ 581 | '' 582 | ].join('')); 583 | } 584 | } 585 | district.innerHTML = sub.join(''); 586 | trigger(district, event); 587 | } else { 588 | if ('value' in zipcode) { 589 | zipcode.value = ''; 590 | } 591 | } 592 | } 593 | } 594 | 595 | // District onchange 596 | function onDistrictChange (evt) { 597 | 598 | var elCounty = self.getEl(id, 'county'), 599 | elDistrict = self.getEl(id, 'district'), 600 | elZipcode = self.getEl(id, 'zipcode'); 601 | 602 | if (elCounty && elDistrict && elZipcode) { 603 | if (self.database.hasOwnProperty(elCounty.value) && 604 | self.database[elCounty.value].hasOwnProperty(elDistrict.value) 605 | ) { 606 | elZipcode.value = self.database[elCounty.value][elDistrict.value]; 607 | if (opts.hasOwnProperty('onSelect') && 'function' === typeof opts.onSelect) { 608 | opts.onSelect.call(this, evt, this.value); 609 | } 610 | } 611 | } 612 | } 613 | 614 | switch (role) { 615 | case 'county': 616 | on(dom, event, onCountyChange); 617 | el.appendChild(dom); 618 | break; 619 | case 'district': 620 | on(dom, event, onDistrictChange); 621 | el.appendChild(dom); 622 | break; 623 | } 624 | 625 | if ('string' === typeof nv && nv) { 626 | 627 | 628 | setTimeout(function () { 629 | o = dom.querySelector('[value="' + nv + '"]'); 630 | if (o) { 631 | o.setAttribute('selected', true); 632 | trigger(dom, event); 633 | } 634 | }, 0); 635 | } 636 | 637 | return dom; 638 | }; 639 | 640 | // 建立 input element 641 | TWzipcode.prototype.createInput = function (el, id, role, opt) { 642 | 643 | var self = this, 644 | opts = deepExtend(true, opt, data.get(el)), 645 | dom = document.createElement('input'), 646 | c; 647 | 648 | dom.setAttribute('type', opts.type); 649 | dom.setAttribute('name', opts.name); 650 | dom.setAttribute('id', [role, '-', id].join('')); 651 | dom.setAttribute('placeholder', opts.placeholder); 652 | dom.setAttribute('pattern', opts.pattern); 653 | dom.className += [opts.css].join(' '); 654 | dom.value = opts.value; 655 | 656 | switch (opts.type) { 657 | case 'number': 658 | dom.setAttribute('min', parseInt(opts.min, 10)); 659 | dom.setAttribute('max', parseInt(opts.max, 10)); 660 | dom.setAttribute('step', parseInt(opts.step, 10)); 661 | break; 662 | default: 663 | dom.setAttribute('maxLength', parseInt(opts.maxlength, 10)); 664 | } 665 | 666 | dom.removeAttribute('data-role'); 667 | 668 | if (opts.required) { 669 | //dom.attr('required', true); 670 | dom.setAttribute('required', true); 671 | } 672 | 673 | if (opts.readonly) { 674 | //dom.attr('readonly', true); 675 | dom.setAttribute('readonly', true); 676 | } 677 | 678 | // 佚代尋找郵遞區號 679 | function findCode (zipcode) { 680 | var n, o, p; 681 | for (n in self.database) { 682 | if (self.database[n]) { 683 | for (o in self.database[n]) { 684 | if (zipcode === self.database[n][o]) { 685 | return { 686 | 'county' : n, 687 | 'district' : o 688 | }; 689 | } 690 | } 691 | } 692 | } 693 | } 694 | 695 | // Events binding 696 | on(dom, 'keyup', function (evt) { 697 | 698 | var elCounty = self.getEl(id, 'county'), 699 | elDistrict = self.getEl(id, 'district'), 700 | county = elCounty ? elCounty.value : {}, 701 | district = elDistrict ? elDistrict.value : {}, 702 | code = findCode(this.value), 703 | c, 704 | d; 705 | 706 | if (code && code.hasOwnProperty('county') && code.hasOwnProperty('district')) { 707 | elCounty.value = code.county 708 | trigger(elCounty, 'change'); 709 | elDistrict.value = code.district; 710 | trigger(elDistrict, 'change'); 711 | c = code.county; 712 | d = code.district; 713 | } 714 | 715 | if ('function' === typeof opts.onKeyup) { 716 | opts.onKeyup.call(this, evt, c, d); 717 | } 718 | }); 719 | 720 | if ('function' === typeof opts.onBlur) { 721 | on(dom, 'blur', opts.onBlur); 722 | } 723 | 724 | if ('function' === typeof opts.onFocus) { 725 | on(dom, 'focus', opts.onFocus); 726 | } 727 | 728 | if (opts.value) { 729 | trigger(dom, 'keyup'); 730 | } 731 | return el.appendChild(dom); 732 | }; 733 | 734 | /** 735 | * 偵測郵遞區號 736 | * Powered by Google Maps API 737 | */ 738 | TWzipcode.prototype.geolocation = function () { 739 | 740 | var self = this, 741 | container = self.container, 742 | geolocation = navigator.geolocation, 743 | options = { 744 | 'maximumAge' : 600000, 745 | 'timeout' : 3000, 746 | 'enableHighAccuracy' : false 747 | }, 748 | opts = self.options, 749 | callback = opts.detect; 750 | 751 | if (!geolocation || !callback) { 752 | return; 753 | } 754 | 755 | // onSuccess 756 | function success (loc) { 757 | 758 | var latLng = [], 759 | params = { 760 | 'key' : self.getOpt('GMAP_KEY'), 761 | 'sensor' : false, 762 | }; 763 | 764 | if (('coords' in loc) && ('latitude' in loc.coords) && ('longitude' in loc.coords)) { 765 | 766 | params.latlng = [loc.coords.latitude, loc.coords.longitude].join(','); 767 | 768 | getJSON('https://maps.googleapis.com/maps/api/geocode/json', params, function (resp) { 769 | 770 | var postal = ''; 771 | 772 | if (resp && 773 | 'undefined' !== typeof resp.results && 774 | 'undefined' !== typeof resp.results[0].address_components && 775 | 'undefined' !== typeof resp.results[0].address_components[0] 776 | ) { 777 | postal = resp.results[0] 778 | .address_components[resp.results[0].address_components.length - 1] 779 | .long_name; 780 | 781 | if (postal) { 782 | Array.prototype.forEach.call(container, function (el) { 783 | var zipcode = el.querySelector('input'); 784 | if (zipcode) { 785 | zipcode.value = postal.toString(); 786 | trigger(zipcode, 'keyup'); 787 | } 788 | }); 789 | } 790 | } 791 | if ('function' === typeof callback) { 792 | callback.call(self, loc); 793 | } 794 | }); 795 | } 796 | } 797 | 798 | // onError 799 | function error (error) { 800 | console.error(error); 801 | } 802 | // Binding 803 | geolocation.watchPosition(success, error, options); 804 | }; 805 | 806 | /** 807 | * Get element by id 808 | * 809 | * @param {string} id Element Id 810 | * @param {string} type Element type 811 | * @return {Object} 812 | */ 813 | TWzipcode.prototype.getEl = function (id, type) { 814 | return document.querySelector(['#', type, '-', id].join('')); 815 | }; 816 | 817 | /** 818 | * 建立所需的 DOM 819 | */ 820 | TWzipcode.prototype.createElements = function () { 821 | 822 | var self = this, 823 | container = self.container, 824 | opts = self.options, 825 | optCounty = self.getOpt('county'), 826 | optDistrict = self.getOpt('district'), 827 | optZipcode = self.getOpt('zipcode'), 828 | dom; 829 | 830 | Array.prototype.forEach.call(container, function (el) { 831 | 832 | var id = Math.random().toString(36).substr(2, 10); 833 | 834 | Array.prototype.forEach.call(el.querySelectorAll('[data-role]'), function (child) { 835 | 836 | var role = child.getAttribute('data-role').toLowerCase(); 837 | 838 | switch (role) { 839 | case 'county': 840 | dom = self.createDropdownList(child, id, role, optCounty); 841 | break; 842 | case 'district': 843 | dom = self.createDropdownList(child, id, role, optDistrict); 844 | break; 845 | case 'zipcode': 846 | dom = self.createInput(child, id, role, optZipcode); 847 | // 如果 combine = true 則隱藏 input 848 | if (opts.combine) { 849 | dom.removeAttribute('required'); 850 | dom.style.display = 'none'; 851 | } 852 | break; 853 | } 854 | }); 855 | 856 | // Elements created callback @v2.0.5 857 | if (opts.hasOwnProperty('created') && 'function' === typeof opts.created) { 858 | opts.created.call(self); 859 | } 860 | }); 861 | }; 862 | 863 | /** 864 | * 設值 865 | */ 866 | TWzipcode.prototype.set = function (input) { 867 | 868 | var self = this, 869 | result = []; 870 | 871 | Array.prototype.forEach.call(self.container, function (el) { 872 | 873 | var county = el.querySelector('[id^="county-"]'), 874 | district = el.querySelector('[id^="district-"]'), 875 | zipcode = el.querySelector('[id^="zipcode-"]'); 876 | 877 | if (input.substring || input.toFixed) { 878 | zipcode.value = input; 879 | trigger(zipcode, 'keyup'); 880 | } else { 881 | 882 | if ('object' === typeof input) { 883 | if (input.hasOwnProperty('county')) { 884 | county.value = transfer(input.county); 885 | trigger(county, 'change'); 886 | } 887 | if (input.hasOwnProperty('district')) { 888 | setTimeout(function () { 889 | district.value = transfer(input.district); 890 | trigger(district, 'change'); 891 | }, 5); 892 | } 893 | if (input.hasOwnProperty('zipcode')) { 894 | setTimeout(function () { 895 | zipcode.value = parseInt(input.zipcode); 896 | trigger(zipcode, 'keyup'); 897 | }, 10); 898 | } 899 | } 900 | } 901 | }); 902 | return result; 903 | }; 904 | 905 | /** 906 | * 取值 907 | */ 908 | TWzipcode.prototype.get = function (callback) { 909 | 910 | var self = this, 911 | pp = [], 912 | result = []; 913 | 914 | Array.prototype.forEach.call(self.container, function (el) { 915 | var county = el.querySelector('[id^="county-"]'), 916 | district = el.querySelector('[id^="district-"]'), 917 | zipcode = el.querySelector('[id^="zipcode-"]'); 918 | result.push({ 919 | 'id' : county.getAttribute('id').replace(/county\-/g, ''), 920 | 'county' : county.value, 921 | 'district': district.value, 922 | 'zipcode' : zipcode.value, 923 | }); 924 | }); 925 | if ('function' === typeof callback) { 926 | callback.call(self, result); 927 | } else if ('string' === typeof callback) { 928 | switch (callback.toLowerCase()) { 929 | case 'county': 930 | case 'district': 931 | case 'zipcode': 932 | result.forEach(function (item) { 933 | pp.push(item[callback]); 934 | }); 935 | return pp; 936 | } 937 | } 938 | return result; 939 | }; 940 | 941 | /** 942 | * 輸出序列化字串 943 | */ 944 | TWzipcode.prototype.serialize = function () { 945 | var result = []; 946 | Array.prototype.forEach.call(this.container, function (el) { 947 | var county = el.querySelector('[id^="county-"]'), 948 | district = el.querySelector('[id^="district-"]'), 949 | zipcode = el.querySelector('[id^="zipcode-"]'); 950 | result.push(elCounty.getAttribute('name') + '=' + elCounty.value); 951 | result.push(elDistrict.getAttribute('name') + '=' + elDistrict.value); 952 | result.push(elZipcode.getAttribute('name') + '=' + elZipcode.value); 953 | }); 954 | return resulresult; 955 | }; 956 | 957 | /** 958 | * 移除 Plugin 959 | */ 960 | TWzipcode.prototype.destroy = function () { 961 | try { 962 | Array.prototype.forEach.call(this.container, function (el) { 963 | var county = el.querySelector('[id^="county-"]'), 964 | district = el.querySelector('[id^="district-"]'), 965 | zipcode = el.querySelector('[id^="zipcode-"]'); 966 | county.parentNode.removeChild(county); 967 | district.parentNode.removeChild(district); 968 | zipcode.parentNode.removeChild(zipcode); 969 | el.removeAttribute('id'); 970 | el.removeAttribute('data-twzipcode'); 971 | 972 | }); 973 | } catch (ignore) { 974 | console.warn(ignore); 975 | } 976 | }; 977 | 978 | /** 979 | * 初始化 980 | */ 981 | TWzipcode.prototype.init = function () { 982 | this.createElements(); 983 | this.geolocation(); 984 | }; 985 | 986 | // Create instance 987 | TWzipcode.create = function (el, options) { 988 | return new TWzipcode(el, options); 989 | }; 990 | 991 | /** 992 | * Version 993 | * @constructor 994 | */ 995 | TWzipcode.VERSION = '2.0.5'; 996 | return TWzipcode; 997 | 998 | })); 999 | //#EOF 1000 | --------------------------------------------------------------------------------