279 lines
7.5 KiB
JavaScript
279 lines
7.5 KiB
JavaScript
/*
|
|
* @version: 1.2
|
|
* @Author: tomato
|
|
* @Date: 2018-4-24 22:56:00
|
|
* @Last Modified by: tomato
|
|
* @Last Modified time: 2018-5-26 18:08:43
|
|
*/
|
|
//无限级下拉框
|
|
layui.define(['jquery', 'form'], function(exports){
|
|
var MOD_NAME = 'selectN';
|
|
var $ = layui.jquery;
|
|
var form = layui.form;
|
|
var obj = function(config){
|
|
//当前选中数据值名数据
|
|
this.selected =[];
|
|
//当前选中的值
|
|
this.values = [];
|
|
//当前选中的名
|
|
this.names = [];
|
|
//当前选中最后一个值
|
|
this.lastValue = '';
|
|
//当前选中最后一个值
|
|
this.lastName = '';
|
|
//是否已选
|
|
this.isSelected = false;
|
|
//初始化配置
|
|
this.config = {
|
|
//选择器id或class
|
|
elem: '',
|
|
//无限级分类数据
|
|
data: [],
|
|
//默认选中值
|
|
selected: [],
|
|
//空值项提示,可设置为数组['请选择省','请选择市','请选择县']
|
|
tips: '请选择',
|
|
//是否允许搜索,可设置为数组[true,true,true]
|
|
search:false,
|
|
//选择项宽度,可设置为数组['80','90','100']
|
|
width:null,
|
|
//为真只取最后一个值
|
|
last: false,
|
|
//值验证,与lay-verify一致
|
|
verify: '',
|
|
//事件过滤器,lay-filter名
|
|
filter: '',
|
|
//input的name 不设置与选择器相同(去#.)
|
|
name: '',
|
|
//数据分隔符
|
|
delimiter: ',',
|
|
//数据的键名 status=0为禁用状态
|
|
field:{idName:'id',titleName:'name',statusName:'status',childName:'children'},
|
|
//多表单区分 form.render(type, filter); 为class="layui-form" 所在元素的 lay-filter="" 的值
|
|
formFilter: null
|
|
}
|
|
|
|
//实例化配置
|
|
this.config = $.extend(this.config,config);
|
|
|
|
//“请选择”文字
|
|
this.setTips = function(){
|
|
var o = this,c = o.config;
|
|
if(Object.prototype.toString.call(c.tips)!='[object Array]'){
|
|
return c.tips;
|
|
}
|
|
else{
|
|
var i=$(c.elem).find('select').length;
|
|
return c.tips.hasOwnProperty(i) ? c.tips[i] : '请选择';
|
|
}
|
|
}
|
|
|
|
//设置是否允许搜索
|
|
this.setSearch = function(){
|
|
var o = this,c = o.config;
|
|
if(Object.prototype.toString.call(c.search)!='[object Array]'){
|
|
return c.search===true ? 'lay-search ' : ' ';
|
|
}
|
|
else{
|
|
var i=$(c.elem).find('select').length;
|
|
if(c.search.hasOwnProperty(i)){
|
|
return c.search[i]===true ? 'lay-search ' : ' ';
|
|
}
|
|
}
|
|
return ' ';
|
|
}
|
|
|
|
//设置是否允许搜索
|
|
this.setWidth = function(){
|
|
var o = this,c = o.config;
|
|
if(Object.prototype.toString.call(c.width)!='[object Array]'){
|
|
return /^\d+$/.test(c.width) ? 'style="width:'+c.width+'px;" ' : ' ';
|
|
}
|
|
else{
|
|
var i=$(c.elem).find('select').length;
|
|
if(c.width.hasOwnProperty(i)){
|
|
return /^\d+$/.test(c.width[i]) ? 'style="width:'+c.width[i]+'px;" ' : ' ';
|
|
}
|
|
}
|
|
}
|
|
|
|
//创建一个Select
|
|
this.createSelect = function(optionData){
|
|
var o = this,c = o.config,f=c.field;
|
|
var html = '';
|
|
html+= '<div class="layui-input-inline" '+o.setWidth()+'>';
|
|
html+= ' <select '+o.setSearch()+'lay-filter="'+c.filter+'">';
|
|
html+= ' <option value="">'+o.setTips()+'</option>';
|
|
for(var i=0;i<optionData.length;i++){
|
|
var disabled = optionData[i][f.statusName]==0 ? 'disabled="" ' : '';
|
|
html+= ' <option '+disabled+'value="'+optionData[i][f.idName]+'">'+optionData[i][f.titleName]+'</option>';
|
|
}
|
|
html+= ' </select>';
|
|
html+= '</div>';
|
|
return html;
|
|
};
|
|
|
|
//获取当前option的数据
|
|
this.getOptionData=function(catData,optionIndex){
|
|
var f = this.config.field;
|
|
var item = catData;
|
|
for(var i=0;i<optionIndex.length;i++){
|
|
if('undefined' == typeof item[optionIndex[i]]){
|
|
item = null;
|
|
break;
|
|
}
|
|
else if('undefined' == typeof item[optionIndex[i]][f.childName]){
|
|
item = null;
|
|
break;
|
|
}
|
|
else{
|
|
item = item[optionIndex[i]][f.childName];
|
|
}
|
|
}
|
|
return item;
|
|
};
|
|
|
|
//初始化
|
|
this.set = function(selected){
|
|
var o = this,c = o.config;
|
|
$E = $(c.elem);
|
|
//创建顶级select
|
|
var verify = c.verify=='' ? '' : 'lay-verify="'+c.verify+'" ';
|
|
var html = '<div style="height:0px;width:0px;overflow:hidden"><input '+verify+'name="'+c.name+'"></div>';
|
|
html += o.createSelect(c.data);
|
|
$E.html(html);
|
|
selected = typeof selected=='undefined' ? c.selected : selected;
|
|
var index=[];
|
|
for(var i=0;i<selected.length;i++){
|
|
//设置最后一个select的选中值
|
|
$E.find('select:last').val(selected[i]);
|
|
//获取该选中值的索引
|
|
var lastIndex = $E.find('select:last').get(0).selectedIndex-1;
|
|
index.push(lastIndex);
|
|
//取出下级的选项值
|
|
var childItem = o.getOptionData(c.data,index);
|
|
//下级选项值存在则创建select
|
|
if(childItem){
|
|
var html = o.createSelect(childItem);
|
|
$E.append(html);
|
|
}
|
|
}
|
|
form.render('select',c.formFilter);
|
|
o.getSelected();
|
|
};
|
|
|
|
//下拉事件
|
|
this.change = function(elem){
|
|
var o = this,c = o.config;
|
|
var $thisItem = elem.parent();
|
|
//移除后面的select
|
|
$thisItem.nextAll('div.layui-input-inline').remove();
|
|
var index=[];
|
|
//获取所有select,取出选中项的值和索引
|
|
$thisItem.parent().find('select').each(function(){
|
|
index.push($(this).get(0).selectedIndex-1);
|
|
});
|
|
|
|
var childItem = o.getOptionData(c.data,index);
|
|
if(childItem){
|
|
var html = o.createSelect(childItem);
|
|
$thisItem.after(html);
|
|
form.render('select',c.formFilter);
|
|
}
|
|
o.getSelected();
|
|
};
|
|
|
|
//获取所有值-数组 每次选择后执行
|
|
this.getSelected=function(){
|
|
var o = this,c = o.config;
|
|
var values =[];
|
|
var names =[];
|
|
var selected =[];
|
|
$E = $(c.elem);
|
|
$E.find('select').each(function(){
|
|
var item = {};
|
|
var v = $(this).val()
|
|
var n = $(this).find('option:selected').text();
|
|
item.value = v;
|
|
item.name = n;
|
|
values.push(v);
|
|
names.push(n);
|
|
selected.push(item);
|
|
});
|
|
o.selected =selected;
|
|
o.values = values;
|
|
o.names = names;
|
|
o.lastValue = $E.find('select:last').val();
|
|
o.lastName = $E.find('option:selected:last').text();
|
|
|
|
o.isSelected = o.lastValue=='' ? false : true;
|
|
var inputVal = c.last===true ? o.lastValue : o.values.join(c.delimiter);
|
|
$E.find('input[name="'+c.name+'"]').val(inputVal);
|
|
};
|
|
//ajax方式获取候选数据
|
|
this.getData = function(url){
|
|
var d;
|
|
$.ajax({
|
|
url:url,
|
|
dataType:'json',
|
|
async:false,
|
|
success:function(json){
|
|
d=json;
|
|
},
|
|
error: function(){
|
|
console.error(MOD_NAME+' hint:候选数据ajax请求错误 ');
|
|
d = false;
|
|
}
|
|
});
|
|
return d;
|
|
}
|
|
|
|
|
|
};
|
|
|
|
//渲染一个实例
|
|
obj.prototype.render = function(){
|
|
var o=this,c=o.config;
|
|
$E = $(c.elem);
|
|
if($E.length==0){
|
|
console.error(MOD_NAME+' hint:找不到容器 '+c.elem);
|
|
return false;
|
|
}
|
|
if(Object.prototype.toString.call(c.data)!='[object Array]'){
|
|
var data = o.getData(c.data);
|
|
if(data===false){
|
|
console.error(MOD_NAME+' hint:缺少分类数据');
|
|
return false;
|
|
}
|
|
o.config.data = data;
|
|
}
|
|
|
|
c.filter = c.filter=='' ? c.elem.replace('#','').replace('.','') : c.filter;
|
|
c.name = c.name=='' ? c.elem.replace('#','').replace('.','') : c.name;
|
|
o.config = c;
|
|
|
|
//初始化
|
|
o.set();
|
|
|
|
//监听下拉事件
|
|
form.on('select('+c.filter+')',function(data){
|
|
o.change($(data.elem));
|
|
});
|
|
//验证失败样式
|
|
$E.find('input[name="'+c.name+'"]').focus(function(){
|
|
var t = $(c.elem).offset().top;
|
|
$('html,body').scrollTop(t-200);
|
|
$(c.elem).find('select:last').addClass('layui-form-danger');
|
|
setTimeout(function(){
|
|
$(c.elem).find('select:last').removeClass('layui-form-danger');
|
|
},3000);
|
|
});
|
|
}
|
|
|
|
//输出模块
|
|
exports(MOD_NAME, function (config) {
|
|
var _this = new obj(config);
|
|
_this.render();
|
|
return _this;
|
|
});
|
|
}); |