layui自定义插件citySelect 省市区三级联动选择
省市区三级菜单联动插件
citySelect.js
/**
* @ 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);
});
layui自定义插件citySelect 省市区三级联动选择的更多相关文章
- vue仿京东省市区三级联动选择组件
工作中需要一个盒京东购物车地址选择相似的一个省市区三级联动选择组件,google查了下都是下拉框形式的,于是自己写了一个,希望对使用vue开发项目的朋友有帮助,显示效果如下:使用vue2.0开发 ht ...
- Android中使用开源框架citypickerview实现省市区三级联动选择
1.概述 记得之前做商城项目,需要在地址选择中实现省市区三级联动,方便用户快速的填写地址,当时使用的是一个叫做android-wheel 的开源控件,当时感觉非常好用,唯一麻烦的是需要自己整理并解析省 ...
- 小程序--wepy省市区三级联动选择
产品老哥对项目再一次进行关爱, 新增页面, 新增需求, 很完美........ 不多说, 记录一下新增东西中的省市区联动选择, (这里全国地区信息是在本地, 但不建议这么做, 因为js文件太大.. 建 ...
- laraveladmin省市区三级联动
Distpicker是一个中国省市区三级联动选择组件,这个包是基于Distpicker的laravel-admin扩展,用来将Distpicker集成进laravel-admin的表单中 安装 com ...
- 原生JS实现省市区(县)三级联动选择
原文地址→看过来 写在前面 前段时间写一个关于天气的东西,里面的省市区(县)城市选择让我很头疼,在网上搜索出来大都是借助插件或者第三方库,感觉这样做代码会很重,所以索性就把几种城市选择的方式实现一遍, ...
- jQuery省市区三级联动插件
体验效果:http://hovertree.com/texiao/bootstrap/4/支持PC和手机移动端. 手机扫描二维码体验效果: 代码如下: <!DOCTYPE html> &l ...
- 项目一:第九天 1、前台客户登录 2、Jquery citypicker省市区三级联动插件 4、业务受理(在线下单)
1. 前台客户登录 2. Jquery citypicker省市区三级联动插件 3. 百度地图介绍 4. 业务受理(在线下单) 1 实现前台系统登录功能 1.1 Md5加密 admin(明文)---- ...
- 插件 原生js 省市区 三级联动 源码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue 引用省市区三级联动(插件)
vue 用省市区三级联动之傻瓜式教程(复制粘贴即用) npm 下载 npm install v-distpicker --save main.js //引入 省市区三级联动 import Distpi ...
随机推荐
- webservice代码编写主要包括服务器端发布和客户端调用。
一.java工程发布,java工程调用 (一).服务器端的编写 1.在eclipse里新建java project工程,创建功能类,通过关键字@webservice(name="newI ...
- 协程系列之Event Loops
Event Loops 事件循环 事件是由程序的一部分在特定条件下发出的消息,循环是在某种条件下完成并执行某个程序直到它完成的构造,因此,事件循环是一个循环,它允许用户订阅事件传输并注册处理程序/回调 ...
- 新版uni-app 在微信小工具调试遇到报错解决方案
问题描述:我在运行到微信小程序是运行报错打不开微信小程序报错如下图 结局方案:将微信小程序安全设置开启如下图
- CSS标签详解
CSS3标签 Css3概述 从2010年开始,HTML5与CSS3就一直是互联网技术中最受关注的两个话题.从前端技术的角度可以把互联网的发展分为三个阶段:第一阶段是web1.0以内容为主的网络,前端主 ...
- 黑马lavarel教程---5、模型操作(AR模式)
黑马lavarel教程---5.模型操作(AR模式) 一.总结 一句话总结: AR: ActiveRecord :Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型 ...
- web前端知识点反思总结
当别人问你之前的知识,我们便会勾起之前的回忆,然后进行一番痛苦的挣扎后,发现我依然记得你 什么是 DTD ? 文档类型定义 (DTD) 可定义合法的 xml 文档的构建模块 ,他是使用一系列合法的元素 ...
- find 命令详细解释
命令格式:find pathname -options [-print -exec -ok ...] 命令参数: pathname: find命令所查找的目录路径.例如用.来表示当前目录,用/来表示系 ...
- iOS即时通讯之CocoaAsyncSocket源码解析三
原文 前言 本文实例Github地址:即时通讯的数据粘包.断包处理实例. 本文旨以实例的方式,使用CocoaAsyncSocket这个框架进行数据封包和拆包.来解决频繁的数据发送下,导致的数据粘包.以 ...
- Visual Studio Code-Vscode下快速补全新建HTML文件默认代码
1.新建文件. 2.点击右下角文档格式:纯文本,上方弹出框输入HTML改成 html文档格式. 3.输入“ !”,按tab. 4.完成.
- linux 文件锁flock,lockf,fcntl
1.flock,lockf,fcntl之间区别 先上结论:flock是文件锁,锁的粒度是整个文件,就是说如果一个进程对一个文件加了LOCK_EX类型的锁,别的进程是不能对这个文件加锁的. lockf是 ...