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


Posted in Javascript onJuly 26, 2019

本文实例为大家分享了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);
});

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

Javascript 相关文章推荐
JS仿flash上传头像效果实现代码
Jul 18 Javascript
javascript操作select元素实例分析
Mar 27 Javascript
分享自己用JS做的扫雷小游戏
Feb 17 Javascript
jQuery 生成svg矢量二维码
Aug 09 Javascript
Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
Nov 22 Javascript
jQuery中 bind的用法简单介绍
Feb 13 Javascript
bootstrap datetimepicker控件位置异常的解决方法
Nov 23 Javascript
Angular网络请求的封装方法
May 22 Javascript
浅谈VUE中演示v-for为什么要加key
Jan 16 Javascript
解决vue中axios设置超时(超过5分钟)没反应的问题
Sep 04 Javascript
JavaScript 定时器详情
Nov 11 Javascript
vue.js 使用原生js实现轮播图
Apr 26 Vue.js
微信小程序自定义头部导航栏和导航栏背景图片 navigationStyle问题
Jul 26 #Javascript
jQuery-Citys省市区三级菜单联动插件使用详解
Jul 26 #jQuery
微信小程序—setTimeOut定时器的问题及解决
Jul 26 #Javascript
layUI实现三级导航菜单效果
Jul 26 #Javascript
layui实现三级联动效果
Jul 26 #Javascript
layui实现三级导航菜单
Jul 26 #Javascript
layui实现左侧菜单点击右侧内容区显示
Jul 26 #Javascript
You might like
《星际争霸》各版本雷兽特点图文解析 雷兽不同形态一览
2020/03/02 星际争霸
详解:――如何将图片储存在数据库里
2006/12/05 PHP
PHP中遍历stdclass object的实现代码
2011/06/09 PHP
PHP新手用的Insert和Update语句构造类
2012/03/31 PHP
php生成图片验证码
2015/06/09 PHP
Zend Framework框架Smarty扩展实现方法
2016/03/22 PHP
php7新特性的理解和比较总结
2019/04/14 PHP
在JavaScript中使用inline函数的问题
2007/03/08 Javascript
yepnope.js 异步加载资源文件
2011/09/08 Javascript
jquery ajax局部加载方法详解(实现代码)
2016/05/12 Javascript
Bootstrap编写一个在当前网页弹出可关闭的对话框 非弹窗
2016/06/30 Javascript
使用JavaScript获取Request中参数的值方法
2016/09/27 Javascript
JS自定义滚动条效果简单实现代码
2020/10/27 Javascript
vue2.0 根据状态值进行样式的改变展示方法
2018/03/13 Javascript
vue使用jsonp抓取qq音乐数据的方法
2018/06/21 Javascript
Vue服务端渲染实践之Web应用首屏耗时最优化方案
2019/03/22 Javascript
[49:27]LGD vs OG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[36:33]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.29
2020/12/02 DOTA
[01:48:04]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant BO3 第一场 2月7日
2021/03/11 DOTA
python实现颜色rgb和hex相互转换的函数
2015/03/19 Python
python django使用haystack:全文检索的框架(实例讲解)
2017/09/27 Python
详解Python开发中如何使用Hook技巧
2017/11/01 Python
linux下python使用sendmail发送邮件
2018/05/22 Python
python抓取需要扫微信登陆页面
2019/04/29 Python
解决python运行效率不高的问题
2020/07/20 Python
Python实现图片指定位置加图片水印(附Pyinstaller打包exe)
2021/03/04 Python
Alba Moda德国网上商店:意大利时尚女装销售
2016/11/14 全球购物
Michael Kors香港官网:美国奢侈品品牌
2019/12/26 全球购物
2014乡镇“三八”国际劳动妇女节活动总结
2014/03/01 职场文书
日语专业毕业生自荐书
2014/06/18 职场文书
2015年党务公开工作总结
2015/05/19 职场文书
暑期工社会实践报告
2015/07/13 职场文书
2015大一新生军训感言
2015/08/01 职场文书
2016年母亲节广告语
2016/01/28 职场文书
python实现过滤敏感词
2021/05/08 Python
Python进度条的使用
2021/05/17 Python