layui自定義插件citySelect實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)選擇
本文實(shí)例為大家分享了layui實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)選擇的具體代碼,供大家參考,具體內(nèi)容如下
省市區(qū)三級(jí)菜單聯(lián)動(dòng)插件
/**
* @ name : citySelect 省市區(qū)三級(jí)選擇模塊
* @ Author: aggerChen
* @ version: 1.0
*/
layui.define(['layer','form','element','laytpl'], function(exports){
var $ = layui.$;
var form = layui.form;
var laytpl = layui.laytpl;
var element = layui.emelemt;
//外部接口
var citySelect = {
config: {} //全局配置項(xiàng)
,cache: {} //數(shù)據(jù)緩存
,index: layui.laypage ? (layui.laypage.index + 10000) : 0
};
//操作當(dāng)前實(shí)例
var thisSelect = function(){
var that = this,
options = that.config,
id = options.id;
id && (thisSelect.config[id] = options);
return {
reload: function(options){
that.reload.call(that, options);
},
config: options
}
};
//字符常量
var MOD_NAME = 'citySelect';
//主模板
var TPL_MAIN = ['<div class="layui-form-item" >',
'<label class="layui-form-label">{{ d.data.lableName }}</label>',
'<div class="layui-input-inline" style="width:160px">',
'<select name="{{ d.data.filed.provinceName }}" class="{{ d.data.id }}_selectCity" id="citySelect_{{ d.data.filed.provinceName }}{{ d.index }}" lay-filter="province{{ d.index }}" {{#if(d.data.search){ }} lay-search {{# } }} {{#if(d.data.required){ }} lay-verify="required" {{# } }} {{#if(d.data.disabled){ }} disabled {{# } }} >',
'<option value="000000">-- 全部 --</option>',
'</select>',
'</div>',
'<div class="layui-input-inline" style="width:161px">',
'<select name="{{ d.data.filed.cityName }}" class="{{ d.data.id }}_selectCity" id="citySelect_{{ d.data.filed.cityName }}{{ d.index }}" lay-filter="city{{ d.index }}" {{#if(d.data.search){ }} lay-search {{# } }} {{#if(d.data.required){ }} lay-verify="required" {{# } }} {{#if(d.data.disabled){ }} disabled {{# } }} >',
'<option value="">-- 全部 --</option>',
'</select>',
'</div>',
'{{# if(d.data.filed.area){ }}',
'<div class="layui-input-inline" style="width:161px">',
'<select name="{{ d.data.filed.areaName }}" class="{{ d.data.id }}_selectCity" id="citySelect_{{ d.data.filed.areaName }}{{ d.index }}" lay-filter="area{{ d.index }}" {{#if(d.data.search){ }} lay-search {{# } }} {{#if(d.data.required){ }} lay-verify="required" {{# } }} {{#if(d.data.disabled){ }} disabled {{# } }} >',
'<option value="">-- 全部 --</option>',
'</select>',
'</div>',
'{{# } }}',
'{{# if(d.data.msg){ }}',
'<div class="layui-form-mid layui-word-aux">{{ d.data.msg }}</div>',
'{{# } }}',
'</div>'
].join("");
//選項(xiàng)模板
var TPL_OPTION = [
'<option value="">-- 全部 --</option>',
'{{# layui.each(d.data,function(index,item){ }}',
'<option class="ajaxOption" value="{{ item[d.options.filed.regionId] }}" {{#if(d.options.selectedArr.length>0 && ($.inArray(item[d.options.filed.regionId], d.options.selectedArr)!=-1)){ }} selected {{# } }} >{{ item[d.options.filed.regionName] }}</option>',
'{{# }) }}'
].join("");
//構(gòu)造器
var Class = function(options){
var that = this;
that.index = ++citySelect.index;
that.config = $.extend(true,{}, that.config, citySelect.config, options);
that.render();
};
//核心入口
citySelect.render = function(options){
var inst = new Class(options);
return thisSelect.call(inst);
};
//獲取選中值
citySelect.values = function(id){
return citySelect.cache[id]["values"]; //返回緩存中的選中值
};
//設(shè)置禁用/啟用
citySelect.disabled = function(id,flag){
$("."+id+"_selectCity").attr("disabled",flag);
};
//重載
thisSelect.config = {};
citySelect.reload = function(id,options){
var config = thisSelect.config[id];
if(!config) return hint.error('The ID option was not found in the citySelect instance');
return citySelect.render($.extend(true, {}, config, options));
};
//默認(rèn)配置
Class.prototype.config = {
lableName : "行政區(qū)域",
required : false, //是否必選
search : true, //是否搜索
msg:null, //默認(rèn)附加信息
selectedArr : [], //默認(rèn)選中數(shù)組
disabled:false, //禁用 默認(rèn)不禁用
filed:{
area:true, //默認(rèn)啟用區(qū)
regionId:'regionId', //默認(rèn)字段id名
regionName:'regionName',//默認(rèn)字段name名
provinceName: "province", //默認(rèn)省份名稱
cityName : "city", //默認(rèn)城市名稱
areaName : "area", //默認(rèn)區(qū)縣名稱
},
};
//加載容器
Class.prototype.render = function(){
var that = this;
var options = that.config;
options.elem = $(options.elem);
var othis = options.elem;
if(!options.elem[0]) return that; //如果元素不存在
//請(qǐng)求參數(shù)的自定義格式
options.request = $.extend({
//pageName: 'page',
//limitName: 'limit'
}, options.request);
//響應(yīng)數(shù)據(jù)的自定義格式
options.response = $.extend({
statusName: 'code',
statusCode: 0,
msgName: 'msg',
dataName: 'data',
}, options.response);
//主容器
var reElem = that.elem = $(laytpl(TPL_MAIN).render({
//VIEW_CLASS: ELEM_VIEW,
data: options,
index: that.index //索引
}));
othis.html(reElem); //生成主元素
that.pullData(); //渲染初始
that.formFilter(); //監(jiān)聽選擇
};
//監(jiān)聽表單
Class.prototype.formFilter = function(){
var that = this;
var options = that.config;
that.key = options.id || options.index;
//監(jiān)聽省
form.on('select(province'+that.index+')', function(data){
var cityDom = $("#citySelect_"+ options.filed.cityName + that.index); //市
var areaDom = $("#citySelect_"+ options.filed.areaName + that.index); //區(qū)
that.chearDom(cityDom); //清理市
that.chearDom(areaDom); //清理區(qū)
citySelect.cache[that.key]["values"][0] = data.value; //存入緩存
citySelect.cache[that.key]["values"][1] = ""; //清理市級(jí)緩存
citySelect.cache[that.key]["values"][2] = ""; //清理區(qū)級(jí)緩存
if(data.value!=""){
if(options.data){
that.localData(cityDom, data.value); //本地渲染市級(jí)
}else{
that.ajaxData(cityDom,data.value); //ajax渲染市
}
}
});
//監(jiān)聽市
form.on('select(city'+that.index+')', function(data){
var areaDom = $("#citySelect_"+ options.filed.areaName + that.index); //區(qū)
that.chearDom(areaDom); //清理區(qū)
citySelect.cache[that.key]["values"][1] = data.value;
citySelect.cache[that.key]["values"][2] = "";
if(data.value!=""){
if(options.data){
that.localData(areaDom, data.value); //本地渲染市級(jí)
}else{
that.ajaxData(areaDom,data.value); //加載區(qū)
}
}
});
//監(jiān)聽區(qū)
form.on('select(area'+that.index+')', function(data){
citySelect.cache[that.key]["values"][2] = data.value;
console.log("選擇區(qū)"); //得到select原始DOM對(duì)象
});
};
//渲染數(shù)據(jù)
Class.prototype.pullData = function(){
var that = this;
var options = that.config;
var dom = $("#citySelect_"+ options.filed.provinceName + that.index); //默認(rèn)先渲染省
that.key = options.id || options.index;
citySelect.cache[that.key] = {values:["","",""]}; //記錄values緩存標(biāo)記
if(options.data){ //data存在
that.localData(dom,"000000");
}else if(options.url){ //url存在
that.ajaxData(dom);
}
};
//data渲染數(shù)據(jù)
Class.prototype.localData = function(dom,regionId){
var that = this;
var options = that.config;
var regs = /^\d{2}0000$/; //驗(yàn)證省id
var regc = /^\d{4}00$/; //驗(yàn)證市ID
if(regionId=="000000"){
//渲染省級(jí)
that.renderData(options.data,dom);
}else if(regs.test(regionId)){
//渲染市級(jí)
$.each(options.data,function(index,item){
if(regionId==item[options.filed.regionId]){
that.renderData(item.children,dom);
}
});
}else if(regc.test(regionId)){
//渲染區(qū)級(jí)
var sId = regionId.substr(0, 2)+"0000"; //獲取省級(jí)Id
$.each(options.data,function(index,item){
if(sId==item[options.filed.regionId]){
$.each(item.children,function(i,it){
if(regionId==it[options.filed.regionId]){
that.renderData(it.children,dom);
}
});
}
});
}
}
//ajax獲取數(shù)據(jù)
Class.prototype.ajaxData = function(dom,regionId){
var that = this;
var options = that.config;
var response = options.response;
var params = {};
params[options.filed.regionId] = regionId==undefined?"000000":regionId;
//先查看緩存有沒有
if(citySelect.cache[that.key][regionId]!=undefined ){
that.renderData(citySelect.cache[that.key][regionId],dom);
}else{
$.ajax({
type: options.method || 'get',
url: options.url,
data: $.extend(params, options.where),
dataType: 'json',
success: function(res){
if(res[response.statusName] != response.statusCode){
that.renderForm();
typeof options.error === 'function' && options.error(res);
return ;
}
var data = res[options.response.dataName] || [];
that.renderData(data,dom);
if(data.length>0){
citySelect.cache[that.key][regionId] = data; //將已經(jīng)獲取的數(shù)據(jù)保存緩存
}
options.time = (new Date().getTime() - that.startTime) + ' ms'; //耗時(shí)(接口請(qǐng)求+視圖渲染)
typeof options.done === 'function' && options.done(res);
}
,error: function(e, m){
that.renderData('<option value="">數(shù)據(jù)接口請(qǐng)求異常</option>',dom);
typeof options.error === 'function' && options.error(res, e,m);
}
});
}
};
//數(shù)據(jù)渲染
Class.prototype.renderData = function(data,dom){
var that = this,
options = that.config;
var selectedArr = options.selectedArr; //獲取默認(rèn)選中數(shù)組
if(typeof data === 'string'){
$(dom).html(data);
}else{
//渲染選擇項(xiàng)
$(dom).html( $(laytpl(TPL_OPTION).render({
data: data,
options:options,
index: that.index //索引
})));
that.renderForm('select');
}
//設(shè)置默認(rèn)選中
var v = $(dom).val();
if(v!=""&&selectedArr.length>0){
for (var i = 0; i < selectedArr.length; i++) {
if(v == selectedArr[i] && i<3){
citySelect.cache[that.key]["values"][i] = v; //保存到選中緩存
that.config.selectedArr[i] = ""; //清除默認(rèn)選擇數(shù)組
if(i==0){
var dom = $("#citySelect_"+ options.filed.cityName + that.index);
if(options.data){
that.localData(dom, v); //本地渲染市級(jí)
}else{
that.ajaxData(dom, v); //ajax渲染市級(jí)
}
}else if(i==1&&options.filed.area){
var dom = $("#citySelect_"+ options.filed.areaName + that.index);
if(options.data){
that.localData(dom, v); //本地渲染區(qū)級(jí)
}else{
that.ajaxData(dom, v); //ajax渲染區(qū)級(jí)
}
}
}
}
}
};
//渲染表單
Class.prototype.renderForm = function(type){
form.render(type);
};
//清空select
Class.prototype.chearDom = function(dom){
var that = this;
$(dom).html('');
$(dom).append('<option value="">-- 全部 --</option>');
that.renderForm('select');
};
//暴露模塊
exports(MOD_NAME, citySelect);
});
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js簡(jiǎn)單遍歷獲取對(duì)象中的屬性值的方法示例
這篇文章主要介紹了js簡(jiǎn)單遍歷獲取對(duì)象中的屬性值的方法,涉及javascript使用for循環(huán)遍歷json對(duì)象屬性值的簡(jiǎn)單操作技巧,需要的朋友可以參考下2019-06-06
axios實(shí)現(xiàn)簡(jiǎn)單文件上傳功能
這篇文章主要為大家詳細(xì)介紹了axios實(shí)現(xiàn)簡(jiǎn)單文件上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
javascript使用閉包模擬對(duì)象的私有屬性和方法
本文給大家簡(jiǎn)單介紹了在一個(gè)項(xiàng)目中涉及到的javascript使用閉包模擬對(duì)象的私有屬性和方法,這里記錄下來(lái),分享給大家。2016-10-10
js實(shí)現(xiàn)文字跟隨鼠標(biāo)移動(dòng)而移動(dòng)的方法
這篇文章主要介紹了js實(shí)現(xiàn)文字跟隨鼠標(biāo)移動(dòng)而移動(dòng)的方法,實(shí)例分析了javascript處理鼠標(biāo)事件及文字特效的技巧,需要的朋友可以參考下2015-02-02
解決echarts的多個(gè)折現(xiàn)數(shù)據(jù)出現(xiàn)坐標(biāo)和值對(duì)不上的問(wèn)題
這篇文章主要介紹了解決echarts的多個(gè)折現(xiàn)數(shù)據(jù)出現(xiàn)坐標(biāo)和值對(duì)不上的問(wèn)題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
JS?中的URLSearchParams?對(duì)象操作(以對(duì)象的形式上傳參數(shù)到url)
這篇文章主要介紹了JS中URLSearchParams的基本用法,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12
openlayers4.6.5實(shí)現(xiàn)距離量測(cè)和面積量測(cè)
這篇文章主要為大家詳細(xì)介紹了openlayers4.6.5實(shí)現(xiàn)距離量測(cè)和面積量測(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09

