多个input组成的记事本,当前行input文本溢出时自动聚焦到下一行input,回车自动切换下一行
需求场景
需求是开发一个类似于笔记本的页面,在每一行都可以输入,点击回车自动切换下一行,并能点击打印(如下图)
话不多说先上效果图
开发前的构思:用一个大的textarea包裹一个table是不可能的实现的,不知道是否有相关的插件,我这个项目是原生的js所以我放弃了,决定用多个input,有多少行就写多少个input,代码如下
<div class="bodyDiv PageNext" id="addPage" style="padding-left: 10px;margin-top: 10px;">
<div style="width:100%; height: 10px;"></div>
<div style="width:100%; height:20%; margin:auto; ">
<img src="/img/logo.bmp" style="height: 70px; position:absolute; "> <!-- padding-left: 30vw-->
<div style="font-size: xx-large; text-align:center; font-family: 宋体,serif; letter-spacing:25px; ">
<p style="line-height:0.4">阜阳民生医院</p>
<p style="line-height:0.4">门诊病历</p>
</div>
</div>
<div style="width:100%; height: 10px;"></div>
<div style="width:100%;">
<table style="width:100%">
<tr>
<td class="tdInfoKey">姓名: </td>
<td class="tdInfoValue" th:text="${record?.hzxm}">XXX</td>
<td class="tdInfoKey">性别: </td>
<td class="tdInfoValue" th:text="${record?.sex}">XXX</td>
<td class="tdInfoKey">年龄: </td>
<td class="tdInfoValue" th:text="${record?.birth}">XXX</td>
</tr>
<tr>
<td class="tdInfoKey">日期: </td>
<td class="tdInfoValue"><div contenteditable="true" th:text="${record?.czrq}" title="日期的更改不会保存"></div></td>
<td class="tdInfoKey">病历号: </td>
<td class="tdInfoValue" th:text="${record?.blh}">XXX</td>
<td class="tdInfoKey">科室: </td>
<td class="tdInfoValue" th:text="${record?.ksmc}">XXX</td>
</tr>
</table>
</div>
<div style="width:100%; height: 10px;"></div>
<hr style="margin: 4px 0;width: 92%">
<div style="width:100%; height:auto;">
<table style="width: 92% ">
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input onkeydown="keydown(0)" id="input0" oninput="checkInputLength(this, 'input1')" th:value="${record?.Info?.fydetailList?.input0}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow: hidden; text-overflow:clip !important; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input1" oninput="checkInputLength(this, 'input2')" onkeydown="keydown(1)" th:value="${record?.Info?.fydetailList?.input1}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input2" oninput="checkInputLength(this, 'input3')" onkeydown="keydown(2)" th:value="${record?.Info?.fydetailList?.input2}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input3" oninput="checkInputLength(this, 'input4')" onkeydown="keydown(3)" th:value="${record?.Info?.fydetailList?.input3}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input4" oninput="checkInputLength(this, 'input5')" onkeydown="keydown(4)" th:value="${record?.Info?.fydetailList?.input4}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input5" oninput="checkInputLength(this, 'input6')" onkeydown="keydown(5)" th:value="${record?.Info?.fydetailList?.input5}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input6" oninput="checkInputLength(this, 'input7')" onkeydown="keydown(6)" th:value="${record?.Info?.fydetailList?.input6}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input7" oninput="checkInputLength(this, 'input8')" onkeydown="keydown(7)" th:value="${record?.Info?.fydetailList?.input7}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input8" oninput="checkInputLength(this, 'input9')" onkeydown="keydown(8)" th:value="${record?.Info?.fydetailList?.input8}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!--<!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input9" oninput="checkInputLength(this, 'input10')" onkeydown="keydown(9)" th:value="${record?.Info?.fydetailList?.input9}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input10" oninput="checkInputLength(this, 'input11')" onkeydown="keydown(10)" th:value="${record?.Info?.fydetailList?.input10}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!-- <!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input11" oninput="checkInputLength(this, 'input12')" onkeydown="keydown(11)" th:value="${record?.Info?.fydetailList?.input11}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!--<!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input12" oninput="checkInputLength(this, 'input13')" onkeydown="keydown(12)" th:value="${record?.Info?.fydetailList?.input12}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
<tr>
<td><hr style="height:1px;border:none;border-top:1px dotted #185598;margin: 0"/></td>
</tr>
<tr>
<td class="tdRecordValue">
<!--<!– <textarea id="zs" autoHeight="true" class="textarea" th:text="${record?.info?.zs}" ></textarea>–>-->
<input id="input13" oninput="checkInputLength(this, 'input13')" onkeydown="keydown(13)" th:value="${record?.Info?.fydetailList?.input13}" type="text" class="inputValue" style="box-shadow: none;width: 100%; overflow:hidden; resize:none; line-height: 1em; word-break:break-all;" ></input>
</td>
</tr>
</table>
<div style="width:100%; height: 10px;"></div>
<hr style="margin: 4px 0;width: 92%">
<div style="width:100%; height: 40px;"></div>
<div style="width:100%; height: auto">
<div style="float: right; width:220px; height: 80px">
<div style="float: left; height:80px; display:inline-block; vertical-align:middle">
医生签名:
</div>
<div style=" display:inline-block; vertical-align:middle">
<img style="vertical-align:middle;width: 100px;" src="" alt="" th:src="${'data:image/jpeg;base64,'+ record?.signature?.baseImg}" >
</div>
<div contenteditable="true" title="你可以删除此内容,以便在打印后手写签名,此更改不会保存,若不慎删除,点击保存后刷新即可" style=" height:80px; display:inline-block; vertical-align:middle">
<img style="vertical-align:middle;width: 100px;" src="" alt="" th:src="${'data:image/jpeg;base64,'+ record?.signature?.baseImg}" >
</div>
</div>
</div>
</div>
</div>
关键问题来了
当前行input文本溢出时禁止输入,并且超出部分不显示,这里禁止输入用maxlength是不可以的,因为同为32个字符的话,汉字的宽度比字母和数字要宽,导致每一行的文本宽度不一致,就会出现空格,
解决input文本溢出时禁止输入
解决办法:监听input输入的文本到达input尾部事件
function checkInputLength(input, nextInputId) {
const str = input.value;
/* console.log(input.scrollWidth,input.offsetWidth,input.clientWidth,nextInputId)*/
if (input.scrollWidth < (input.offsetWidth-8)) {
}else{/*
*/ console.log("溢出了",str)
input.value = str.slice(0, str.length - 1);
/* console.log("截掉后",input.value)*/
document.getElementById(nextInputId).focus();
if(nextInputId == "input13"){
document.getElementById(nextInputId).blur();
}
}
}
input.scrollWidth 只要小于 input.offsetWidth就说明没有到达尾部,大于的话就自动聚焦到下一个input
测试中有一个问题:
当连续输入超出的文本最后一个字会显示不全
解决办法:字符串删除最后一个字符
input.value = str.slice(0, str.length - 1);
最后完美解决!!!