背景:layui 已经停更了。但公司还在用。默认的下拉框是不能输入的,因为项目要求,需要让下拉框可以输入自定义值。
虽然有些小瑕疵,但个人比较满意。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>可输入的下拉框(允许输入非选项值)</title>
<link rel="stylesheet" href="../../libs/layui/layui-2.4.5/dist/css/layui.css">
<script src="../../libs//layui/layui-2.4.5/dist/layui.js"></script>
<style>
</style>
</head>
<body style="margin: 10px;">
<form class="layui-form" action="" id="formWindow">
<div class="layui-form-item">
<label class="layui-form-label">姓名:</label>
<div class="layui-input-inline">
<input name="xm" class="layui-input" lay-verify="" placeholder="请输入姓名">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">列车</label>
<div class="layui-input-block" style="width: 200px;">
<!-- 用于编辑时回填信息-->
<!-- <input id="jylc_default" type="hidden" value="${item.jylc}"> -->
<select id="jylc" name="jylc" class="layui-input" lay-verify="required" placeholder="请输入列车"
lay-search>
<option value="">请选择</option>
<option value="动车-1">动车-1</option>
<option value="高铁-2">高铁-2</option>
<option value="普快-3">普快-3</option>
</select>
</div>
</div>
<div class="layerBtnCenter btn-box btn-box-1">
<button type="button" class="layui-btn" lay-filter="submitBtnAdd" lay-submit id="saveBtn"><i
class="iconfont"></i>取值
</button>
<button type="button" class="layui-btn btn-close" type="reset" id="reset"><i class="iconfont"></i>重置
</button>
</div>
</form>
<div>
<h1>-------------------------------------</h1>
<span>原生下拉框</span>
<select placeholder="请输入救援列车" lay-search>
<option value="">请选择</option>
<option value="鹰潭机务段">鹰潭机务段-1</option>
<option value="福州机务段">福州机务段-2</option>
<option value="向塘机务段">向塘机务段-3</option>
</select>
</div>
<script>
/**
* @note 可编辑下拉框
* @author jiangxu
*/
class EditableCombobox {
constructor(layuiId, $) {
this.layuiId = layuiId;
this._$ = $;
this.invaildTagNameOfDD = "id_" + this.layuiId + "_dd";
this.invaildTagNameOfOption = "id_" + this.layuiId + "_option";
this.invalidValue_DataKey = "data-" + this.layuiId;
this.defaultValue4InvalidTag = "#"
this.textObj = this._$(this._$("#" + this.layuiId).next()[0].children[0]);
this.selectObj = this._$(this._$("#" + this.layuiId).next()[0].children[1]);
this.defaultValueObj = this._$("#" + this.layuiId + "_default");
this.init();
this.putDefaultValue();
}
/**
* 用于编辑时回填信息
*/
putDefaultValue() {
/**
* 处于编辑界面时,下拉框会被预填入值的。此时需要处理显示【非法值的问题】
* 在页面加载完毕时触发
*/
//获取实际值
if (!this.defaultValueObj) {
return;
}
var value_default = this.defaultValueObj.val();
if (value_default == undefined || value_default == '' || value_default == null) {
return;
}
//如果是已知的值,就忽略;如果不是,需要追加 非法信息
var arrValue = this.getValidValues();
if (arrValue.indexOf(value_default) >= 0) {
return;
}
console.log(value_default, arrValue);
this._$("#" + this.layuiId).val(value_default);
this.textObj.find('input').val(value_default);
}
init() {
// var inputStr = "";
var that = this;
this.textObj.on('keyup', function (v) {
that.appendInfoTag4InvalidValue();
});
/**
* 对已有的下拉框值 提前绑定 click 事件。
* 如果点击了已有值,则需要提前清楚【非法值】
*/
this.selectObj.find("dd").on('click', function (v) {
//清除预存 非法值
that._$("#" + that.layuiId).data(that.invalidValue_DataKey, "");
//清除非法值的 dom
// console.log($("#"+layuiId).data("jylc-data"));
// console.log($(this).html())
// 删除之前的 非法的option 的dom
if (that._$("#" + that.invaildTagNameOfOption)) {
that._$("#" + that.invaildTagNameOfOption).remove();
that._$("#" + that.invaildTagNameOfDD).remove();
}
});
}
/**
* 获取有效值集合
*/
getValidValues() {
var values = [];
var that = this;
this._$("#" + this.layuiId).find("option").each(function (index) {
// console.log(that._$(this));
var v = that._$(this).attr("value");
if (v != undefined && v != null && v != '') {
values.push(v);
}
})
return values;
}
/**
* 根据【非法值】追加标签信息
*/
appendInfoTag4InvalidValue() {
var inputStr = this.textObj.find('input').val();
this._$("#" + this.layuiId).data(this.invalidValue_DataKey, inputStr);
// 删除之前的 非法的option 的dom
if (this._$("#" + this.invaildTagNameOfOption)) {
this._$("#" + this.invaildTagNameOfOption).remove();
this._$("#" + this.invaildTagNameOfDD).remove();
}
this._$("#" + this.layuiId).append('<option id="' + this.invaildTagNameOfOption + '" value="' + this.defaultValue4InvalidTag + '" selected>' + inputStr + '</option>')
//先移除内部的 class="layui-this"
this.selectObj.find(".layui-this").removeClass("layui-this");
this.selectObj.append('<dd id="' + this.invaildTagNameOfDD + '" class="layui-this" lay-value="' + this.defaultValue4InvalidTag + '" >' + inputStr + '(未定义)</dd>');
this.textObj.val(this.defaultValue4InvalidTag);
}
getValue() {
var name = this._$("#" + this.layuiId).attr('name');
var value = this._$("#" + this.layuiId).val();
if (value == this.defaultValue4InvalidTag) {
value = this._$("#" + this.layuiId).data(this.invalidValue_DataKey);
}
// var formData = {};
// formData[name] = value;
return value;
}
}
layui.use(['jquery', 'layer', 'form', 'table', 'laydate', 'util', 'upload', 'element'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var laydate = layui.laydate;
var element = layui.element;
var table = layui.table;
var util = layui.util;
var layerWindow;
var upload = layui.upload;
var serializeFormToObject = function (formSelector) {
var formData = {};
formSelector.find(':input[name]').each(function () {
var name = $(this).attr('name');
var value = $(this).val();
if ($(this).is('select')) {
value = $(this).find('option:selected').val();
}
formData[name] = value;
});
// var jsonData = JSON.stringify(formData);
return formData;
};
var jxCombobox = new EditableCombobox("jylc", $);
// jxCombobox.init()
form.on('submit(submitBtnAdd)', function (data) {
var datas = data.field;
var dataString = JSON.stringify(datas);
console.log(dataString);
// var ds = serializeFormToObject($("#formWindow"));
// console.log(JSON.stringify(ds));
console.log(jxCombobox.getValue());
});
// $("#reset").click(() => {
// // debugger
// var t = $($("#"+layuiId).next()[0].children[0]).find(":input");
// var v = t.val();
// setTimeout(function () {
// t.val(v);
// }, 100)
// })
});
</script>
</body>
</html>
用vscode 打开,启动简易web 服务(Live server),
预览
然后随便输入个非法值,可以看到后端能够获取到1111。
同时,也看到了小瑕疵,就是form表单提交时,值是 #,需要你手动获取自定义控件的值,去涂改下。