distpicker.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*!
  2. * Distpicker v1.0.4
  3. * https://github.com/fengyuanchen/distpicker
  4. *
  5. * Copyright (c) 2014-2016 Fengyuan Chen
  6. * Released under the MIT license
  7. *
  8. * Date: 2016-06-01T15:05:52.606Z
  9. */
  10. (function (factory) {
  11. if (typeof define === 'function' && define.amd) {
  12. // AMD. Register as anonymous module.
  13. define(['jquery', 'ChineseDistricts'], factory);
  14. } else if (typeof exports === 'object') {
  15. // Node / CommonJS
  16. factory(require('jquery'), require('ChineseDistricts'));
  17. } else {
  18. // Browser globals.
  19. factory(jQuery, ChineseDistricts);
  20. }
  21. })(function ($, ChineseDistricts) {
  22. 'use strict';
  23. if (typeof ChineseDistricts === 'undefined') {
  24. throw new Error('The file "distpicker.data.js" must be included first!');
  25. }
  26. var NAMESPACE = 'distpicker';
  27. var EVENT_CHANGE = 'change.' + NAMESPACE;
  28. var PROVINCE = 'province';
  29. var CIRY = 'city';
  30. var DISTRICT = 'district';
  31. function Distpicker(element, options) {
  32. this.$element = $(element);
  33. this.options = $.extend({}, Distpicker.DEFAULTS, $.isPlainObject(options) && options);
  34. this.placeholders = $.extend({}, Distpicker.DEFAULTS);
  35. this.active = false;
  36. this.init();
  37. }
  38. Distpicker.prototype = {
  39. constructor: Distpicker,
  40. init: function () {
  41. var options = this.options;
  42. var $select = this.$element.find('select');
  43. var length = $select.length;
  44. var data = {};
  45. $select.each(function () {
  46. $.extend(data, $(this).data());
  47. });
  48. $.each([PROVINCE, CIRY, DISTRICT], $.proxy(function (i, type) {
  49. if (data[type]) {
  50. options[type] = data[type];
  51. this['$' + type] = $select.filter('[data-' + type + ']');
  52. } else {
  53. this['$' + type] = length > i ? $select.eq(i) : null;
  54. }
  55. }, this));
  56. this.bind();
  57. // Reset all the selects (after event binding)
  58. this.reset();
  59. this.active = true;
  60. },
  61. bind: function () {
  62. if (this.$province) {
  63. this.$province.on(EVENT_CHANGE, (this._changeProvince = $.proxy(function () {
  64. this.output(CIRY);
  65. this.output(DISTRICT);
  66. }, this)));
  67. }
  68. if (this.$city) {
  69. this.$city.on(EVENT_CHANGE, (this._changeCity = $.proxy(function () {
  70. this.output(DISTRICT);
  71. }, this)));
  72. }
  73. },
  74. unbind: function () {
  75. if (this.$province) {
  76. this.$province.off(EVENT_CHANGE, this._changeProvince);
  77. }
  78. if (this.$city) {
  79. this.$city.off(EVENT_CHANGE, this._changeCity);
  80. }
  81. },
  82. output: function (type) {
  83. var options = this.options;
  84. var placeholders = this.placeholders;
  85. var $select = this['$' + type];
  86. var districts = {};
  87. var data = [];
  88. var code;
  89. var matched;
  90. var value;
  91. if (!$select || !$select.length) {
  92. return;
  93. }
  94. value = options[type];
  95. code = (
  96. type === PROVINCE ? 86 :
  97. type === CIRY ? this.$province && this.$province.find(':selected').data('code') :
  98. type === DISTRICT ? this.$city && this.$city.find(':selected').data('code') : code
  99. );
  100. districts = $.isNumeric(code) ? ChineseDistricts[code] : null;
  101. if ($.isPlainObject(districts)) {
  102. $.each(districts, function (code, address) {
  103. var selected = address === value;
  104. if (selected) {
  105. matched = true;
  106. }
  107. data.push({
  108. code: code,
  109. address: address,
  110. selected: selected
  111. });
  112. });
  113. }
  114. if (!matched) {
  115. if (data.length && (options.autoSelect || options.autoselect)) {
  116. data[0].selected = true;
  117. }
  118. // Save the unmatched value as a placeholder at the first output
  119. if (!this.active && value) {
  120. placeholders[type] = value;
  121. }
  122. }
  123. // Add placeholder option
  124. if (options.placeholder) {
  125. data.unshift({
  126. code: '',
  127. address: placeholders[type],
  128. selected: false
  129. });
  130. }
  131. $select.html(this.getList(data));
  132. },
  133. getList: function (data) {
  134. var list = [];
  135. $.each(data, function (i, n) {
  136. list.push(
  137. '<option' +
  138. ' value="' + (n.address && n.code ? n.address : '') + '"' +
  139. ' data-code="' + (n.code || '') + '"' +
  140. (n.selected ? ' selected' : '') +
  141. '>' +
  142. (n.address || '') +
  143. '</option>'
  144. );
  145. });
  146. return list.join('');
  147. },
  148. reset: function (deep) {
  149. if (!deep) {
  150. this.output(PROVINCE);
  151. this.output(CIRY);
  152. this.output(DISTRICT);
  153. } else if (this.$province) {
  154. this.$province.find(':first').prop('selected', true).trigger(EVENT_CHANGE);
  155. }
  156. },
  157. destroy: function () {
  158. this.unbind();
  159. this.$element.removeData(NAMESPACE);
  160. }
  161. };
  162. Distpicker.DEFAULTS = {
  163. autoSelect: true,
  164. placeholder: true,
  165. province: '—— 省 ——',
  166. city: '—— 市 ——',
  167. district: '—— 区 ——'
  168. };
  169. Distpicker.setDefaults = function (options) {
  170. $.extend(Distpicker.DEFAULTS, options);
  171. };
  172. // Save the other distpicker
  173. Distpicker.other = $.fn.distpicker;
  174. // Register as jQuery plugin
  175. $.fn.distpicker = function (option) {
  176. var args = [].slice.call(arguments, 1);
  177. return this.each(function () {
  178. var $this = $(this);
  179. var data = $this.data(NAMESPACE);
  180. var options;
  181. var fn;
  182. if (!data) {
  183. if (/destroy/.test(option)) {
  184. return;
  185. }
  186. options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
  187. $this.data(NAMESPACE, (data = new Distpicker(this, options)));
  188. }
  189. if (typeof option === 'string' && $.isFunction(fn = data[option])) {
  190. fn.apply(data, args);
  191. }
  192. });
  193. };
  194. $.fn.distpicker.Constructor = Distpicker;
  195. $.fn.distpicker.setDefaults = Distpicker.setDefaults;
  196. // No conflict
  197. $.fn.distpicker.noConflict = function () {
  198. $.fn.distpicker = Distpicker.other;
  199. return this;
  200. };
  201. $(function () {
  202. $('[data-toggle="distpicker"]').distpicker();
  203. });
  204. });