基于jq + mui 实现, 和框架没有关系. 分享一个思路
0. 后端返回的json数据
在开始看代码之前, 先看看一下后端返回的json数据
[
{
apiParamsName: "", //input的name属性
disabled: false,
id: "",
properties: {
id: "",
subType: "TEXT", //和外层的type拼接确认类型
placeholder: "请输入单行文本", //输入提示
defaultValue: "测试" //默认值
},
readonly: false,
required: false, //是否必填
title: "单行文本", //元素的名称
type: "TEXT",
},
....
]
1. 创建一个InputBase基类
import { toast } from "./../../../plugIn/toast/toast.js";
class InputBase {
input;
//返回input名称的方法
getKey(){
let thah = this;
return thah.input.apiParamsName;
}
//获取值得方法, 有些input的值需要特殊处理
getValue(){
let thah = this;
return $(`input[name='${thah.input.apiParamsName}']`).val();
}
//返回dom元素的方法
returnHtml() { };
//注册dom元素的点击事件的方法
formEvents() { };
//dom元素的执行的方法
formEventsAction() { };
//验证方法
verification() {
let input = this.input;
return this.verificationAction({ input: input });
};
//验证的执行方法
verificationAction({ bool = true, input }) {
if (!input.required) {
return true;
}
let value = $(`input[name='${input.apiParamsName}']`).val();
if (!value) {
toast(`${bool ? '请选择' : '请输入'}${input.title}`);
return false;
}
return true;
};
//接受值和返回dom元素
createInput(inputPojo) {
this.input = inputPojo;
let html = this.returnHtml(inputPojo);
return html;
};
}
export default InputBase;
2. 根据一些input的特征, 在抽象出几个基类
2.1 CheckboxBase, 多选和单选的基类
import InputBase from "./../formModeBase/inputBase.js";
class CheckboxBase extends InputBase {
//重写的返回值的方法, 更具业务要求改写
getValue(){
let value = $(`input[name=${this.input.apiParamsName}]`).val();
if (value.length == 0){
return JSON.stringify([]);
}
var values = value.split(',');
return JSON.stringify(values);
}
//两个Input ,一个显示选中的中文值并绑定点击事件. 一个保存选中的值.
returnHtml() {
let input = this.input;
return `<div class="mui-input-row">
<label>${input.title}</label>
<input type="text" readonly
name="${input.apiParamsName}Text"
id="${input.apiParamsName}Text"
class="mui-input-clear"
placeholder="${input.placeholder ?? "请选择"}">
<input type="hidden" readonly
id="${input.apiParamsName}"
name="${input.apiParamsName}">
</div>`;
};
//单选和多选的事件绑定方法
formEvents() {
let thah = this;
$(`.mui-input-row`).on("click", `input[name=${this.input.apiParamsName}Text]`, function (e) {
thah.formEventsAction();//调用的执行方法
})
}
}
export default CheckboxBase;
还有几个基类, 篇幅原因, 就不一一列出来了
3. 创建具体的实现类
3.1 单选的具体实现类
import CheckboxBase from "./inputBase/CheckboxBase.js"
class SingChoice extends CheckboxBase {
getValue(){
return $(`input[name=${this.input.apiParamsName}]`).val();
}
//单选的点击事件需要初始化PopPicker, 不能用父类的formEvents
formEvents() {
let input = this.input;
var userPicker = new mui.PopPicker();
userPicker.setData(input.data);
var showUserPickerButton = document.getElementById(`${input.apiParamsName}Text`);
var userResult = document.getElementById(`${input.apiParamsName}`);
showUserPickerButton.addEventListener('tap', function (event) {
userPicker.show(function (items) {
$(userResult).val(items[0].value);
$(showUserPickerButton).val(items[0].text);
});
}, false);
}
createInput(input) {
//data需要特殊处理
let data = input.data;
let options = JSON.parse(data);
input.data = [];
options.forEach((item, index) => {
input.data.push({
text: item.label,
value: item.value
});
})
//调用父类的方法, 返回dom
return super.createInput(input);
}
}
export { SingChoice };
4. 使用
4.1 将实现类都放到map
import { Text as createText } from "./formMode/text.js";
import { SingChoice as createRadio } from "./formMode/singleChoice.js";
import { Date as createDate } from "./formMode/date.js";
import { Money as createMoney } from "./formMode/money.js";
import { UserList as createUserList } from "./formMode/userList.js";
import { Checkbox as createCheckbox } from "./formMode/checkbox.js";
import { Department as createDepartment } from "./formMode/department.js";
import { Textarea as createTextarea } from "./formMode/textarea.js";
import { Quoteform as createQuoteform } from "./formMode/quoteform.js";
import { UpFile as createUpFile } from "./formMode/upFile.js";
import { Timerange as createTimerange } from "./formMode/timerange.js";
var modelMap = new Map();
modelMap.set("TEXT.TEXT", new createText());
modelMap.set("NUMBER.COMMON", new createText());
modelMap.set("SELECT.RADIO", new createRadio());//单选
modelMap.set("DATEPICKER.DATE", new createDate());//时间选择
modelMap.set("DATEPICKER.DATETIME", new createDate());//日期+时间
modelMap.set("NUMBER.MONEY", new createMoney());//钱
modelMap.set("QUOTE.QUOTEUSER", new createUserList());//用户
modelMap.set("SELECT.MULTIPLE", new createCheckbox());//多选
modelMap.set("QUOTE.QUOTEDEPARTMENT", new createDepartment());//选择部门
modelMap.set("TEXT.TEXTAREA", new createTextarea());
modelMap.set("TEXT.EXPLAIN", new createTextarea());
modelMap.set("QUOTE.QUOTEFORM", new createQuoteform());//选择部门
modelMap.set("FILE.", new createUpFile());
modelMap.set("DATEPICKER.TIMERANGE", new createTimerange());//时长
export const map = modelMap;
4.2 循环创建dom
inputList.forEach((item, index) => {
let inputType = `${item.type}.${item.properties.subType || ""}`;
let createDom = map.get(inputType);
if (createDom) {
let html = createDom.createInput({
maxSize: item.properties.maxSize,
number: item.properties.number,
defaultValue: inputType == 'QUOTE.QUOTEFORM' ? item.properties.quoteFormId : item.properties.defaultValue,
title: item.title,
placeholder: item.properties.placeholder || item.properties.buttonText,
required: item.required,
apiParamsName: item.apiParamsName,
type: item.type == "DATEPICKER" || item.properties.subType == "EXPLAIN" ? item.properties.subType.toLowerCase() : item.type,
data: item.properties.options
});
//添加到提交按钮前面
$("#submitFrom").before(html);
//绑定点击事件
createDom.formEvents();
//添加到集合里, 提交时调用验证方法
verifications.push(createDom);
}
});
inputPojo参数的解释, 代码里没有用到(我也是才发现的)
class InputPojo{
maxSize; //文件的最大size
number; //文件的格数
defaultValue; //默认值
title; //元素的名称
placeholder; //input的输入提示
apiParamsName = ""; //input的name元素
required; //是否必填
type = ""; //input的type
data; //多选框的数据
}
export default InputPojo;