layui自定义插件citySelect实现省市区三级联动选择

本文实例为大家分享了layui实现省市区三级联动选择的具体代码,供大家参考,具体内容如下

省市区三级菜单联动插件

/**
 * @ name : citySelect 省市区三级选择模块
 * @ 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: {} //全局配置项
   ,cache: {} //数据缓存
   ,index: layui.laypage ? (layui.laypage.index + 10000) : 0
 };
 
 //操作当前实例
 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(\"\");
 //选项模板
 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(\"\");
 
 
 //构造器
 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\"]; //返回缓存中的选中值
  };
  //设置禁用/启用
  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));
  };
 
 //默认配置
 Class.prototype.config = {
 lableName : \"行政区域\",
 required : false, //是否必选
 search : true,  //是否搜索
 msg:null,  //默认附加信息
 selectedArr : [], //默认选中数组
 disabled:false,  //禁用 默认不禁用
 filed:{
   area:true,  //默认启用区
   regionId:\'regionId\', //默认字段id名
   regionName:\'regionName\',//默认字段name名
   provinceName: \"province\", //默认省份名称
  cityName : \"city\",  //默认城市名称
  areaName : \"area\",  //默认区县名称
   },
 
 };
 
 //加载容器
 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; //如果元素不存在
   
  //请求参数的自定义格式
   options.request = $.extend({
    //pageName: \'page\',
    //limitName: \'limit\'
   }, options.request);
   
   //响应数据的自定义格式
   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();  //监听选择
  
 };
 
 //监听表单
 Class.prototype.formFilter = function(){
 var that = this;
 var options = that.config;
 that.key = options.id || options.index;
 
 //监听省
 form.on(\'select(province\'+that.index+\')\', function(data){
  var cityDom = $(\"#citySelect_\"+ options.filed.cityName + that.index); //市
  var areaDom = $(\"#citySelect_\"+ options.filed.areaName + that.index); //区
  that.chearDom(cityDom);    //清理市
  that.chearDom(areaDom);    //清理区
  citySelect.cache[that.key][\"values\"][0] = data.value; //存入缓存
  citySelect.cache[that.key][\"values\"][1] = \"\";  //清理市级缓存
  citySelect.cache[that.key][\"values\"][2] = \"\";  //清理区级缓存
  if(data.value!=\"\"){
  if(options.data){
   that.localData(cityDom, data.value);  //本地渲染市级  
  }else{
   that.ajaxData(cityDom,data.value);   //ajax渲染市
  }
  }
 }); 
 //监听市
 form.on(\'select(city\'+that.index+\')\', function(data){
  var areaDom = $(\"#citySelect_\"+ options.filed.areaName + that.index); //区
  that.chearDom(areaDom);     //清理区
  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);  //本地渲染市级  
  }else{
   that.ajaxData(areaDom,data.value);   //加载区
  }
  }
 }); 
 //监听区
 form.on(\'select(area\'+that.index+\')\', function(data){
  citySelect.cache[that.key][\"values\"][2] = data.value;
  console.log(\"选择区\"); //得到select原始DOM对象
 }); 
 
 };
 
 //渲染数据
 Class.prototype.pullData = function(){
 var that = this;
 var options = that.config;
 var dom = $(\"#citySelect_\"+ options.filed.provinceName + that.index); //默认先渲染省
 that.key = options.id || options.index;
 citySelect.cache[that.key] = {values:[\"\",\"\",\"\"]}; //记录values缓存标记
 
 if(options.data){  //data存在
  that.localData(dom,\"000000\");
 }else if(options.url){ //url存在
  that.ajaxData(dom);
 }
 
 };
 
 //data渲染数据
 Class.prototype.localData = function(dom,regionId){ 
 var that = this;
 var options = that.config;
 var regs = /^\\d{2}0000$/; //验证省id 
 var regc = /^\\d{4}00$/; //验证市ID
 if(regionId==\"000000\"){
  //渲染省级
  that.renderData(options.data,dom);
 }else if(regs.test(regionId)){
  //渲染市级
  $.each(options.data,function(index,item){
  if(regionId==item[options.filed.regionId]){
   that.renderData(item.children,dom);
  }
  });
 }else if(regc.test(regionId)){
  //渲染区级
  var sId = regionId.substr(0, 2)+\"0000\"; //获取省级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获取数据
 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;  //将已经获取的数据保存缓存
    }
    options.time = (new Date().getTime() - that.startTime) + \' ms\'; //耗时(接口请求+视图渲染)
    typeof options.done === \'function\' && options.done(res);
    }
   ,error: function(e, m){
    that.renderData(\'<option value=\"\">数据接口请求异常</option>\',dom);
    typeof options.error === \'function\' && options.error(res, e,m);
   }
   });
   }
   
 };
 
 //数据渲染
 Class.prototype.renderData = function(data,dom){
 var that = this,
 options = that.config;
 var selectedArr = options.selectedArr; //获取默认选中数组
 
 if(typeof data === \'string\'){
  $(dom).html(data);
 }else{
  //渲染选择项
  $(dom).html( $(laytpl(TPL_OPTION).render({
  data: data,
  options:options,
  index: that.index //索引
  })));
  that.renderForm(\'select\');
 }
 //设置默认选中
 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] = \"\";   //清除默认选择数组
   if(i==0){
   var dom = $(\"#citySelect_\"+ options.filed.cityName + that.index);
   if(options.data){
    that.localData(dom, v); //本地渲染市级  
   }else{
    that.ajaxData(dom, v); //ajax渲染市级
   }
   }else if(i==1&&options.filed.area){
   var dom = $(\"#citySelect_\"+ options.filed.areaName + that.index);
   if(options.data){
    that.localData(dom, v); //本地渲染区级  
   }else{
    that.ajaxData(dom, v); //ajax渲染区级
   }
   }
  }
  }
 }
 };

 
 //渲染表单
 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);
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容