问题
使用layui做了一段时间的项目了,实现了一个这样的功能:根据需要手动增加布局。包括编辑,重置之类,把开发中遇到的问题,以及解决方法记录一下。实现效果如下:
问题1:怎么手动增加布局,删除布局
其实很简单,使用html布局,添加到指定布局中,有一种简单写法,使用es6方式,可以在布局中先写一个html,调整到结果符合需求,再单独拿出来,放到一个方法中,
在form布局中,定义一个div布局,需要增加的布局,放在这个div中
<div class="layui-form-item">
<div class="layui-row" style="text-align: center;">
<a id="addRecord" class="layui-btn">添加一个癌症信息</a>
</div>
</div>
<div id="dynamic-table"></div>
新增状态下,前台设置一个对象,字段值为空,
$("#addRecord").click(function () {
var newData = {
cancerTypes:"",
planingCoding:"",
morphologicalCoding: "",
behavioralCoding: "",
cd03: "",
icd10: "",
onsetDate: "",
diagnosticBasis:"",
clinicalTnm: "",
pathologyTnm:"",
outpatientNumber: "",
inpatientNumber: "",
diagnosticUnit: "",
reportingUnit: "",
reportingDate: "",
reportingDoctor: "",
}
mkLesionsHtml(newData);
});
从列表项,点击编辑,进入本页面,根据id从后台获取数据
let aData = [[${data}]];
if (aData) {
edit(aData);
setCheckBoxValues(aData.followupMode,"followupMode");
setCheckBoxValues(aData.followupInformation,"followupInformation");
setCheckBoxValues(aData.treatmentProgram,"treatmentProgram");
loadDatas(aData);
}
function loadDatas(aData){
idRecord=1;
var id=""
if(aData!=null){
id=aData.id
}
$.ajax({
type: "GET",
url: _CONTEXT_PATH +'mg/breast/xxxx/' + id,
error: function (errorRes) {
layer.msg(errorRes.responseText, function () {});
},
success: function (responseData) {
for (var k in responseData.body) {
mkLesionsHtml(responseData.body[k]);
}
}
});
}
需要手动增加页面的布局代码
//添加信息记录表
function mkLesionsHtml(d) {
let html = ` <fieldset id="dynamic-line-${idRecord}" class="layui-elem-field" id="cancelInfoDiv1" >
<legend>癌症信息${idRecord}</legend>
<div class="layui-form-item" style="margin-left: 1rem;">
<div class="layui-inline upDown">
<label class="layui-form-label">1.癌症种类:</label>
<div class="layui-input-block">
<input type="radio" name="cancerTypes${idRecord}" lay-filter="cancerTypes"
lay-verify="otherReq" lay-verType="tips" value="0"
title="ICD-O-3编码" >
<input type="radio" name="cancerTypes${idRecord}" lay-filter="cancerTypes"
lay-verify="otherReq" lay-verType="tips" value="1"
title="ICD-10编码">
</div>
</div>
<div id="checkICDO3${idRecord}" style="display:none;">
<div class="layui-form-item">
<div class="layui-inline upDown">
<label class="layui-form-label">解剖学编码:</label>
<div class="layui-input-block">
<input type="text" name="planingCoding${idRecord}" id="planingCoding${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
<div class="layui-inline upDown">
<label class="layui-form-label">形态学编码:</label>
<div class="layui-input-block">
<input type="text" name="morphologicalCoding${idRecord}" id="morphologicalCoding${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
<div class="layui-inline upDown">
<label class="layui-form-label">行为学编码:</label>
<div class="layui-input-block">
<input type="text" name="behavioralCoding${idRecord}" id="behavioralCoding${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
<div class="layui-inline upDown">
<label class="layui-form-label">分级:</label>
<div class="layui-input-block">
<input type="text" name="cd03${idRecord}" id="cd03${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
</div>
</div>
<div id="checkICD10${idRecord}" style="display:none;">
<div class="layui-form-item">
<div class="layui-inline upDown">
<label class="layui-form-label">ICD-10编码:</label>
<div class="layui-input-block">
<input type="text" name="icd10${idRecord}" id="icd10${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
</div>
</div>
</div>
<div class="layui-form-item" style="margin-left: 1rem;">
<div class="layui-inline upDown">
<label class="layui-form-label">2.发病日期:</label>
<div class="layui-input-block">
<input type="text" name="onsetDate${idRecord}" id="onsetDate${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
</div>
<div class="layui-form-item" style="margin-left: 1rem;">
<div class="layui-inline upDown">
<label class="layui-form-label">3.诊断依据:</label>
<div class="layui-input-block" id="search_checkbox">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="临床" value="0">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="X光" value="1">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="超声波" value="2">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="CT" value="3">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="内窥镜" value="4">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="免疫" value="5">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="生化" value="6">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="骨髓片" value="7">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="血片" value="8">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="细胞学" value="9">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="病理" value="10">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="不详" value="11">
<input type="checkbox" name="diagnosticBasis${idRecord}" lay-skin="primary" title="DCO" value="12">
</div>
</div>
</div>
<div class="layui-form-item" style="margin-left: 1rem;">
<div class="layui-inline upDown">
<label class="layui-form-label">4.确诊时病理分期TNM:</label>
<div class="layui-input-block" style="margin-left: 20px">
<input type="radio" name="pathologyTnm${idRecord}" lay-verType="tips" value="0"
title="0-I 期">
<input type="radio" name="pathologyTnm${idRecord}" lay-verType="tips" value="1"
title="II 期">
<input type="radio" name="pathologyTnm${idRecord}" lay-verType="tips"
value="2" title="III 期">
<input type="radio" name="pathologyTnm${idRecord}" lay-verType="tips" value="3"
title="IV 期">
<input type="radio" name="pathologyTnm${idRecord}" lay-verType="tips" value="4"
title="不详">
</div>
</div>
</div>
<div class="layui-form-item" style="margin-left: 1rem;">
<div class="layui-inline upDown">
<label class="layui-form-label">5.确诊时临床分期TNM:</label>
<div class="layui-input-block" style="margin-left: 20px">
<input type="radio" name="clinicalTnm${idRecord}" lay-verType="tips" value="0"
title="0-I 期">
<input type="radio" name="clinicalTnm${idRecord}" lay-verType="tips" value="1"
title="II 期">
<input type="radio" name="clinicalTnm${idRecord}" lay-verType="tips"
value="2" title="III 期">
<input type="radio" name="clinicalTnm${idRecord}" lay-verType="tips" value="3"
title="IV 期">
<input type="radio" name="clinicalTnm${idRecord}" lay-verType="tips" value="4"
title="不详">
</div>
</div>
</div>
<div class="layui-form-item" style="margin-left: 1rem;">
<div class="layui-inline upDown">
<label class="layui-form-label">6.门诊号:</label>
<div class="layui-input-block">
<input type="text" name="outpatientNumber${idRecord}" id="outpatientNumber${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
<div class="layui-inline upDown">
<label class="layui-form-label">住院号:</label>
<div class="layui-input-block">
<input type="text" name="inpatientNumber${idRecord}" id="inpatientNumber${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div class="layui-form-item" style="margin-left: 1rem;">
<div class="layui-inline upDown">
<label class="layui-form-label">7.诊断单位:</label>
<div class="layui-input-block">
<input type="text" name="diagnosticUnit${idRecord}" id="diagnosticUnit${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
<div class="layui-inline upDown">
<label class="layui-form-label">报告单位:</label>
<div class="layui-input-block">
<input type="text" name="reportingUnit${idRecord}" id="reportingUnit${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
</div>
<div class="layui-form-item" style="margin-left: 1rem;">
<div class="layui-inline upDown">
<label class="layui-form-label">8.报告日期:</label>
<div class="layui-input-block">
<input type="text" name="reportingDate${idRecord}" id="reportingDate${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
<div class="layui-inline upDown">
<label class="layui-form-label">报告医生:</label>
<div class="layui-input-block">
<input type="text" name="reportingDoctor${idRecord}" id="reportingDoctor${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" >
</div>
</div>
<div class="layui-form-item">
<div class="layui-row" style="text-align: center;">
<a id=${idRecord} class="layui-btn relation">删除</a>
</div>
</div>
</fieldset>`;
$('#dynamic-table').append(html);
/**
* 通过js赋值,直接通过value="${d.reportingDoctor}"之类赋值,重置的话,input不置空
*/
$("#planingCoding"+idRecord).val(d.planingCoding);
$("#morphologicalCoding"+idRecord).val(d.morphologicalCoding);
$("#behavioralCoding"+idRecord).val(d.behavioralCoding);
$("#cd03"+idRecord).val(d.cd03);
$("#icd10"+idRecord).val(d.icd10);
$("#onsetDate"+idRecord).val(d.onsetDate);
$("#outpatientNumber"+idRecord).val(d.outpatientNumber);
$("#inpatientNumber"+idRecord).val(d.inpatientNumber);
$("#diagnosticUnit"+idRecord).val(d.diagnosticUnit);
$("#reportingUnit"+idRecord).val(d.reportingUnit);
$("#reportingDate"+idRecord).val(d.reportingDate);
$("#reportingDoctor"+idRecord).val(d.reportingDoctor);
//给checkbox赋值
var unitType = [];
unitType = d.diagnosticBasis.split(",");
for (var j = 0; j < unitType.length; j++) {
var unitTypeCheckbox = $("input[name=diagnosticBasis"+idRecord+"]");
for (var i = 0; i < unitTypeCheckbox.length; i++) {
if (unitTypeCheckbox[i].value == unitType[j]) {
unitTypeCheckbox[i].checked = true;
}
}
}
//给radio赋值
if(d.cancerTypes!=''){
$("input[name=cancerTypes"+idRecord+"][value="+d.cancerTypes+"]").prop('checked','checked');
if (d.cancerTypes == 0) {
$("#checkICDO3"+idRecord).show();
$("#checkICD10"+idRecord).hide();
} else if(d.cancerTypes == 1){
$("#checkICDO3"+idRecord).hide();
$("#checkICD10"+idRecord).show();
}
}
if(d.pathologyTnm!=''){
$("input[name=pathologyTnm"+idRecord+"][value="+d.pathologyTnm+"]").prop('checked','checked');
}
if(d.clinicalTnm!=''){
$("input[name=clinicalTnm"+idRecord+"][value="+d.clinicalTnm+"]").prop('checked','checked');
}
//删除按钮
$(".relation").on("click", function () {
var id = $.trim($(this).attr("id"));
console.log("id:"+id)
$("#dynamic-line-" + id).remove();
});
laydate.render({
elem: '#onsetDate'+idRecord
});
laydate.render({
elem: '#reportingDate'+idRecord
});
idRecord++;
form.render();
}
具体怎么设计,怎么往后台传递数据,这个在前一篇文章中已经写了,就不重复了
列表手动增加删除列表行的实现–layui实现以及html实现
问题2.layui给radio和checkbox赋值
在提交数据之前,对checkbox进行取值,用","拼接
类似于这样
var followupModes ='';
$('#followupMode_checkbox input[type=checkbox]:checked').each(function() {
followupModes=followupModes+($(this).val())+","
});
field.followupMode=followupModes.substring(0, followupModes.length - 1);
布局代码是
<div class="layui-form-item">
<div class="layui-inline upDown">
<label class="layui-form-label">3.随访调查方法</label>
<div class="layui-input-block" id="followupMode_checkbox">
<input type="checkbox" name="followupMode" lay-skin="primary" title="面对面" value="0">
<input type="checkbox" name="followupMode" lay-skin="primary" title="电话询问" value="1">
<input type="checkbox" name="followupMode" lay-skin="primary" title="调查对象代理人(调查对象不能提供信息)" value="2">
<input type="checkbox" name="followupMode" lay-skin="primary" title="被动随访" value="3">
</div>
</div>
</div>
编辑的时候,根据后台数据,对checkbox赋值,代码
function setCheckBoxValues(value,name){
//给checkbox赋值
var unitType = [];
unitType = value.split(",");
for (var j = 0; j < unitType.length; j++) {
var unitTypeCheckbox =$("input[name="+name+"]");
for (var i = 0; i < unitTypeCheckbox.length; i++) {
if (unitTypeCheckbox[i].value == unitType[j]) {
unitTypeCheckbox[i].checked = true;
}
}
}
}
调用方法
if (aData) {
edit(aData);
setCheckBoxValues(aData.followupMode,"followupMode");
。。。。。。
}
对radio赋值就简单了
$("input[name=cancerTypes"+idRecord+"][value="+d.cancerTypes+"]").prop('checked','checked');
获取radio选中的值
var arr_box ='';
$('#search_checkbox input[type=checkbox]:checked').each(function() {
arr_box=arr_box+($(this).val())+","
});
arr_box=arr_box.substring(0, arr_box.length - 1);
var saveDataAry = [];
for (var i = 1; i < idRecord; i++) {
//没有被禁用i
if ($('#dynamic-line-' +i ).val() !=null) {
var cancerTypes="cancerTypes"+i;
var clinicalTnm="clinicalTnm"+i;
var pathologyTnm="pathologyTnm"+i;
var data = {
"cancerTypes":$("input[name="+ cancerTypes + "]:checked").val(),
"planingCoding": $("#planingCoding" + i).val(),
"morphologicalCoding": $('#morphologicalCoding' + i).val(),
"behavioralCoding": $('#behavioralCoding' + i).val(),
"cd03": $('#cd03' + i).val(),
"icd10": $('#icd10' + i).val(),
"onsetDate": $('#onsetDate' + i).val(),
"diagnosticBasis":arr_box,
"clinicalTnm": $("input[name="+ clinicalTnm + "]:checked").val(),
"pathologyTnm":$("input[name="+ pathologyTnm + "]:checked").val(),
"outpatientNumber": $('#outpatientNumber' + i).val(),
"inpatientNumber": $('#inpatientNumber' + i).val(),
"diagnosticUnit": $('#diagnosticUnit' + i).val(),
"reportingUnit": $('#reportingUnit' + i).val(),
"reportingDate": $('#reportingDate' + i).val(),
"reportingDoctor": $('#reportingDoctor' + i).val(),
};
saveDataAry.push(data)
}
}
field.params=JSON.stringify(saveDataAry);
其中
$("input[name="+ cancerTypes + "]:checked").val()
就是对于radio已选中的值
问题3.根据radio选择项,动态控制布局隐藏
可能有这样的需求,选择某一个单选项,会显示一个布局,选择另一个,会显示另一个布局。实现代码也不难
form.on('radio(followupState)', function (data) {
var value = $(this).val();
if ('1' == value) {
$("#checkDeath").show();
$("#checkMissing").hide();
} else if ('2' == value) {
$("#checkDeath").hide();
$("#checkMissing").show();
} else {
$("#checkDeath").hide();
$("#checkMissing").hide();
}
setHideViewNotRequired();
});
<div id="checkDeath" style="display:none;">
。。。。。
</div>
问题4.含有必填项的布局,隐藏情况下,怎么修改必填判断
有的需要动态显示布局,如果有的布局已经隐藏,但是含有必填项,点击提交的时候,会报错,需要填写,但是已经布局已经隐藏了,这样就有问题,其实解决办法也不难,就是遍历所有隐藏的布局,将lay-verify=‘otherReq’随便设置一个值,就相当于把必填判断设为无效了
function setHideViewNotRequired(){
$("#myForm div[style='display:none;']").each(function(){
var idEach = $(this).attr("id");
$("#"+ idEach + " :input").each(function(){
let verifyName = $(this).attr("lay-verify");
if(verifyName == "otherReq"){
verifyName = verifyName.replace("otherReq","otherReqNo");
$(this).attr("lay-verify",verifyName);
}
});
});
}
可以在进入页面的时候调用这个方法,可以在切换hide和show的时候调用
对应的div设置
<div class="layui-inline upDown" id="checkMissing" style="display:none;">
........
</div>
可以重新设置为必填
if ('2' == value) {
$("#checkDeath").hide();
$("#checkMissing :input").each(function(){
let verifyName = $(this).attr("lay-verify");
if(verifyName == "otherReqNo"){
verifyName = verifyName.replace("otherReqNo","otherReq");
$(this).attr("lay-verify",verifyName);
}
});
$("#checkMissing").show();
可以把代码单独提到一个方法里,注意点就是,不要在方法里直接用 $(this),这样有可能会出错,可能是 $(this)作用域的问题吧,借鉴之前微信小程序的写法,可以写成这样
//页面校验
function verifyCheck(verifyName,that){
if(verifyName == "otherReq"){
verifyName = verifyName.replace("otherReqNo","otherReq");
that.attr("lay-verify",verifyName);
}
if(verifyName == "required"){
verifyName = verifyName.replace("requiredNo","required");
that.attr("lay-verify",verifyName);
}
}
//页面不校验
function verifyCheckNo(verifyName,that){
if(verifyName == "otherReq"){
verifyName = verifyName.replace("otherReq","otherReqNo");
that.attr("lay-verify",verifyName);
}
if(verifyName == "required"){
verifyName = verifyName.replace("required","requiredNo");
that.attr("lay-verify",verifyName);
}
}
调用
$("#myForm div[style='display: none;']").each(function(){
console.log("id:"+ $(this).attr("id"))
var idEach = $(this).attr("id");
$("#"+ idEach + " :input").each(function(){
let verifyName = $(this).attr("lay-verify");
verifyCheckNo(verifyName, $(this));
/* if(verifyName == "otherReq"){
verifyName = verifyName.replace("otherReq","otherReqNo");
$(this).attr("lay-verify",verifyName);
}*/
});
});
form.on('radio(followupState)', function (data) {
var value = $(this).val();
if ('1' == value) {
$("#checkDeath").show();
$("#checkMissing").hide();
setHideViewNotRequired();
} else if ('2' == value) {
$("#checkDeath").hide();
$("#checkMissing").show();
$("#checkMissing :input").each(function(){
let verifyName = $(this).attr("lay-verify");/*
if(verifyName == "otherReqNo"){
verifyName = verifyName.replace("otherReqNo","otherReq");
$(this).attr("lay-verify",verifyName);
}*/
verifyCheck(verifyName,$(this))
});
} else {
$("#checkDeath").hide();
$("#checkMissing").hide();
setHideViewNotRequired();
}
});
问题5.点击重置按钮,input不置空
自己手动写的html中的input,在点击重置按钮的时候,没有置空,原因应该是,代码中加入了value=后台字段值,类似于这样
<input type="text" name="outpatientNumber${idRecord}" id="outpatientNumber${idRecord}" lay-verType="tips"
autocomplete="off" class="layui-input" value="${d.outpatientNumber}">
value="${d.outpatientNumber}",这样的话,重置的时候,没办法置空,解决办法就是使用js赋值
/**
* 通过js赋值,直接通过value="${d.reportingDoctor}"之类赋值,重置的话,input不置空
*/
$("#planingCoding"+idRecord).val(d.planingCoding);
$("#morphologicalCoding"+idRecord).val(d.morphologicalCoding);
$("#behavioralCoding"+idRecord).val(d.behavioralCoding);
$("#cd03"+idRecord).val(d.cd03);
$("#icd10"+idRecord).val(d.icd10);
$("#onsetDate"+idRecord).val(d.onsetDate);
$("#outpatientNumber"+idRecord).val(d.outpatientNumber);
$("#inpatientNumber"+idRecord).val(d.inpatientNumber);
$("#diagnosticUnit"+idRecord).val(d.diagnosticUnit);
$("#reportingUnit"+idRecord).val(d.reportingUnit);
$("#reportingDate"+idRecord).val(d.reportingDate);
$("#reportingDoctor"+idRecord).val(d.reportingDoctor);
问题6.上传数据之前,隐藏控件的值不上传
根据radio选项,动态选择控件隐藏和显示,可能出现先给控件输入了一部分值,然后切换radio,把控件隐藏了,但是数值没有清空,有两种办法,第一种是在隐藏的时候,就清空里边的数据,清空选项,第二种方法,就是在提交数据的时候,遍历隐藏控件,他们的值不提交
//上传数据之前,隐藏控件的值,不上传,置为空
$("#myForm div[style='display: none;']").each(function(){
console.log("id:"+ $(this).attr("id"))
var idEach = $(this).attr("id");
$("#"+ idEach + " :input").each(function(){
var inputName=$(this).attr("name")
field[inputName]=""
});
});
filed是layui表单上传数据的对象
$.ajax({
type: "POST",
url: _CONTEXT_PATH + "mg/breast/xxxxx",
data: field,
error: function (errorRes) {
console.log(errorRes);
if (errorRes.status == 401) {
window.location.replace(_CONTEXT_PATH + errorRes.responseText);
} else {
layer.msg(errorRes.responseText, function () {
});
}
},
success: function (responseData) {
if (responseData.result) {
layer.msg("提交成功", {icon: 1, shift: 0, time: 1500, shade: 0.6}, function () {
});
} else {
layer.msg(responseData.message, {
icon: 2,
shift: 0,
time: 1500,
shade: 0.6
}, function () {
});
}
}
});