下面是效果图:
在public\assets\libs\fastadmin-citypicker目录下原有的基础上复制一份,重命名city-picker-multi.min.js,在这个基础上更改。
参考文章
如何在FastAdmin中加载第三方JS插件或自己编写插件? - FastAdmin问答社区
在public\assets\js\backend-init.js中新增一下内容:
define(['backend'], function (Backend) {
require.config({
paths: {
'citypickermulti': '../libs/fastadmin-citypicker/dist/js/city-picker-multi.min',
},
shim: {
'citypickermulti': ['citypicker-data', 'css!../libs/fastadmin-citypicker/dist/css/city-picker.css'],
}
});
});
执行命令
php think min -m all -r all
这样加载就ok了.
如果执行命令未压缩 backend-init.js
可以在public\assets\js\require-backend.js中增加
那么怎么绑定触发呢?参考city-picker的使用,在public\assets\js\require-form.js中新增一下内容
调用:
其中:
data-toggle="city-picker-multi" 是触发器了,data-input是生成的隐藏域的name值,提交后用这个name值接收,data-input_val是默认选中的code值,多个值用英文“,”连接,data-input_address和value是默认选中的code值对应的地区名称,用 “/” 连接多个值,注意要和code一一对应,下面是插件的代码:
/*!
* CityPicker v1.3.1
* https://github.com/tshi0912/citypicker
*
* Copyright (c) 2015-2018 Tao Shi
* Released under the MIT license
*
* Date: 2018-09-10T15:57:49.592Z
*/
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery', 'ChineseDistricts'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'), require('ChineseDistricts'));
} else {
// Browser globals.
factory(jQuery, ChineseDistricts);
}
})(function($, ChineseDistricts) {
'use strict';
// $.post("/api/pub/getcity",function(data){
// ChineseDistricts = data;
// },"json");
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 COUNTRY = 'country';
var PROVINCE = 'province';
var CITY = 'city';
var DISTRICT = 'district';
Array.prototype.indexOf = function(val, key = '') {
for (var i = 0; i < this.length; i++) {
if(key != ''){
if(this[i][key] == val) return i;
}else{
if (this[i] == val) return i;
}
}
return -1;
}
Array.prototype.remove = function(val, key = '') {
var index = this.indexOf(val, key);
if (index > -1) {
this.splice(index, 1);
}
};
function CityPicker(element, options) {
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;
},
render: function() {
var p = this.getPosition(),
placeholder = this.$element.attr('placeholder') || this.options.placeholder,
valInput = this.$element.data('input') || this.options.input,
inputval = this.$element.data('input_val') || this.options.inputval,
inputaddress = this.$element.data('input_address') || this.options.inputaddress,
textspan = '' +
(placeholder ? '' + placeholder + '' : '') +
'' + '',
dropdown = '' +
'' +
'' +
'国家' +
(this.includeDem('province') ? '省份' : '') +
(this.includeDem('city') ? '城市' : '') +
(this.includeDem('district') ? '区县' : '') + '' +
'' +
'' +
(this.includeDem('province') ? '' : '') +
(this.includeDem('city') ? '' : '') +
(this.includeDem('district') ? '' : '') +
'' +
'',
inputitem = '',
multiresdiv = ' ';
this.$element.addClass('city-picker-input');
this.$textspan = $(textspan).insertAfter(this.$element);
this.$dropdown = $(dropdown).insertAfter(this.$textspan);
this.$inputitem = $(inputitem).insertAfter(this.$dropdown);
this.$multiresdiv = $(multiresdiv).insertBefore(this.$element);
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('/');
val = val.split(',');
val = val[0].split(/[\/-]/);
if(val[0] != '' && val[0] != '全国'){
val.unshift('全国');
}
$.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(COUNTRY);
// this.tab(PROVINCE);
this.feedText();
this.feedVal();
},
defineDems: function() {
var stop = false;
$.each([COUNTRY, PROVINCE, CITY, 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 = $("").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 _that = this;
var $select = $(this).parents('.city-select');
var $active = $select.find('a.active');
var last = $select.next().length === 0;
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).addClass('active');
}
var dataitem = [];
var selectitem = $select.data('item') || [];
if (selectitem.length <= 0) {
$select.data('item', []);
}
if ($(this).hasClass('active')) {
$select.data('item').push({
address: $(this).attr('title'),
code: $(this).data('code')
});
} else {
selectitem = $select.data('item');
$select.data('item').remove($(_that).attr('title'), 'address');
}
$(this).trigger(EVENT_CHANGE);
$this.feedText();
$this.feedVal(true);
}).on('click', '.city-select-tab a', function() {
if (!$(this).hasClass('active')) {
var type = $(this).data('count');
$this.tab(type);
}
}).on('click', '.city-select-confirm .csc-y', function() {
var code = $this.getCode("district") || $this.getCode("city") || $this.getCode("province") || $this.getCode('country');
var text = $this.getVal();
var multivalarr = $this.$inputitem.val() ? $this.$inputitem.val().split(',') : [];
// console.log(text);
var _that = this;
if(typeof code != 'undefined' && code.length > 0){
var textarr = text.split(',');
var textspan = '';
for (var i = 0; i < code.length; i++) {
var isthere = false;
$this.$multiresdiv.find('.multi-city-res-span').each(function(){
if($(this).data('code') == code[i]){
isthere = true;
}
});
if(isthere === false){
multivalarr.push(code[i]);
$this.$inputitem.val(multivalarr.join());
textspan += ' X ' + textarr[i] + ' ';
}
}
$this.$multiresdiv.removeClass('hide');
$(textspan).appendTo($this.$multiresdiv);
}
$this.close();
}).on('click', '.city-select-confirm .csc-n', function() {
$this.close();
}).on('mousedown', function() {
$this.needBlur = false;
});
this.$multiresdiv.on('click', '.del-multi-span', function(){
var multispan = $(this).closest('span');
var thiscode = multispan.data('code');
var multivalarr = $this.$inputitem.val() ? $this.$inputitem.val().split(',') : [];
for (var i = 0; i < multivalarr.length; i++) {
// console.log({'multival': multivalarr[i], 'thiscode': thiscode});
if(parseInt(multivalarr[i]) == thiscode){
multivalarr.splice(i, 1);
}
}
multispan.remove();
$this.$inputitem.val(multivalarr);
if($this.$multiresdiv.find('.multi-city-res-span').length <= 0){
$this.$multiresdiv.addClass('hide');
}
});
if (this.$country) {
this.$country.on(EVENT_CHANGE, (this._changeCountry = $.proxy(function() {
this.output(PROVINCE)
this.output(CITY);
this.output(DISTRICT);
// this.tab(PROVINCE);
}, this)));
}
if (this.$province) {
this.$province.on(EVENT_CHANGE, (this._changeProvince = $.proxy(function() {
this.output(CITY);
this.output(DISTRICT);
// this.tab(CITY);
}, this)));
}
if (this.$city) {
this.$city.on(EVENT_CHANGE, (this._changeCity = $.proxy(function() {
this.output(DISTRICT);
// this.tab(DISTRICT);
}, this)));
}
if (this.$inputval) {
}
},
open: function(type) {
type = type || COUNTRY;
// type = type || 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.$country) {
this.$country.off(EVENT_CHANGE, this._changeCountry);
}
if (this.$province) {
this.$province.off(EVENT_CHANGE, this._changeProvince);
}
if (this.$city) {
this.$city.off(EVENT_CHANGE, this._changeCity);
}
},
getText: function() {
var text = '';
var spantextarr = [];
var eachindex = 0;
this.$dropdown.find('.city-select')
.each(function() {
var _that = this;
var spanresarr = [];
var item = $(this).data('item');
console.log(item)
var type = $(this).data('count');
var spantext;
if (item) {
$.each(item, function(index, itemdata) {
spantext = '' + itemdata.address + '';
spanresarr.push(spantext);
})
spantextarr.push(spanresarr)
}
});
var zuhe = this.zuHe(spantextarr);
if (typeof zuhe != 'undefined') {
text = zuhe.join();
}
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').html(this.getText()).show();
} else {
this.$textspan.find('>.placeholder').text(this.getPlaceHolder()).show();
this.$textspan.find('>.title').html('').hide();
}
},
getCode: function(count) {
var obj = {},
arr = [];
this.$textspan.find('.select-item')
.each(function() {
var code = $(this).data('code');
var count = $(this).data('count');
if(! (count in obj)){
obj[count] = [];
}
obj[count].push(code);
arr.push(code);
});
// var res = count ? obj[count] : arr.join('/');
// console.log(res);
return count ? obj[count] : arr.join('/');
},
getVal: function() {
var text = '';
var textarr = [];
var eachindex = 0;
this.$dropdown.find('.city-select')
.each(function() {
var _that = this;
var resarr = [];
var item = $(this).data('item');
// console.log(item);
if (item) {
$.each(item, function(index, itemdata) {
resarr.push(itemdata.address);
})
textarr.push(resarr)
}
});
var zuhe = this.zuHe(textarr);
if (typeof zuhe != 'undefined') {
text = zuhe.join();
}
return text;
},
feedVal: function(trigger) {
this.$element.val(this.getVal());
if (trigger) {
this.$element.trigger('cp:updated');
}
},
zuHe: function(selectaddress) {
var heads = selectaddress[0];
for (var i = 1, len = selectaddress.length; i < len; i++) {
if (selectaddress[i].length) {
heads = this.addNewType(heads, selectaddress[i]);
}
}
return heads;
},
addNewType: function(heads, choices) {
var result = [];
for (var i = 0, len = heads.length; i < len; i++) {
for (var j = 0, lenj = choices.length; j < lenj; j++) {
result.push(heads[i] + '/' + choices[j]);
}
}
return result;
},
indexOfArr: function(arr, val) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] == val) {
return i;
}
}
return -1;
},
removeArrVal: function(arr, val) {
var index = this.indexOfArr(arr, val);
if (index > -1) {
arr.splice(index, 1);
}
return arr;
},
addMultiSpan: function(inputaddress, inputval) {
var text = '';
if(inputaddress){
var inputaddarr = inputaddress ? inputaddress.toString().split(',') : [];
var inputvalarr = inputval ? inputval.toString().split(',') : [];
var textarr = [];
for (var i = 0; i < inputaddarr.length; i++) {
textarr.push(' X ' + inputaddarr[i] + ' ');
}
text = textarr.join(',');
}
return text;
},
output: function(type) {
var options = this.options;
//var placeholders = this.placeholders;
var $select = this['$' + type];
// var data = type === COUNTRY ? {} : [];
var data = type === PROVINCE ? {} : [];
var item;
var districts;
var code;
var matched = null;
var value;
var ismore = false;
if (!$select || !$select.length) {
return;
}
item = $select.data('item');
value = (item ? item.address : null) || options[type];
code = (
type === COUNTRY ? 0 :
// type === PROVINCE ? 86 :
type === PROVINCE ? this.$country && this.$country.find('.active').data('code') :
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;
ismore = (
type === COUNTRY ? false :
// type === PROVINCE ? 86 :
type === PROVINCE ? (this.$country.find('.active').length > 1) :
type === CITY ? (this.$province.find('.active').length > 1) :
type === DISTRICT ? (this.$city.find('.active').length > 1) : ismore
);
if (ismore == true) {
districts = {};
}
if ($.isPlainObject(districts)) {
$.each(districts, function(code, address) {
var provs;
if (type === COUNTRY) {
if (address === value) {
// matched = {
// code: code,
// address: address
// };
matched = [];
matched.push({
code: code,
address: address
});
}
data.push({
code: code,
address: address,
selected: address === value
});
} else 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
// };
matched = [];
matched.push({
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
// };
matched = [];
matched.push({
code: code,
address: address
});
}
data.push({
code: code,
address: address,
selected: address === value
});
}
});
}
$select.html(type === COUNTRY ? this.getCountryList(data, type) :
type === PROVINCE ? this.getProvinceList(data) :
this.getList(data, type));
$select.data('item', matched);
},
getCountryList: function(data, type) {
var list = [],
$this = this,
simple = this.options.simple;
list.push('- ');
$.each(data, function(i, n) {
list.push(
'' +
(simple ? $this.simplize(n.address, type) : n.address) +
'');
});
list.push('
');
return list.join('');
},
getProvinceList: function(data) {
var list = [],
$this = this,
simple = this.options.simple;
$.each(data, function(i, n) {
list.push('');
list.push('- ' + i + '
- ');
$.each(n, function(j, m) {
list.push(
'' +
(simple ? $this.simplize(m.address, PROVINCE) : m.address) +
'');
});
list.push('
');
});
return list.join('');
},
getList: function(data, type) {
var list = [],
$this = this,
simple = this.options.simple;
list.push('- ');
$.each(data, function(i, n) {
list.push(
'' +
(simple ? $this.simplize(n.address, type) : n.address) +
'');
});
list.push('
');
return list.join('');
},
simplize: function(address, type) {
address = address || '';
if (type === COUNTRY) {
return address.replace(/[国家,省,市,自治区]/g, '');
} else if (type === PROVINCE) {
return address.replace(/[省,市,自治区,壮族,回族,维吾尔]/g, '');
} else if (type === CITY) {
return address.replace(/[市,地区,回族,蒙古,苗族,白族,傣族,景颇族,藏族,彝族,壮族,傈僳族,布依族,侗族]/g, '')
.replace('哈萨克', '').replace('自治州', '').replace(/自治县/, '');
} else if (type === 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');
},
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: '请选择全国省/市/区',
input: 'area',
inputval: '',
inputaddress: '',
level: 'district',
country: '',
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-multi"]').citypicker();
});
});
以上代码只是初步满足了需求。