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 相关文章推荐
表格 隔行换色升级版
Nov 07 Javascript
ajax页面无刷新 IE下遭遇Ajax缓存导致数据不更新的问题
Dec 11 Javascript
JQuery中对Select的option项的添加、删除、取值
Aug 25 Javascript
jQuery Trim去除字符串首尾空字符的实现方法说明
Feb 11 Javascript
jQuery实现tag便签去重效果的方法
Jan 20 Javascript
JS实现页面进入和返回定位到具体位置
Dec 08 Javascript
EasyUI学习之Combobox下拉列表(1)
Dec 29 Javascript
highcharts 在angular中的使用示例代码
Sep 20 Javascript
JS遍历DOM文档树的方法实例详解
Apr 03 Javascript
Javascript实现时间倒计时功能
Nov 17 Javascript
微信小程序MUI导航栏透明渐变功能示例(通过改变opacity实现)
Jan 24 Javascript
jQuery是用来干什么的 jquery其实就是一个js框架
Feb 04 jQuery
微信小程序自定义头部导航栏和导航栏背景图片 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
不用iconv库的gb2312与utf-8的互换函数
2006/10/09 PHP
Zend的MVC机制使用分析(二)
2013/05/02 PHP
使用ThinkPHP+Uploadify实现图片上传功能
2014/06/26 PHP
js 强制弹出窗口代码研究-又一款代码
2010/03/20 Javascript
js 返回时间戳所对应的具体时间
2010/07/20 Javascript
jquery仅用6行代码实现滑动门效果
2015/09/07 Javascript
knockoutjs动态加载外部的file作为component中的template数据源的实现方法
2016/09/01 Javascript
微信小程序开发之视频播放器 Video 弹幕 弹幕颜色自定义实例
2016/12/08 Javascript
自定义事件解决重复请求BUG的问题
2017/07/11 Javascript
jQuery实现浏览器之间跳转并传递参数功能【支持中文字符】
2018/03/28 jQuery
解决vue项目打包后提示图片文件路径错误的问题
2018/07/04 Javascript
jquery.param()实现数组或对象的序列化方法
2018/10/08 jQuery
浅谈vue获得后台数据无法显示到table上面的坑
2020/08/13 Javascript
一起深入理解js中的事件对象
2021/02/06 Javascript
[02:02]DOTA2英雄基础教程 斯拉达
2013/12/11 DOTA
Python牛刀小试密码爆破
2011/02/03 Python
Python对文件操作知识汇总
2016/05/15 Python
Python的collections模块中的OrderedDict有序字典
2016/07/07 Python
Python对列表中的各项进行关联详解
2017/08/15 Python
Python爬虫实例扒取2345天气预报
2018/03/04 Python
Python matplotlib 画图窗口显示到gui或者控制台的实例
2018/05/24 Python
python 判断字符串中是否含有汉字或非汉字的实例
2019/07/15 Python
python使用tomorrow实现多线程的例子
2019/07/20 Python
Python3安装pip工具的详细步骤
2019/10/14 Python
详解python中groupby函数通俗易懂
2020/05/14 Python
韩国三星旗下的一家超市连锁店:Home Plus
2016/07/30 全球购物
Expedia英国:全球最大的在线旅游公司
2017/09/07 全球购物
澳大利亚领先的内衣店:Bendon Lingerie澳大利亚
2020/05/15 全球购物
美国狗旅行和户外用品领先供应商:kurgo
2020/08/18 全球购物
C#面试常见问题
2013/02/25 面试题
网上常见的一份Linux面试题(多项选择部分)
2015/02/07 面试题
2014年重阳节老干部座谈会上的讲话稿
2014/09/25 职场文书
反四风个人对照检查材料思想汇报
2014/09/25 职场文书
青岛海底世界导游词
2015/02/11 职场文书
党支部半年考察意见
2015/06/01 职场文书
感恩主题班会教案
2015/08/12 职场文书