一、背景
项目中有一个表单填报,表单基本可分为左右两边,左边是一些基本评分规则(数量不固定),右边是一些被评分人(数量也不固定)。现在的需求就是,当被评分人数过多时,右边表格需要自动形成滚动条,可滚动评分,而此时左边评分规则不动。
当每一个评分因素评完分之后,需要自动计算该评分项的小计总分以及该被评分人的总计得分,且此处表格存在合并单元格的样式。
二、解决方案
由于此处固定部分需要合并单元格,并且每一评分项都需要小计,所以在尝试Boostrap-Table、LayUI -Table无果之后,就选择了手动将表单分为两个table表格来写,最终再拼接在一起。
注:兼容IE11(其它版本没测)、Google、Firefox
三、页面代码
<html>
<head>
<meta name="generator"
content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>拼接表格示例</title>
<!-- Bootstrap -->
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" />
<script src="js/jquery.js"></script>
<!-- 拼接表格的样式 -->
<style type="text/css">
.table td {
font-size: 14px;
text-align: center;
vertical-align: middle!important;
}
.table thead tr th {
font-size: 16px;
/* 内容水平居中 */
text-align: center;
/* 内容垂直居中 */
vertical-align: middle!important;
}
.error{
text-align: left;
color: #d9534f;
float: left;
}
.box .right .table .form_pingfen{
width: 80%;
display: inline-block;
}
.box {
position: relative;
margin: 20px;
}
/* 让table的内部布局固定大小,才能使td内容溢出后显示省略号生效 */
.box div table {
table-layout: fixed;
}
/* 左边固定项表格的宽度 */
.box .left {
width: 40%;
/* border: 1px solid #dcdcdc; */
}
/* 内容溢出生成滚动条;移动右边table,使其与左边table连接起来 */
/* 右边活动项表格的宽度 */
.box .right{
width:60%;
overflow:auto;
/* 不需要垂直滚动条 */
overflow-y:hidden;
display:block;
position: absolute;
left: 40%;
top: 0;
border-right: 1px solid #dcdcdc;
/* border: 1px solid #dcdcdc; */
}
.box .right table{
min-width:100%;
margin-bottom: 0;
}
.box .right table tr th, .box .right table tr td{
width: 220px;
min-width:220px;
}
/* 使td内容溢出时以省略号显示 */
.box .table tr td, .box .table tr th{
/* 不换行 */
word-break:keep-all;
/* 不换行 */
white-space:nowrap;
overflow:hidden;
text-overflow: ellipsis;
}
.box .table .td_pingfen {
height: 60px;
min-height: 60px;
max-height: 60px;
}
.box .table .td_jisuan {
height: 52px;
min-height: 52px;
max-height: 52px;
}
.box .table .td_beizhu {
height: 150px;
min-height: 150px;
max-height: 150px;
}
.box div .table tbody .color_pingfen > td {
background-color: #f3e9d8;
}
.box div .table tbody .color_xiaoji > td {
background-color: #c1e5f7;
}
.box div .table tbody .color_zongji > td {
background-color: #efc5c5;
}
</style>
<script type="text/javascript">
/* 根据浏览器大小设定右边table的div的宽度 */
$(function(){
/* $(window).resize(function(){
$("#right").css("max-width", $(window).width() - $(window).width() * 0.40 - 60);
}).resize(); */
})
/** 高亮鼠标悬浮行 */
var tr_index;
function overColor_pingfen($this){
tr_index = $this.rowIndex; //rowIndex是相对于table来计算下标的,index是相对于所处同一个父元素下来计算
// tr_index = $($this).index() + 1;
$(".left table tr:eq("+tr_index+")").addClass("color_pingfen");
$(".right table tr:eq("+tr_index+")").addClass("color_pingfen");
// $($this).addClass("color_pingfen");
}
function outColor_pingfen($this){
$(".left table tr:eq("+tr_index+")").removeClass("color_pingfen");
$(".right table tr:eq("+tr_index+")").removeClass("color_pingfen");
// $($this).removeClass("color_pingfen");
}
function overColor_xiaoji($this){
tr_index = $this.rowIndex;
// tr_index = $($this).index() + 1;
$(".left table tr:eq("+tr_index+")").addClass("color_xiaoji");
$(".right table tr:eq("+tr_index+")").addClass("color_xiaoji");
// $($this).addClass("color_xiaoji");
}
function outColor_xiaoji($this){
$(".left table tr:eq("+tr_index+")").removeClass("color_xiaoji");
$(".right table tr:eq("+tr_index+")").removeClass("color_xiaoji");
// $($this).removeClass("color_xiaoji");
}
function overColor_zongji($this){
tr_index = $this.rowIndex;
// tr_index = $($this).index() + 1;
$(".left table tr:eq("+tr_index+")").addClass("color_zongji");
$(".right table tr:eq("+tr_index+")").addClass("color_zongji");
// $($this).addClass("color_zongji");
}
function outColor_zongji($this){
$(".left table tr:eq("+tr_index+")").removeClass("color_zongji");
$(".right table tr:eq("+tr_index+")").removeClass("color_zongji");
// $($this).removeClass("color_zongji");
}
</script>
</head>
<body>
<div class="box">
<!-- 左边固定项表格 -->
<div id="left" class="left">
<table id="contentTable" class="table table-striped table-bordered">
<colgroup>
<col style="width:30%" />
<col style="width:30%" />
<col style="width:40%" />
</colgroup>
<thead>
<tr class="success">
<th class="td_pingfen">评分项</th>
<th class="td_pingfen">评分因素</th>
<th class="td_pingfen">评分规则</th>
</tr>
</thead>
<tbody>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td rowspan="2" class="td_pingfen">评分项-1</td>
<td class="td_pingfen">评分因素-1.1</td>
<td class="td_pingfen">评分规则-1.1</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">评分因素-1.2</td>
<td class="td_pingfen">评分规则-1.2</td>
</tr>
<tr class="info" style="font-weight: bold;" onmouseover="overColor_xiaoji(this)" onmouseout="outColor_xiaoji(this)">
<td class="td_jisuan">小计</td>
<td colspan="2" class="td_jisuan">得分小计</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td rowspan="3" class="td_pingfen">评分项-2</td>
<td class="td_pingfen">评分因素-2.1</td>
<td class="td_pingfen">评分规则-2.1</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">评分因素-2.2</td>
<td class="td_pingfen">评分规则-2.2</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">评分因素-2.3</td>
<td class="td_pingfen">评分规则-2.3</td>
</tr>
<tr class="info" style="font-weight: bold;" onmouseover="overColor_xiaoji(this)" onmouseout="outColor_xiaoji(this)">
<td class="td_jisuan">小计</td>
<td colspan="2" class="td_jisuan">得分小计</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td rowspan="2">评分项-3</td>
<td class="td_pingfen">评分因素-3.1</td>
<td class="td_pingfen">评分规则-3.1</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">评分因素-3.2</td>
<td class="td_pingfen">评分规则-3.2</td>
</tr>
<tr class="info" style="font-weight: bold;" onmouseover="overColor_xiaoji(this)" onmouseout="outColor_xiaoji(this)">
<td class="td_jisuan">小计</td>
<td colspan="2" class="td_jisuan">得分小计</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
<tr class="danger" style="font-weight: bold;" onmouseover="overColor_zongji(this)" onmouseout="outColor_zongji(this)">
<td class="td_jisuan">总计</td>
<td colspan="2" class="td_jisuan">综合得分</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>
<tr style="font-weight: bold;" onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td colspan="3" class="td_beizhu">备注</td>
</tr>
</tbody>
</table>
</div>
<!-- 右边活动项表格 -->
<div id="right" class="tab-content right">
<table id="contentTable" class="table table-striped table-bordered">
<thead>
<tr class="success">
<th class="td_pingfen" title="被评价人-1">被评价人-1</th>
<th class="td_pingfen" title="被评价人-2">被评价人-2</th>
<th class="td_pingfen" title="被评价人-3">被评价人-3</th>
<th class="td_pingfen" title="被评价人-4">被评价人-4</th>
</tr>
</thead>
<tbody>
<!-- 评分项-1 -->
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<!-- 评分因素-1 小计 -->
<tr class="info" style="font-weight: bold;" onmouseover="overColor_xiaoji(this)" onmouseout="outColor_xiaoji(this)">
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<!-- 评分项-2 -->
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<!-- 评分项-2 小计 -->
<tr class="info" style="font-weight: bold;" onmouseover="overColor_xiaoji(this)" onmouseout="outColor_xiaoji(this)">
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<!-- 评分项-3 -->
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<tr onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_pingfen">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<!-- 评分项-3 小计 -->
<tr class="info" style="font-weight: bold;" onmouseover="overColor_xiaoji(this)" onmouseout="outColor_xiaoji(this)">
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<tr>
<td colspan="4"></td>
</tr>
<!-- 总计 -->
<tr class="danger" onmouseover="overColor_zongji(this)" onmouseout="outColor_zongji(this)">
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
<td class="td_jisuan">
<input htmlescape="false" max="100" min="0" class="form-control form_pingfen required number" />
</td>
</tr>
<tr>
<td colspan="4"></td>
</tr>
<!-- 备注 -->
<tr style="font-weight: bold;" onmouseover="overColor_pingfen(this)" onmouseout="outColor_pingfen(this)">
<td colspan="4" class="td_beizhu">
<textarea rows="5" id="beizhu" class="required" style="width: 97%;"></textarea>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
四、效果图
注:当被评价人数超出表格范围时,右边表格会自动形成滚动条 。
五、小计、总计的计算说明
由于这里没有使用真实数据,计算方法也不好直接在样板中展示,在此仅说明下思路:
1、在数据中每个评分项(ruleId)、被评分人(personId)都有唯一的ID标识;
2、小计:在每一个打分输入框(input)都添加ruleId_personId这个类,在此输入框绑定onchange事件,参数就为ruleId_personId,在事件中使用类选择器获取该被评分人该评分项的所有输入框,遍历相加即可;
注:计算时需注意数字长度和精度的控制!
3、总计:在每一个小计输入框都添加personId这个类,在此输入框绑定onchange事件,参数就为personId,在事件中使用类选择器获取该被评分人该评分项的所有输入框,遍历相加即可;
/** 小计统计 */
function xiaoji(xjId){
var count = 0;
var regExp = new RegExp("\\d+");
$("." + xjId).each(function(){
if(regExp.test($(this).val())){
count += Number($(this).val());
}
});
$("#" + xjId).val(count.toFixed(2));
var zjId = xjId.substring(0, xjId.indexOf("_"));
zongji(zjId);
}
/** 总计计统计 */
function zongji(zjId){
var count = 0;
var regExp = new RegExp("\\d+");
$("." + zjId).each(function(){
if(regExp.test($(this).val())){
count += Number($(this).val());
}
});
if (count == 0) {
$("#" + zjId).val('');
}else{
$("#" + zjId).val(count.toFixed(2));
}
}
附-示例代码打包: