本文采用thymeleaf模闆下使用bootstrap4。本人非前端,如有問題請指正,謝謝。
bootstrap4中文文檔可參考:http://bs4.ntp.org.cn/
直接上代碼,html部分:
<div class="container">
<div class = "card-body">
<div class="row">
<div class="col-lg-2">
<img src="/vendor/img/qq1.jpg" class="img-thumbnail">
</div>
<div class="col-lg-10">
<div>
<span class="text-secondary"style="font-size:17px;">ID:[[${profile.userId}]]</span>
</div>
<div>
<span style="margin-right:16px;">關注 1 </span><span>粉絲1</span>
</div>
<hr>
<div class="commom-info">
昵稱:<span>[[${profile.nickname}]]</span>
<span id="mod-info" class="float-right text-primary" style="cursor:pointer" data-toggle="modal" data-target="#accountModal">修改資料</span>
</div>
<!-- ...省略 -->
</div>
</div>
</div>
</div>
<!-- modal -->
<div class="modal fade" id="accountModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="myModalLabel">修改資訊</h3>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<form id="updateForm" method="post" class="form-inline">
<input id="userId" name="userId" type="hidden" th:value="${profile.userId}"/>
<div class="input-group input-group-sm col-lg-6" style="margin-bottom:1rem;">
<label for="nickname" >昵稱:</label>
<input id="nickname" name="nickname" type="text" class="form-control" th:value="${profile.nickname}" required/>
</div>
<div class="col-12"></div>
<div class="input-group input-group-sm col-lg-4" style="margin-bottom:1rem;">
<label for="sex" >性别:</label>
<select id="sex" name="sex" class="form-control" th:value="${profile.sex}">
<option value="" style="display: none">未知</option>
<option value="1" th:selected="${profile.sex==1}">男</option>
<option value="0" th:selected="${profile.sex==0}">女</option>
</select>
</div>
<div class="col-12"></div>
<div class="col-lg-8 " onmouseover="addButton();" onmouseout="removeButton();">
<div class="row">
<div id="datetimepicker" class="input-group input-group-sm date col-lg-9" style="margin-bottom:1rem;" >
<label for="birthday" >生日:</label>
<input id="birthday" name="birthday" type="text" class="form-control" th:value="${#dates.format(profile.birthday, 'yyyy-MM-dd')}"/>
<span class="input-group-append input-group-addon" >
<i class="fa fa-calendar input-group-text" style="top:0px;" aria-hidden="true" ></i>
</span>
</div>
<div class="col-lg-3" style="padding-left:0px;top:4px;">
<i id="removeButton" class="glyphicon glyphicon-remove text-secondary" hidden="true" onclick="clearDate();"></i>
</div>
</div>
</div>
<div class="col-12"></div>
<div class="input-group input-group-sm col-lg-6" style="margin-bottom:1rem;">
<label for="occupation" >職業:</label>
<input id="occupation" name="occupation" type="text" class="form-control" th:value="${profile.occupation}"/>
</div>
<div class="col-12"></div>
<div class="input-group input-group-sm col-lg-12" style="margin-bottom:1rem;">
<label for="address" >位址:</label>
<select id="province" name="province" class="form-control" th:onchange="getCitys(this,'city');" style="margin-right:.5rem">
<option value="">--選擇省--</option>
<option th:each="province:${map['provinces']}" th:value="${province.code}" th:selected="${profile.province==province.code}">
[[${province.name}]]
</option>
</select>
<select id="city" name="city" class="form-control" th:onchange="getCitys(this,'county');" style="margin-right:.5rem">
<option value="">--選擇市--</option>
<option th:each="city:${citys}" th:value="${city.code}" th:selected="${profile.city==city.code}">
[[${city.name}]]
</option>
</select>
<select id="county" name="county" class="form-control" style="margin-right:.5rem">
<option value="">--選擇縣--</option>
<option th:each="county:${countys}" th:value="${county.code}" th:selected="${profile.county==county.code}">
[[${county.name}]]
</option>
</select>
</div>
<div class="col-12"></div>
<div class="input-group input-group-sm col-lg-12" style="margin-bottom:1rem;">
<label for="brief" >簡介:</label>
<textarea id="brief" name="brief" class="form-control">[[${profile.brief}]]</textarea>
</div>
<div class="col-12"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">關閉</button>
<button type="button" name="submit" class="btn btn-primary" onclick="update();">送出更改</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal -->
</div>
先完成模态框的綁定,點選 立即修改 就會彈出。通過thymeleaf th:value屬性或者[[${data}]]來初始化背景傳輸的資料。
這裡還有個問題,如果在模态框修改input值之後,沒有送出至背景,直接關閉模态框,再次打開時會是修改後的值,這樣顯示出的資料與原始資料有出入,使用者體驗不好,是以再每次打開對模态框的值進行初始化。上代碼:
<script th:inline="javascript">
$('#accountModal').on('show.bs.modal', function (e) {
$('#nickname').val([[${profile.nickname}]]);
$('#nickname').tooltip('dispose').removeClass('error');
$('#sex').val([[${profile.sex}]]);
$('#birthday').val([[${#dates.format(profile.birthday, 'yyyy-MM-dd')}]]);
$('#occupation').val([[${profile.occupation}]]);
$('#brief').val([[${profile.brief}]]);
$('#province').val([[${profile.province}]]);
getCitys($('#province'),'city');//這行代碼暫不考慮
$('#city').val([[${profile.city}]]);
getCitys($('#city'),'county');//這行代碼暫不考慮
$('#county').val([[${profile.county}]]);
});
</script>
‘show.bs.modal’是模态框打開之前觸發的事件,js中使用thymeleaf文法,務必加上 th:inline="javascript"。
考慮到每次修改完成後隻是更新使用者的資料,name重新整理整個頁面看起來就不那麼好了,是以本人采用局部重新整理。上網找了好久,網上推薦使用.load()方法。
$("#accountModal").modal('hide');
$.ajax({
type:'post',
url:'/user/profile',
contentType: 'application/json',
data:JSON.stringify($('#updateForm').formToJSON()),
success :
function(jsonData) {
if(jsonData.success){
$("div.modal-backdrop").remove();//有用
$('#main-content').load("/user/profile/module");
return;
}else {
$("#tip").tooltip({
title:jsonData.message,
placement:"auto",
template:'<div class="tooltip" role="tooltip"><div></div><div class="tooltip-inner"></div></div>'
});
$("#tip").tooltip("show");
setTimeout(function(){
$("#tip").tooltip('dispose');
},1000);
return;
}
},
});
$('#main-content').load("/user/profile/module"); $('#main-content')為要重新整理的元素位置,load(url)将傳回的頁面渲染到main-content。是以load傳回的頁面也應該是原來的大小,也就是去除導航欄等等的,不然會出現俄羅斯套娃。
<div id="main-content">
<div class="card" th:fragment="main-content">
</div>
</div>
每次局部重新整理,這裡也就是重新整理main-content部分,頁面傳回的html就是th:fragment所包含的。後端代碼:
@GetMapping("/user/profile/module")
public String module(Model model) {
SysUser user = getUser();
Profile profile = profileService.getById(user.getId());
tranName(profile);
Map<String, List<Object>> map = resourceRespository.getAllGroup(CnDivisionResourceLoaderImpl.LOADER);
model.addAttribute("profile", profile);
model.addAttribute("provinces", map.get("provinces"));
model.addAttribute("citys", map.get(profile.getProvince()));
model.addAttribute("countys", map.get(profile.getCity()));
model.addAttribute("map", map);
return "user/profile::main-content";
}
"user/profile::main-content 其中user/profile是你要傳回的html的位置,main-content 為它内部th:fragment屬性所包含的内容。這樣就隻重新整理main-content部分,而不是整個頁面。該傳的參數還是用通過Model傳出。
前面代碼中提到的$("div.modal-backdrop").remove();//有用,這是因為.load局部重新整理的時候,由于頁面的沖突,有時候模态框的遮罩窗還沒又消失就頁面重新整理了,遮罩會覆寫在上層,是以手動清除。
由于局部重新整理時重新加載的元素,原來的綁定事件會失效,是以綁定的元件和插件都得重新綁定(本人不知道有什麼其他的解決方式),比如這裡使用的datetimepicke日期插件,局部重新整理後,打開模态框,月曆插件失效不顯示。是以采用jquery的.load(url,data,function),修改代碼如下:
<script th:inline="javascript">
//隻有這部分代碼,局部重新整理後會失效
$('#datetimepicker').datetimepicker({
language: "zh-CN",
format: "yyyy-mm-dd",//顯示格式
minView: 2,//設定隻顯示到月份
initialDate: new Date(),//初始化目前日期
autoclose: true,//選中自動關閉
todayBtn: true, //顯示今日按鈕
pickerPosition: "bottom-left",
});
$.ajax({
type:'post',
url:'/user/profile',
contentType: 'application/json',
data:JSON.stringify($('#updateForm').formToJSON()),
success :
function(jsonData) {
if(jsonData.success){
$("div.modal-backdrop").remove();//消除遮罩
$('.datetimepicker').remove();//消除上次的月曆元素,否則會一直添加新的,可以F12看看
$('#main-content').load("/user/profile/module",function(){
$('#datetimepicker').datetimepicker({
language: "zh-CN",
format: "yyyy-mm-dd",//顯示格式
minView: 2,//設定隻顯示到月份
initialDate: new Date(),//初始化目前日期
autoclose: true,//選中自動關閉
todayBtn: true, //顯示今日按鈕
pickerPosition: "bottom-left",
});
});
return;
}else {
$("#tip").tooltip({
title:jsonData.message,
placement:"auto",
template:'<div class="tooltip" role="tooltip"><div></div><div class="tooltip-inner"></div></div>'
});
$("#tip").tooltip("show");
setTimeout(function(){
$("#tip").tooltip('dispose');
},1000);
return;
}
},
});
</script>
這樣月曆插件也能正常使用了。
如果模态框不放在局部重新整理的頁面内,模态框綁定的插件能正常使用,但是模态框内的資料不會跟着重新整理。當然這裡應該有更好的方法,或者前端的其他架構有更好的處理方式,由于本人非前端,自己做頁面時自己摸索,如有問題歡迎讨論。如需轉載,請注明出處,敲代碼不容易啊。