123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585 |
- layui.define(['jquery'], function (exports) {
- var $ = layui.$;
- 'use strict';
- if (typeof ChineseDistricts === 'undefined') {
- throw new Error('The file "city-picker.data.js" must be included first!');
- }
- var NAMESPACE = 'citypicker';
- var EVENT_CHANGE = 'change.' + NAMESPACE;
- // 城市选择类
- var CityPicker = function (element, options) {
- this.PROVINCE = 'provinceId';
- this.CITY = 'cityId';
- this.DISTRICT = 'districtId';
- this.$element = $(element);
- this.$dropdown = null;
- this.options = $.extend({}, CityPicker.DEFAULTS, $.isPlainObject(options) && options);
- this.active = false;
- this.dems = [];
- this.needBlur = false;
- this.init();
- };
- CityPicker.prototype = {
- constructor: CityPicker,
- init: function () {
- this.defineDems();
- this.render();
- this.bind();
- this.active = true;
- var _this = this;
- $(".icon_ca").on('click', function () {
- $("#" + this.PROVINCE).val();
- $("#" + this.CITY).val();
- $("#" + this.DISTRICT).val();
- _this.reset();
- });
- },
- render: function () {
- var p = this.getPosition(),
- placeholder = this.$element.attr('placeholder') || this.options.placeholder,
- textspan = '<span class="city-picker-span" style="' +
- this.getWidthStyle(p.width) + 'height:' +
- (p.height - 2) + 'px;line-height:' + (p.height - 1) + 'px;">' +
- (placeholder ? '<span class="placeholder">' + placeholder + '</span>' : '') +
- '<span class="title"></span><div class="arrow"></div>' + '<i class="icon_ca"></i></span>',
- dropdown = '<div class="city-picker-dropdown" style="left:0px;top:100%;' +
- this.getWidthStyle(p.width, true) + '">' +
- '<div class="city-select-wrap">' +
- '<div class="city-select-tab">' +
- '<a class="active" data-count="' + this.PROVINCE + '">省份</a>' +
- (this.includeDem(this.CITY) ? '<a data-count="' + this.CITY + '">城市</a>' : '') +
- (this.includeDem(this.DISTRICT) ? '<a data-count="' + this.DISTRICT + '">区县</a>' : '') + '</div>' +
- '<div class="city-select-content">' +
- '<div class="city-select province ' + this.PROVINCE + '" data-count="' + this.PROVINCE + '"></div>' +
- (this.includeDem(this.CITY) ? '<div class="city-select ' + this.CITY + '" data-count="' + this.CITY + '"></div>' : '') +
- (this.includeDem(this.DISTRICT) ? '<div class="city-select ' + this.DISTRICT + '" data-count="' + this.DISTRICT + '"></div>' : '') +
- '</div></div>';
- this.$element.addClass('city-picker-input');
- this.$textspan = $(textspan).insertAfter(this.$element);
- this.$dropdown = $(dropdown).insertAfter(this.$textspan);
- var $select = this.$dropdown.find('.city-select');
- // setup this.$province, this.$city and/or this.$district object
- $.each(this.dems, $.proxy(function (i, type) {
- this['$' + type] = $select.filter('.' + type + '');
- }, this));
- this.refresh();
- },
- refresh: function (force) {
- // clean the data-item for each $select
- var $select = this.$dropdown.find('.city-select');
- $select.data('item', null);
- // parse value from value of the target $element
- var val = this.$element.val() || '';
- val = val.split('/');
- $.each(this.dems, $.proxy(function (i, type) {
- if (val[i] && i < val.length) {
- this.options[type] = val[i];
- } else if (force) {
- this.options[type] = '';
- }
- this.output(type);
- }, this));
- this.tab(this.PROVINCE);
- this.feedText();
- this.feedVal();
- },
- defineDems: function () {
- var stop = false;
- if (this.options.provincename !== "") {
- this.PROVINCE = this.options.provincename;
- }
- if (this.options.cityname !== "") {
- this.CITY = this.options.cityname;
- }
- if (this.options.districtname !== "") {
- this.DISTRICT = this.options.districtname;
- }
- $.each([this.PROVINCE, this.CITY, this.DISTRICT], $.proxy(function (i, type) {
- if (!stop) {
- this.dems.push(type);
- }
- if (type === this.options.level) {
- stop = true;
- }
- }, this));
- },
- includeDem: function (type) {
- return $.inArray(type, this.dems) !== -1;
- },
- getPosition: function () {
- var p, h, w, s, pw;
- p = this.$element.position();
- s = this.getSize(this.$element);
- h = s.height;
- w = s.width;
- if (this.options.responsive) {
- pw = this.$element.offsetParent().width();
- if (pw) {
- w = w / pw;
- if (w > 0.99) {
- w = 1;
- }
- w = w * 100 + '%';
- }
- }
- return {
- top: p.top || 0,
- left: p.left || 0,
- height: h,
- width: w
- };
- },
- getSize: function ($dom) {
- var $wrap, $clone, sizes;
- if (!$dom.is(':visible')) {
- $wrap = $("<div />").appendTo($("body"));
- $wrap.css({
- "position": "absolute !important",
- "visibility": "hidden !important",
- "display": "block !important"
- });
- $clone = $dom.clone().appendTo($wrap);
- sizes = {
- width: $clone.outerWidth(),
- height: $clone.outerHeight()
- };
- $wrap.remove();
- } else {
- sizes = {
- width: $dom.outerWidth(),
- height: $dom.outerHeight()
- };
- }
- return sizes;
- },
- getWidthStyle: function (w, dropdown) {
- if (this.options.responsive && !$.isNumeric(w)) {
- return 'width:' + w + ';';
- } else {
- return 'width:' + (dropdown ? Math.max(320, w) : w) + 'px;';
- }
- },
- bind: function () {
- var $this = this;
- $(document).on('click', (this._mouteclick = function (e) {
- var $target = $(e.target);
- var $dropdown, $span, $input;
- if ($target.is('.city-picker-span')) {
- $span = $target;
- } else if ($target.is('.city-picker-span *')) {
- $span = $target.parents('.city-picker-span');
- }
- if ($target.is('.city-picker-input')) {
- $input = $target;
- }
- if ($target.is('.city-picker-dropdown')) {
- $dropdown = $target;
- } else if ($target.is('.city-picker-dropdown *')) {
- $dropdown = $target.parents('.city-picker-dropdown');
- }
- if ((!$input && !$span && !$dropdown) ||
- ($span && $span.get(0) !== $this.$textspan.get(0)) ||
- ($input && $input.get(0) !== $this.$element.get(0)) ||
- ($dropdown && $dropdown.get(0) !== $this.$dropdown.get(0))) {
- $this.close(true);
- }
- }));
- this.$element.on('change', (this._changeElement = $.proxy(function () {
- this.close(true);
- this.refresh(true);
- }, this))).on('focus', (this._focusElement = $.proxy(function () {
- this.needBlur = true;
- this.open();
- }, this))).on('blur', (this._blurElement = $.proxy(function () {
- if (this.needBlur) {
- this.needBlur = false;
- this.close(true);
- }
- }, this)));
- this.$textspan.on('click', function (e) {
- var $target = $(e.target), type;
- $this.needBlur = false;
- if ($target.is('.select-item')) {
- type = $target.data('count');
- $this.open(type);
- } else {
- if ($this.$dropdown.is(':visible')) {
- $this.close();
- } else {
- $this.open();
- }
- }
- }).on('mousedown', function () {
- $this.needBlur = false;
- });
- this.$dropdown.on('click', '.city-select a', function () {
- var $select = $(this).parents('.city-select');
- var $active = $select.find('a.active');
- var last = $select.next().length === 0;
- $active.removeClass('active');
- $(this).addClass('active');
- if ($active.data('code') !== $(this).data('code')) {
- $select.data('item', {
- address: $(this).attr('title'), code: $(this).data('code')
- });
- $(this).trigger(EVENT_CHANGE);
- $this.feedText();
- $this.feedVal();
- if (last) {
- $this.close();
- }
- }
- }).on('click', '.city-select-tab a', function () {
- if (!$(this).hasClass('active')) {
- var type = $(this).data('count');
- $this.tab(type);
- }
- }).on('mousedown', function () {
- $this.needBlur = false;
- });
- if (this['$' + this.PROVINCE]) {
- this['$' + this.PROVINCE].on(EVENT_CHANGE, (this._changeProvince = $.proxy(function () {
- this.output(this.CITY);
- this.output(this.DISTRICT);
- this.tab(this.CITY);
- }, this)));
- }
- if (this['$' + this.CITY]) {
- this['$' + this.CITY].on(EVENT_CHANGE, (this._changeCity = $.proxy(function () {
- this.output(this.DISTRICT);
- this.tab(this.DISTRICT);
- }, this)));
- }
- },
- open: function (type) {
- type = type || this.PROVINCE;
- this.$dropdown.show();
- this.$textspan.addClass('open').addClass('focus');
- this.tab(type);
- },
- close: function (blur) {
- this.$dropdown.hide();
- this.$textspan.removeClass('open');
- if (blur) {
- this.$textspan.removeClass('focus');
- }
- },
- unbind: function () {
- $(document).off('click', this._mouteclick);
- this.$element.off('change', this._changeElement);
- this.$element.off('focus', this._focusElement);
- this.$element.off('blur', this._blurElement);
- this.$textspan.off('click');
- this.$textspan.off('mousedown');
- this.$dropdown.off('click');
- this.$dropdown.off('mousedown');
- if (this['$' + this.PROVINCE]) {
- this['$' + this.PROVINCE].off(EVENT_CHANGE, this._changeProvince);
- }
- if (this.$city) {
- this.$city.off(EVENT_CHANGE, this._changeCity);
- }
- },
- // 动态添加的input无法删除,切换请求有问题
- getText: function () {
- var text = '';
- this.$dropdown.find('.city-select')
- .each(function () {
- var item = $(this).data('item'),
- type = $(this).data('count');
- if (item) {
- text += ($(this).hasClass('province') ? '' : '/') + '<span class="select-item" data-count="' +
- type + '" data-code="' + item.code + '">' + item.address + '</span><input type="hidden" id="' + type + '" name="' + type + '" value="' + item.code + '" />';
- }
- });
- return text;
- },
- getPlaceHolder: function () {
- return this.$element.attr('placeholder') || this.options.placeholder;
- },
- feedText: function () {
- var text = this.getText();
- if (text) {
- this.$textspan.find('>.placeholder').hide();
- // this.$textspan.find('>.title').siblings('input').val('');
- //this.$textspan.find('>.title').children().remove();
- this.$textspan.find('>.title').children("input").val('');
- this.$textspan.find('>.title').html(this.getText()).show();
- } else {
- this.$textspan.find('>.placeholder').text(this.getPlaceHolder()).show();
- this.$textspan.find('>.title').html('').hide();
- }
- },
- getVal: function () {
- var text = '';
- this.$dropdown.find('.city-select')
- .each(function () {
- var item = $(this).data('item');
- if (item) {
- text += ($(this).hasClass('province') ? '' : '/') + item.address;
- }
- });
- return text;
- },
- feedVal: function () {
- this.$element.val(this.getVal());
- },
- output: function (type) {
- var options = this.options;
- var PROVINCE = this.PROVINCE;
- var CITY = this.CITY;
- var DISTRICT = this.DISTRICT;
- //var placeholders = this.placeholders;
- var $select = this['$' + type];
- var data = type === PROVINCE ? {} : [];
- var item;
- var districts;
- var code;
- var matched = null;
- var value;
- if (!$select || !$select.length) {
- return;
- }
- item = $select.data('item');
- value = (item ? item.address : null) || options[type];
- code = (
- type === PROVINCE ? 86 :
- type === CITY ? this['$' + PROVINCE] && this['$' + PROVINCE].find('.active').data('code') :
- type === DISTRICT ? this['$' + CITY] && this['$' + CITY].find('.active').data('code') : code
- );
- districts = $.isNumeric(code) ? ChineseDistricts[code] : null;
- if ($.isPlainObject(districts)) {
- $.each(districts, function (code, address) {
- var provs;
- if (type === PROVINCE) {
- provs = [];
- for (var i = 0; i < address.length; i++) {
- if (address[i].address === value) {
- matched = {
- code: address[i].code,
- address: address[i].address
- };
- }
- provs.push({
- code: address[i].code,
- address: address[i].address,
- selected: address[i].address === value
- });
- }
- data[code] = provs;
- } else {
- if (address === value) {
- matched = {
- code: code,
- address: address
- };
- }
- data.push({
- code: code,
- address: address,
- selected: address === value
- });
- }
- });
- }
- $select.html(type === PROVINCE ? this.getProvinceList(data) :
- this.getList(data, type));
- $select.data('item', matched);
- },
- getProvinceList: function (data) {
- var PROVINCE = this.PROVINCE;
- var list = [],
- $this = this,
- simple = this.options.simple;
- $.each(data, function (i, n) {
- list.push('<dl class="clearfix">');
- list.push('<dt>' + i + '</dt><dd>');
- $.each(n, function (j, m) {
- list.push(
- '<a' +
- ' title="' + (m.address || '') + '"' +
- ' data-code="' + (m.code || '') + '"' +
- ' class="' +
- (m.selected ? ' active' : '') +
- '">' +
- (simple ? $this.simplize(m.address, PROVINCE) : m.address) +
- '</a>');
- });
- list.push('</dd></dl>');
- });
- return list.join('');
- },
- getList: function (data, type) {
- var list = [],
- $this = this,
- simple = this.options.simple;
- list.push('<dl class="clearfix"><dd>');
- $.each(data, function (i, n) {
- list.push(
- '<a' +
- ' title="' + (n.address || '') + '"' +
- ' data-code="' + (n.code || '') + '"' +
- ' class="' +
- (n.selected ? ' active' : '') +
- '">' +
- (simple ? $this.simplize(n.address, type) : n.address) +
- '</a>');
- });
- list.push('</dd></dl>');
- return list.join('');
- },
- simplize: function (address, type) {
- address = address || '';
- if (type === this.PROVINCE) {
- return address.replace(/[省,市,自治区,壮族,回族,维吾尔]/g, '');
- } else if (type === this.CITY) {
- return address.replace(/[市,地区,回族,蒙古,苗族,白族,傣族,景颇族,藏族,彝族,壮族,傈僳族,布依族,侗族]/g, '')
- .replace('哈萨克', '').replace('自治州', '').replace(/自治县/, '');
- } else if (type === this.DISTRICT) {
- return address.length > 2 ? address.replace(/[市,区,县,旗]/g, '') : address;
- }
- },
- tab: function (type) {
- var $selects = this.$dropdown.find('.city-select');
- var $tabs = this.$dropdown.find('.city-select-tab > a');
- var $select = this['$' + type];
- var $tab = this.$dropdown.find('.city-select-tab > a[data-count="' + type + '"]');
- if ($select) {
- $selects.hide();
- $select.show();
- $tabs.removeClass('active');
- $tab.addClass('active');
- }
- },
- reset: function () {
- this.$element.val(null).trigger('change');
- },
- setValue: function (address) { //河南省/信阳市/新县
- this.$element.val(address).trigger('change');
- },
- destroy: function () {
- this.unbind();
- this.$element.removeData(NAMESPACE).removeClass('city-picker-input');
- this.$textspan.remove();
- this.$dropdown.remove();
- }
- };
- // 默认值和参数
- CityPicker.DEFAULTS = {
- simple: false,
- responsive: false,
- placeholder: '请选择省/市/区',
- level: 'district',// 级别
- provincename: '',//input hidden 的值
- cityname: '',//input hidden 的值
- districtname: '',//input hidden 的值
- province: '河南省',// 默认省份名称
- city: '',// 默认地市名称
- district: ''// 默认区县名称
- };
- CityPicker.setDefaults = function (options) {
- $.extend(CityPicker.DEFAULTS, options);
- };
- // Save the other citypicker
- CityPicker.other = $.fn.citypicker;
- // Register as jQuery plugin
- $.fn.citypicker = function (option) {
- var args = [].slice.call(arguments, 1);
- return this.each(function () {
- var $this = $(this);
- var data = $this.data(NAMESPACE);
- var options;
- var fn;
- if (!data) {
- if (/destroy/.test(option)) {
- return;
- }
- options = $.extend({}, $this.data(), $.isPlainObject(option) && option);
- $this.data(NAMESPACE, (data = new CityPicker(this, options)));
- }
- if (typeof option === 'string' && $.isFunction(fn = data[option])) {
- fn.apply(data, args);
- }
- });
- };
- $.fn.citypicker.Constructor = CityPicker;
- $.fn.citypicker.setDefaults = CityPicker.setDefaults;
- // No conflict
- $.fn.citypicker.noConflict = function () {
- $.fn.citypicker = CityPicker.other;
- return this;
- };
- // 自动扫描机制注释掉
- //$(function () {
- // $('[data-toggle="city-picker"]').citypicker();
- //});
- exports('citypicker', CityPicker);
- });
|