官方的select不能接收更丰富的配置,这就需要适当改动即可。可以看我过去的相关文章,这个改动改动的地方比较多
首先,下载官方开发版的layui。
找到modules->form.js文件
定位到“初始渲染 select 组件选项”部分。
官方的做法是对option内的标签会进一步拆解,这就造成了看上去似乎能渲染但是会有很多重复的选项,此外,option标签内理论上不应该再出现别的元素标签,在部分浏览器会自动过滤掉这些标签,因此代码部分还应当是转义过的文本。
js代码如下
/**
* form 表单组件
*/
layui.define(['lay', 'layer', 'util'], function(exports){
"use strict";
var $ = layui.$;
var layer = layui.layer;
var util = layui.util;
var hint = layui.hint();
var device = layui.device();
var needCheckboxFallback = lay.ie && parseFloat(lay.ie) === 8;
var MOD_NAME = 'form';
var ELEM = '.layui-form';
var THIS = 'layui-this';
var SHOW = 'layui-show';
var HIDE = 'layui-hide';
var DISABLED = 'layui-disabled';
var OUT_OF_RANGE = 'layui-input-number-out-of-range';
var BAD_INPUT = 'layui-input-number-invalid';
var Form = function(){
this.config = {
// 内置的验证规则
verify: {
required: function(value) {
if (!/[\S]+/.test(value) || value === undefined || value === null) {
return '必填项不能为空';
}
},
phone: function(value) {
var EXP = /^1\d{10}$/;
if (value && !EXP.test(value)) {
return '手机号格式不正确';
}
},
email: function(value) {
var EXP = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
if (value && !EXP.test(value)) {
return '邮箱格式不正确';
}
},
url: function(value) {
var EXP = /^(#|(http(s?)):\/\/|\/\/)[^\s]+\.[^\s]+$/;
if (value && !EXP.test(value)) {
return '链接格式不正确';
}
},
number: function(value){
if (value && isNaN(value)) {
return '只能填写数字';
}
},
date: function(value){
var EXP = /^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/;
if (value && !EXP.test(value)) {
return '日期格式不正确';
}
},
identity: function(value) {
var EXP = /(^\d{15}$)|(^\d{17}(x|X|\d)$)/;
if (value && !EXP.test(value)) {
return '身份证号格式不正确';
}
}
},
autocomplete: null // 全局 autocomplete 状态。 null 表示不干预
};
};
// 全局设置
Form.prototype.set = function(options){
var that = this;
$.extend(true, that.config, options);
return that;
};
// 验证规则设定
Form.prototype.verify = function(settings){
var that = this;
$.extend(true, that.config.verify, settings);
return that;
};
// 获取指定表单对象
Form.prototype.getFormElem = function(filter){
return $(ELEM + function(){
return filter ? ('[lay-filter="' + filter +'"]') : '';
}());
};
// 表单事件
Form.prototype.on = function(events, callback){
return layui.onevent.call(this, MOD_NAME, events, callback);
};
// 赋值/取值
Form.prototype.val = function(filter, object){
var that = this
,formElem = that.getFormElem(filter);
// 遍历
formElem.each(function(index, item){
var itemForm = $(this);
// 赋值
for(var key in object){
if(!lay.hasOwn(object, key)) continue;
var type;
var value = object[key];
var itemElem = itemForm.find('[name="'+ key +'"]');
// 如果对应的表单不存在,则不执行
if(!itemElem[0]) continue;
type = itemElem[0].type;
// 如果为复选框
if(type === 'checkbox'){
itemElem[0].checked = value;
} else if(type === 'radio') {
// 如果为单选框
itemElem.each(function(){
this.checked = this.value == value + '';
});
} else {
// 其它类型的表单
itemElem.val(value);
}
};
});
form.render(null, filter);
// 返回值
return that.getValue(filter);
};
// 取值
Form.prototype.getValue = function(filter, itemForm){
itemForm = itemForm || this.getFormElem(filter);
var nameIndex = {
} // 数组 name 索引
,field = {
}
,fieldElem = itemForm.find('input,select,textarea') // 获取所有表单域
layui.each(fieldElem, function(_, item){
var othis = $(this)
,init_name; // 初始 name
item.name = (item.name || '').replace(/^\s*|\s*&/, '');
if(!item.name) return;
// 用于支持数组 name
if(/^.*\[\]$/.test(item.name)){
var key = item.name.match(/^(.*)\[\]$/g)[0];
nameIndex[key] = nameIndex[key] | 0;
init_name = item.name.replace(/^(.*)\[\]$/, '$1['+ (nameIndex[key]++) +']');
}
if(/^(checkbox|radio)$/.test(item.type) && !item.checked) return; // 复选框和单选框未选中,不记录字段
// select 多选用 jQuery 方式取值,未选中 option 时,
// jQuery v2.2.4 及以下版本返回 null,以上(3.x) 返回 []。
// 统一规范化为 [],参考 https://github.com/jquery/jquery/issues/2562
field[init_name || item.name] = (this.tagName === 'SELECT' && typeof this.getAttribute('multiple') === 'string')
? othis.val() || []
: this.value;
});
return field;
};
// 表单控件渲染
Form.prototype.render = function(type, filter){
var that = this;
var options = that.config;
var elemForm = $(ELEM + function(){
return filter ? ('[lay-filter="' + filter +'"]') : '';
}());
var items = {
// 输入框
input: function(elem){
var inputs = elem || elemForm.find('input,textarea');
// 初始化全局的 autocomplete
options.autocomplete && inputs.attr('autocomplete', options.autocomplete);
var handleInputNumber = function(elem, eventType){
var that = this;
var rawValue = elem.val();
var value = Number(rawValue);
var step = Number(elem.attr('step')) || 1; // 加减的数字间隔
var min = Number(elem.attr('min'));
var max = Number(elem.attr('max'));
var precision = Number(elem.attr('lay-precision'));
var noAction = eventType !== 'click' && rawValue === ''; // 初始渲染和失焦时空值不作处理
var isInit = eventType === 'init';
var isBadInput = isNaN(value);
var isStepStrictly = typeof elem.attr('lay-step-strictly') === 'string';
elem.toggleClass(BAD_INPUT, isBadInput);
if(isBadInput) return; // 若非数字,则不作处理
if(eventType === 'click'){
// 兼容旧版行为,2.10 以前 readonly 不禁用控制按钮
if(elem[0].type === 'text' && typeof elem.attr('readonly') === 'string') return;
var isDecrement = !!$(that).index() // 0: icon-up, 1: icon-down
value = isDecrement ? value - step : value + step;
}
// 获取小数点后位数
var decimals = function(step){
var decimals = (step.toString().match(/\.(\d+$)/) || [])[1] || '';
return decimals.length;
};
precision = precision >= 0 ? precision : Math.max(decimals(step), decimals(rawValue));
// 赋值
if (!noAction) {
// 初始渲染时只处理数字精度
if (!isInit) {
if(isStepStrictly){
value = Math.round(value / step) * step;
}
if(value <= min) value = min;
if(value >= max) value = max;
}
// 若 `lay-precision` 为 0, 则表示只保留整数
if (precision === 0) {
value = parseInt(value);
} else if(precision > 0) {
// 小数位精度
value = value.toFixed(precision);
}
elem.val(value);
elem.attr('lay-input-mirror', elem.val())
}
// 超出范围的样式
var outOfRange = value < min || value > max;
elem[outOfRange && !noAction ? 'addClass' : 'removeClass'](OUT_OF_RANGE);
if(isInit) return;
// 更新按钮状态
var controlBtn = {
increment: elem.next().find('.layui-icon-up'),
decrement: elem.next().find('.layui-icon-down')
}
controlBtn.increment[(value >= max && !noAction) ? 'addClass' : 'removeClass'](DISABLED)
controlBtn.decrement[(value <= min && !noAction) ? 'addClass' : 'removeClass'](DISABLED)
}
// 初始化输入框动态点缀
elemForm.find('input[lay-affix],textarea[lay-affix]').each(function(){
var othis = $(this);
var affix = othis.attr('lay-affix');
var CLASS_WRAP = 'layui-input-wrap';
var CLASS_SUFFIX = 'layui-input-suffix';
var CLASS_AFFIX = 'layui-input-affix';
var disabled = othis.is('[disabled]') || othis.is('[readonly]');
// 根据是否空值来显示或隐藏元素
var showAffix = function(elem, value){
elem = $(elem);
if(!elem[0]) return;
elem[$.trim(value) ? 'removeClass' : 'addClass'](HIDE);
};
// 渲染动态点缀内容
var renderAffix = function(opts){
opts = $.extend({
}, (affixOptions[affix] || {
value: affix
}), opts, lay.options(othis[0]));
var elemAffix = $('<div class="'+ CLASS_AFFIX +'">');
var value = layui.isArray(opts.value) ? opts.value : [opts.value];
var elemIcon = $(function(){
var arr = [];
layui.each(value, function(i, item){
arr.push('<i class="layui-icon layui-icon-'+ item + (
opts.disabled ? (' '+ DISABLED) : ''
) +'"></i>');
});
return arr.join('');
}());
elemAffix.append(elemIcon); // 插入图标元素
// 追加 className
if(opts.split) elemAffix.addClass('layui-input-split');
if(opts.className) elemAffix.addClass(opts.className);
// 移除旧的元素
var hasElemAffix = othis.next('.'+ CLASS_AFFIX);
if(hasElemAffix[0]) hasElemAffix.remove();
// 是否在规定的容器中
if(!othis.parent().hasClass(CLASS_WRAP)){
othis.wrap('<div class="'+ CLASS_WRAP +'"></div>');
}
// 是否已经存在后缀元素
var hasElemSuffix = othis.next('.'+ CLASS_SUFFIX);
if(hasElemSuffix[0]){
hasElemAffix = hasElemSuffix.find('.'+ CLASS_AFFIX);
if(hasElemAffix[0]) hasElemAffix.remove();
hasElemSuffix.prepend(elemAffix);
othis.css('padding-right', function(){
var paddingRight = othis.closest('.layui-input-group')[0]
? 0
: hasElemSuffix.outerWidth();
return paddingRight + elemAffix.outerWidth()
});
} else {
elemAffix.addClass(CLASS_SUFFIX);
othis.after(elemAffix);
}
opts.show === 'auto' && showAffix(elemAffix, othis.val());
typeof opts.init === 'function' && opts.init.call(this, othis, opts);
// 输入事件
othis.on('input propertychange', function(){
var value = this.value;
opts.show === 'auto' && showAffix(elemAffix, value);
});
// 失去焦点事件
othis.on('blur', function(){
typeof opts.blur === 'function'

最低0.47元/天 解锁文章
1766

被折叠的 条评论
为什么被折叠?



