不要害怕孤独,因为这个世界上总有一个人在努力走向你。
上节回顾:从一个简单页面带你体验H5开发
这一节我们来做一个稍微有点难度的页面。首先还是上原型和UI设计
了解主要功能:(1)数据库获取列表数据展示(2)年度、季度、部门、岗位的查询(3)重置(4)点击某一项弹出评分框-获取该条数据打分详情并展示(5)点击保存按钮发送请求、提交数据(6)点击提交按钮按照年份、季度提交所有记录。
确实比昨天的复杂一些,不过一步一步来,现在就开始吧。
1. 根据设计稿先写出前端静态页面
<body>
<div class='top'></div>
<div id="index-mask" class="index-mask" title="测评-首页">
<div class="dqkhzq">
<span class="khzq">当前考核周期:</span>
</div>
<div class="allDiv">
<div class="divWrap" style="position:relative">
<div class="divLeft">年份</div>
<div class="divRight" id="year" style="padding-right:0.4rem;"> <input placeholder='请选择' value="2021"
style="border:none;text-align:right;" id="yearInit" />
</div>
<img src="./images/kaoqin/xiala.png" style="width:0.25rem;height:0.14rem;position: absolute;
top: 0.35rem;right:0.4rem;" />
</div>
<div class="hpVertical"></div>
<div class="divWrap" style="position:relative">
<div class="divLeft">季度</div>
<div class="divRight" id="jidu" style="padding-right:0.4rem;"> <input id="jiduInit" placeholder="请选择"
value="第二季度" style="border:none;text-align:right;" />
</div>
<img src="./images/kaoqin/xiala.png" style="width:0.25rem;height:0.14rem;position: absolute;
top: 0.35rem;right:0.4rem;" />
</div>
</div>
<div class='allDiv'>
<div class="divWrap" style="position:relative">
<div class="divLeft">部门</div>
<div class="divRight" id="bumen" style="padding-right:0.4rem;"> <input id="bumenInit" placeholder='请选择'
style="border:none;text-align:right;" />
</div>
<img src="./images/huping/xiala.png" style="width:0.25rem;height:0.14rem;position: absolute;
top: 0.35rem;right:0.4rem;" />
</div>
<div class="hpVertical" style="position:relative"></div>
<div class="divWrap" style="position:relative">
<div class="divLeft">岗位</div>
<div class="divRight" id="gangwei" style="padding-right:0.4rem;"> <input id="gangweiInit" placeholder='请选择'
style="border:none;text-align:right;" />
</div>
<img src="./images/huping/xiala.png" style="width:0.25rem;height:0.14rem;position: absolute;
top: 0.35rem;right:0.4rem;" />
</div>
<div class="hpVertical" style="position:relative"></div>
<div class="divWrap" style="justify-content: flex-end;">
<span class="btncx" onclick="getDPList()">查询</span>
<span class="btncz" onclick="resetList()">重置</span>
</div>
</div>
<div id="content_1" class="content_1"></div>
<!-- <div class="allDiv">
<div class="divWrap">
<div class="divLeft">姓名</div>
<div class="divRight">刘明</div>
</div>
<div class="hpVertical"></div>
<div class="divWrap">
<div class="divLeft">部门</div>
<div class="divRight">刑事侦察大队</div>
</div>
<div class="hpVertical"></div>
<div class="divWrap">
<div class="divLeft">岗位</div>
<div class="divRight">综合管理岗</div>
</div>
<div class="hpVertical"></div>
<div class="divWrap">
<div class="divLeft">考核类型</div>
<div class="divRight">非领导成员公务员</div>
</div>
<div class="hpVertical"></div>
<div class="divWrap">
<div class="divLeft">状态</div>
<div class="divRightBlue">待提交</div>
</div>
<div class="hpVertical"></div>
<div class="divWrap">
<div class="divLeft">得分</div>
<div class="divRightBlue">95</div>
</div>
<div class="hpVertical"></div>
<div class="divWrap" style="justify-content: flex-end">
<div class="rate" data-toggle="modal" data-target="#myModal">评分</div>
</div>
</div> -->
<div style="text-align: center;">
<div class="btnSubmit" id="submitBtn" onclick="allSubmit()">提交</div>
</div>
</div>
<!-- 评分模态框(Modal) -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"
style="margin-top: -1.5rem;">
<div class="modal-dialog" style="width: 6rem;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<div class="modal-title" id="myModalLabel">测评</div>
</div>
<div class="modal-body" style="padding-left: 0.3rem;">
<div class="bodycontent">分值:<input class="inputS" type="text" id="fenzhi" disabled="disabled"></div>
<div class="bodycontent" style="margin-top: 0.3rem;">打分:<input class="inputS" id="dafen"></div>
<div class="bodycontent" style="margin-top: 0.3rem;">说明:<textarea class="textarea" rows="3" id="explain"
disabled="true"></textarea></div>
</div>
<div class="modal-footer" style="text-align: center;">
<button type="button" class="btn btn-default" data-dismiss="modal">取消
</button>
<button type="button" class="btn btn-primary" style="margin-top: 0.3rem;margin-bottom: 0.31rem;"
onclick="btnSave()" id="baocun">
保存
</button>
<button type="button" class="btn btn-primary" data-dismiss="modal"
style="margin-top: 0.3rem;margin-bottom: 0.31rem;" id="queren">
确认
</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
<!-- 提交Modal -->
<div class="modal fade" id="subModal" tabindex="-1" role="dialog" aria-labelledby="subModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<div class="modal-title" id="subModalLabel" style="color: black; font-weight: 400;">
提交后不可修改,是否确认提交?
</div>
</div>
<!-- <div class="modal-body">
在这里添加一些文本
</div> -->
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消
</button>
<button type="button" class="btn btn-primary" onclick="btnSure()">
确定
</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
</body>
2. 添加年份、季度、岗位的select下拉框信息
<script src="./js/mobileSelect.js"></script>
var year = ['2017', '2018', '2019', '2020', '2021'];
var mobileSelect1 = new MobileSelect({
trigger: '#year',
title: '年份',
wheels: [
{ data: year }
],
position: [4], //初始化定位 打开时默认选中的哪个 如果不填默认为0
transitionEnd: function (indexArr, data) {
$("#year").val(data[0])
},
callback: function (indexArr, data) {
}
});
var jidu = ['第一季度', '第二季度', '第三季度', '第四季度'];
var mobileSelect2 = new MobileSelect({
trigger: '#jidu',
title: '季度',
wheels: [
{ data: jidu }
],
position: [1], //初始化定位 打开时默认选中的哪个 如果不填默认为0
transitionEnd: function (indexArr, data) {
//console.log(data);
},
callback: function (indexArr, data) {
$("#jidu").val(data[0])
}
});
// 岗位 0:综合管理岗,1:行政事务岗,2:行政执法岗,3:专业技术岗,4:窗口服务岗
var choosedGangweiIndex = "";
var gangwei = ['综合管理岗', '行政事务岗', '行政执法岗', '专业技术岗', '窗口服务岗'];
var mobileSelect4 = new MobileSelect({
trigger: '#gangwei',
title: '岗位',
wheels: [
{ data: gangwei }
],
position: [0], //初始化定位 打开时默认选中的哪个 如果不填默认为0
transitionEnd: function (indexArr, data) {
//console.log(data);
},
callback: function (indexArr, data) {
// console.log(indexArr[0])
choosedGangweiIndex = indexArr[0]
$("#gangwei").val(data[0])
}
});
其实对于部门也是一个道理,但是这里,部门不是固定枚举的,而是根据用户从数据库(调接口)中获取显示,因此我们稍后再解决
3.同上一节的介绍,需要初始化页面并添加数据到content_1
var pageNum = 1; //默认是从第一页开始访问
var pageSize = pageSizeGlobal; //默认一页访问的条数
var isMore = false;
var year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
var jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
var bumen = ""
var gangwei = ""
//第一次进入页面,加载2021第二季度的数据。
getList(year, jidu, pageNum, pageSize, bumen, gangwei);
function getList(year, quarter, pageNum, pageSize, departmentId, jobPost) {
// console.log(window.localStorage.getItem("currentUser"))
$.ajax({
type: "post",
url: urlGlobal + "/api/h5/assess/score/evaluation/page",
async: true,
dataType: "json",//后台返回值类型
contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
async: false,//异步请求
data: JSON.stringify({
year: year,
quarter: quarter,
pageNum: pageNum,
pageSize: pageSize,
departmentId: departmentId,
jobDuty: jobPost
}),
headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
success: function (data) {
console.log(data)
if (data.code === 200) {
total = data.data.totalCount; //总
pades = data.data.totalPage; //总页数
//isMore,当不是最后一页的时候,为ture,若是最后一页,则为false
// data.data.list[0].status = 0;
if (data.data.currPage < data.data.totalPage) {
isMore = true;
}
if (data.data.currPage === data.data.totalPage) {
isMore = false;
}
//如果总个数===0,做暂无数据的处理。
if (data.data.totalCount == 0) {
$("#content_1").empty();
// $("#content_1").append("暂无内容");
// 没有“提交按钮”
document.getElementById("submitBtn").style.display = "none"
} else {
for (var i = 0; i < data.data.list.length; i++) {
$("#content_1").append(strlistDom(data.data.list[i]))
}
//当前是最后一页的时候增加全部加载完毕的提示语
if (data.data.currPage === data.data.totalPage) {
$("#content_1").append("<div style='margin-top:0.2rem;margin-bottom:0.4rem;text-align:center;color: #999999;font-size:0.3rem;'>数据加载完毕</div>");
}
}
} else {
alertGlobal(data.message, 3000, true)
}
}
});
}
// 获取页面DOM元素
function strlistDom(data) {
// 防止先查询到无数据后又查询有数据后不显示btn按钮
var status = data.status === 0 ? "待提交" : "已提交";
var score = data.score ? data.score : 0;
var pfck = status === "已提交" ? "查看" : "评分"
if (pfck === "查看") {
document.getElementById("submitBtn").style.display = "none"
} else {
document.getElementById("submitBtn").style.display = "inline-block"
}
var str =
"<div class='allDiv'>" +
"<div class='divWrap'>" +
"<div class='divLeft'>姓名</div>" +
"<div class='divRight'>" + data.name + "</div></div>" +
"<div class='hpVertical'></div>" +
"<div class='divWrap'>" +
"<div class='divLeft'>部门</div>" +
"<div class='divRight'>" + data.department + "</div></div><div class='hpVertical'></div>" +
"<div class='divWrap'>" +
"<div class='divLeft'>岗位</div>" +
"<div class='divRight'>" + data.jobPostStr + "</div></div><div class='hpVertical'></div>" +
"<div class='divWrap'> <div class='divLeft'>考核类型</div>" +
"<div class='divRight'>" + data.examineeTypeStr + "</div></div><div class='hpVertical'></div>" +
"<div class='divWrap'><div class='divLeft'>得分</div>" +
"<div class='divRight'>" + score + "</div></div><div class='hpVertical'></div>" +
"<div class='divWrap'><div class='divLeft'>状态</div>" +
"<div class='divRightBlue'>" + status + "</div></div><div class='hpVertical'></div>" +
// 评分
// "<div class='divWrap' style='justify-content: flex-end'><div class='rate' data-toggle='modal' data-target='#myModal'>评分</div></div>"
// 查看
"<div class='divWrap' style='justify-content: flex-end'>" +
"<div class='rate' data-toggle='modal' data-target='#myModal' onclick='pingfen(\"" + data.id + "\",\"" + pfck + "\")'>" + pfck + "</div></div></div>"
return str;
}
其中可以看到,对于“待提交”“已提交”做了区分处理,由于后端返回的数据是0-1,因此这里需要区分显示,并且对于“待提交”的数据可以评分,但是对于“已提交”的数据只可以进行查看。
4. 处理滚动翻页问题
$(window).scroll(function () {
$(".content_1").each(function () {
var scrollTop = this.scrollTop || document.body.scrollTop || document.documentElement.scrollTop;
if (scrollTop + window.innerHeight + 20 >= this.offsetHeight) {
if (isMore) {
isMore = false;
pageNum++;
year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
bumen = choosedDepartmentID;
console.log(bumen)
gangwei = choosedGangweiIndex;
getList(year, jidu, pageNum, pageSize, bumen, gangwei);
}
}
});
});
5. 数据库获取部门信息并显示在select
var choosedDepartmentID;
// 加载部门所有数据显示在下拉框
window.onload = function () {
var organizationId = window.localStorage.getItem("unitId"); //当前登录用户的机构ID
//获取当前机构id下的所有部门
$.ajax({
type: "get",
url: urlGlobal + "/api/h5/sys/organizationList",
async: true,
dataType: "json",//后台返回值类型
contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
async: false,//异步请求
data: ({
organizationId: organizationId,
}),
headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
success: function (data) {
if (data.code === 200) {
var bumen = []
for (var i = 0; i < data.data.length; i++) {
bumen.push({ id: data.data[i].id, value: data.data[i].name });
}
var mobileSelect3 = new MobileSelect({
trigger: '#bumen',
title: '部门',
wheels: [
{ data: bumen }
],
position: [0], //初始化定位 打开时默认选中的哪个 如果不填默认为0
transitionEnd: function (indexArr, data) {
},
callback: function (indexArr, data) {
choosedDepartmentID = data[0].id;
$("#bumen").val(data[0])
},
});
} else {
alertGlobal(data.message, 3000, true)
}
}
});
}
6. 查询函数和重置函数
//查询函数
function getDPList() {
console.log("search")
pageNum = 1; //默认是从第一页开始访问
pageSize = pageSizeGlobal;
isMore = false;
year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
bumen = choosedDepartmentID;
gangwei = choosedGangweiIndex;
// bumen = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
// gangwei = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
$("#content_1").empty();
getList(year, jidu, pageNum, pageSize, bumen, gangwei);
}
//重置函数
function resetList() {
pageNum = 1; //默认是从第一页开始访问
pageSize = pageSizeGlobal;
isMore = false;
$("#year").html(yearInitGlobal); //充值下拉框的默认显示值
$("#jidu").html("第二季度");
$("#bumen").html('请选择');
choosedDepartmentID = '';
$("#gangwei").html('请选择');
choosedGangweiIndex = '';
$("#content_1").empty();
getList(yearInitGlobal, quarterInitGlobal, pageNum, pageSize, '', '');
}
至此完成了主页面的列表,其实和上一节的基本相似,只是对于一些复杂情况做了处理,接下开我们需要进行评分弹框中显示详情,以及评分保存功能,整体提交功能进行开发,先看一下接口文档。
对于测评详情(即点击弹框后显示的数据),需要传入该测评的id,请求后会返回测评id,得分、分值、说明,把这些显示在页面上。
而对于弹框输入后的保存,接口就比较简单,只需要传入测评id和得分即可,没有返回数据。
对于最终的批量提交功能,相对来说比较简单,直接按照年份和季度提交所有数据即可
7. 静态页面中已经写好了Modal弹框,我们首先让点击“评分”按钮后,触发事件进行弹框显示
<div class='rate' data-toggle='modal' data-target='#myModal' onclick='pingfen(\"" + data.id + "\",\"" + pfck + "\")'>" + pfck + "</div></div></div>
上面已经写好,而对于每次选中“评分”的这条信息,需要获取其id才可以调接口显示数据,因此在pingfen()函数中传入了data.id,评分弹框展示并显示数据的代码如下
var tempId;
var tempScore;
// 评分函数
function pingfen(id, pfck) {
tempId = id
$.ajax({
type: "get",
url: urlGlobal + "/api/h5/assess/score/evaluation/" + id,
async: true,
dataType: "json",//后台返回值类型
contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
async: false,//异步请求
headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
success: function (data) {
console.log(data)
if (data.code === 200) {
tempScore = data.data.presetScore // 暂存分数-方面后面比较
var list = data.data
console.log(list.score)
$("#fenzhi").val(list.presetScore)
$("#dafen").val(list.score)
$("#explain").val(list.remark)
// 已提交还是待提交
console.log(list.score)
if (pfck === "查看") { //已提交
console.log("已提交")
document.getElementById("dafen").disabled = "disabled";
document.getElementById("baocun").style.display = "none"
document.getElementById("queren").style.display = "inline-block"
} else { //
console.log("待提交")
document.getElementById("queren").style.display = "none"
document.getElementById("baocun").style.display = "inline-block"
}
} else {
alertGlobal(data.message, 3000, true)
}
}
});
}
可以看到获取返回值后,把他们对应渲染到input里面就可以了。这里由于“查看”和“评分”按钮名称和功能不同,所有做了显示和隐藏的处理。
8. 评分页面后,输入相应的分数进行打分,并调用接口保存数据。
// 评分页保存
function btnSave(id) {
console.log(tempId)
var dafen = $("#dafen").val()
if (parseInt($("#dafen").val()) > tempScore) { //判断输入正确性
alertGlobal('评分数应小于分值', 3000, true)
} else if (dafen == "" || isNaN(dafen)) {
alertGlobal('评分数应非空且为数字', 3000, true)
}
else {
$.ajax({
type: "post",
url: urlGlobal + "/api/h5/assess/score/evaluation",
async: true,
dataType: "json",//后台返回值类型
contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
async: false,//异步请求
data: JSON.stringify({
id: tempId,
score: $("#dafen").val()
}),
headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
success: function (data) {
console.log(data)
if (data.code === 200) {
// 刷新页面 但保存当前年份和季度??
var year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
var jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
bumen = choosedDepartmentID;
gangwei = choosedGangweiIndex;
$("#content_1").empty();
getList(year, jidu, pageNum, pageSize, bumen, gangwei);
alertGlobal(data.message, 3000, true)
} else {
alertGlobal(data.message, 3000, true)
}
}
});
//关闭评分modal
$('#myModal').modal("hide")
}
}
在评分之前,先判断“分数小于分值”“输入必须为数字且不为空”,后请求即可。并注意完成之后需要刷新页面,即:先将页面制空empty()之后,再重新获取数据放入。
9. 批量提交功能
// 全部提交弹框
function allSubmit() {
$('#subModal').modal({ show: true })
}
// 全部提交(按照年份和季度全部提交)
function btnSure() {
var year = $("#yearInit").val() ? yearInitGlobal : $("#year").html();
var jidu = $("#jiduInit").val() ? quarterInitGlobal : getQuarterGlobal($("#jidu").html());
$.ajax({
type: "post",
url: urlGlobal + "/api/assess/score/evaluation/submit",
async: true,
dataType: "json",//后台返回值类型
contentType: "application/json;charset=utf-8", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
async: false,//异步请求
data: JSON.stringify({
year: year,
quarter: jidu
}),
headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem("token") },
success: function (data) {
if (data.code === 200) {
alertGlobal("提交成功", 3000, true)
// $('#subModal').modal({ show: false })
} else {
alertGlobal(data.message, 3000, true)
}
}
});
$('#subModal').modal("hide")
refresh();
}
至此就完成了今天的页面效果
下一节,我们将实现一个更有难度的功能,批量提交,不同于本文的批量提交,需要进行选择,对于选中的项目获取对应的id和score交给后端。