本文已参与「新人创作礼」活动,一起开启掘金创作之路。
需求分析
说明
- (总的时间为一年):如图起始日期选择2020-01-28,分期方式为季度(隔三个月缴费一次)。
- 填写总金额,选择起始缴费日期,再选缴费方式,当点击下拉框“季度”选项时,下方表格自动清除全部内容后生成新的数据。
- 如果选择other,会出现“添加行”和“删除全部”两个按钮,点击添加行,会增加一条数据,点击清除行会全部清除
实现技术采用
- 前端:jsp页面,layui框架,JS , JQ
- 后端:java
代码前端js
静态部分(去掉部分样式)
- 输入框部分
<div>
<div>
<span><strong>总金额:</strong></span>
<fmt:formatNumber type="number" value="${mainObject.amount}" groupingUsed="false" var="formattedNumber" />
<form:input path="amount" htmlEscape="false" maxlength="21" id="amount" class = "金额样式" value="${formattedNumber}" />
</div>
<div>
<span><strong>起始日期:</strong></span>
<input id="dueDate" name="dueDate" type="text" maxlength="20" class="时间样式"
value="<fmt:formatDate value="${mainObject.dueDate}" pattern="yyyy-MM-dd"/>"
onclick="封装的时间选择器,dateFmt:'yyyy-MM-dd',isShowClear:false});" />
</div>
<div>
<span><strong>缴费方式:</strong></span>
<form:select id="payMethodId" path="payMethod" class="下拉框样式" onchange="getStagingInformation();">
<form:option value="" label="请选择分期方式" /> <%-- 数据库字典方式 --%>
<form:options items="getDictList('payMethod')" itemLabel="label" itemValue="value" htmlEscape="false" />
</form:select>
</div>
</div>
- 表格部分
<table id="contentTable" class="table table-striped table-bordered table-condensed" style="width: 60%;">
<thead>
<tr>
<th>缴费期次</th>
<th>缴费日期</th>
<th>缴费金额</th>
</tr>
</thead>
<tbody id="payplansList"></tbody><%-- 表身此处为空,等待动态添加行 --%>
</table>
动态部分
- 表格动态添加行的JS
<!-- 一行的模板样式 id="payplansListTpl" -->
<script type="text/template" id="payplansListTpl">
<tr id="payplansList{{idx}}">
<td id= "bbb"><%-- 缴费期次 --%>
<input id="payplansList{{idx}}_paytimes" name="bsPolicyPayplansList[{{idx}}].paytimes" type="text"
value="{{row.paytimes}}" maxlength="13" class="numberPos14_2" readonly="true" />
</td>
<td><%-- 缴费日期 --%>
<input id="payplansList{{idx}}_paydate" name="payplansList[{{idx}}].paydate" value="{{row.paydate}}"
pattern="yyyy-MM-dd" maxlength="32" class="时间样式" onclick="选时间" maxlength="32"/>
</td>
<td><%-- 金额 --%>
<input id="bsPolicyPayplansList{{idx}}_preAmount" name="payplansList[{{idx}}].preAmount" type="text"
value="{{row.preAmount}}" maxlength="21" class="金额样式"/>
</td>
</tr>
</script>
<script type="text/javascript">
var payplansListRowIdx = 0, payplansListTpl = $("#payplansListTpl").html().replace(/(\/\/\<!\-\-)|(\/\/\-\->)/g,"");
$(document).ready(function() {
var data = ${fns:toJson(main.payplansList)};
for (var i=0; i<data.length; i++){
addRow('#payplansList', payplansListRowIdx, payplansListTpl, data[i]);
payplansListRowIdx = payplansListRowIdx + 1;
}
});
function addRow(list, idx, tpl, row){
$(list).append(Mustache.render(tpl, {
idx: idx, delBtn: true, row: row
}));
//再加金额样式css
}
</script>
- 生成数据(js代码)
<script type="text/javascript">
//下拉框选择后执行代码
function getStagingInformation(){
//验证总金额是否存在,验证起始日期是否存在,验证缴费方式是否存在
......
//首先:清空所有行
var len = $("#payplansList tr").length;
for (var i=0; i<len; i++){
var tr = document.getElementById("bbb").parentNode;
tr.parentNode.removeChild(tr)
payplansListRowIdx--;
}
//获取期次=缴费方式进行判断
var numberOfPeriods = $("#payMethodId").val()
if(numberOfPeriods != '05'){//01年02半年03季度04月05其他
$("#information_action_button").hide(); //other方式需要的“添加行”和“删除全部”
//将付款方式 和 起始时间 交给后端,后端会计算出时间和条数,以集合方式返回给前端,下方有具体代码
$.ajax({
type: "POST",
url: '${xxx}/xxx/xxx/getDateByPayMethod',
data:{
payMethod:$("#payMethodId").val(),
dutyDay:$("#dueDate").val()
},
async : false,
dataType: "json",
success: function (data){
var size = data.length - 1
//总金额除以添加行数赋值
var amount = Number($("#amount").val().replace(/[,]/g,""));
//金额设定:这里有个需求,将所有零头累积到最后一期
var preAmount=amount/size;
//定义标记
var preAmountTag = 0.00;
for ( k = 0 ; k<size; k++){
//添加一行空模板
addAccRow('#payplansList',payplansListRowIdx, payplansListTpl,payplansListRowIdx = payplansListRowIdx + 1);
//自动生成序号
var str=$("#payplansList tr:eq("+(payplansListRowIdx-1)+") td:eq(0) input")
.val(payplansListRowIdx);
//时间设定
var dateValue = $("#payplansList tr:eq("+(payplansListRowIdx-1)+") td:eq(1) input").val(data[k]);
//金额设定:这里有个需求,将所有零头累积到最后一期
if( k != size-1 ){//不是最后一期
//赋值
var preAmount = $("#payplansList tr:eq("+(payplansListRowIdx-1)+") td:eq(2) input")
.val(preAmount.toFixed(2)).formatCurrency();
//给标记加上此期金额
preAmountTag += parseFloatWithCurrency(preAmount.toFixed(2));
}else{//不是最后一期
//平均除后前几期累加后为preAmountTag: 总金额-preAmountTag=最后一期
var preAmountLast = parseFloatWithCurrency(amount - Number(preAmountTag));
}
}
},
error:function () {
// alert("请求失败!");
}
});
}else if(numberOfPeriods == '05'){ //选择的付款方式是其他,先不做任何操作,显示出
//显示“添加行”和“删除全部”按钮
$("#information_action_button").show();
}
}
</script>
代码后端java
- 生成数据(java代码)
@RequestMapping(value = "getDateByPayMethod")
@ResponseBody
public List<String> getDateByPayMethod(String payMethod,String dutyDay) {// payMethod---01年 02半年 03季度 04月
List<String> list=new ArrayList<>();
//几条数据(一年几次)
int count = 0;
//相隔几个月
int type = 0;
if(payMethod.equals("04")) {
count=12;
type=1;
}else if(payMethod.equals("03")) {
count=4;
type=3;
}else if(payMethod.equals("02")) {
count=2;
type=6;
}else if(payMethod.equals("01")) {
count=1;
type=12;
}
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//起始日期是 date
LocalDate date = LocalDate.parse(dutyDay, fmt);
for(int i=0;i<=count;i++) {
//起始日期往后顺延
list.add(fmt.format(date.plusMonths(i*type)));
}
return list;
}
- “添加行” 和 “删除全部” 按钮的点击事件
<script>
////////添加行////按钮事件
function onClickPay(){
//现有多少行 :现有一行 即 清空全部后 带出两行(+1)
var len = $("#payplansList tr").length;
var resultsNumRows = Number(len+1);
//清除以前行数
for (var i=0; i<len; i++){
var tr = document.getElementById("bbb").parentNode;
tr.parentNode.removeChild(tr)
bsPolicyPayplansListRowIdx--;
}
var size = resultsNumRows;
//总保费除以添加行数赋值
var amount =Number($("#amount").val().replace(/[,]/g,""));
var preAmount = amount/size;
var preAmountTag = 0.00;
for ( k = 0 ; k<size; k++){
addAccRow('#payplansList',payplansListRowIdx, payplansListTpl,payplansListRowIdx = payplansListRowIdx + 1);
//自动生成序号
var str=$("#payplansList tr:eq("+(payplansListRowIdx-1)+") td:eq(0) input").val(payplansListRowIdx);
//时间就自选吧,在这不计算设定
//如果是最后一期
if( k != size-1 ){//不是最后一期
//赋值
var preAmount = $("#payplansList tr:eq("+(payplansListRowIdx-1)+") td:eq(2) input")
.val(preAmount.toFixed(2)).formatCurrency();
//给标记加上此期金额
preAmountTag += parseFloatWithCurrency(preAmount.toFixed(2));
}else{//不是最后一期
//平均除后前几期累加后为preAmountTag: 总金额-preAmountTag=最后一期
var preAmountLast = parseFloatWithCurrency(amount - Number(preAmountTag));
}
}
}
/////清除行////按钮事件
function cleanPay(){
//现有多少行 :现有一行 即 清空全部后 带出两行(+1)
var len = $("#payplansList tr").length;
//清除以前行数
for (var i=0; i<len; i++){
var tr = document.getElementById("bbb").parentNode;
tr.parentNode.removeChild(tr)
payplansListRowIdx--;
}
}