在這裏會簡述及展現,部分表單控件如何應用以及後端數據如何處理和應用。html
框架使用Spring封裝的一系列表單標籤。前端
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
涉及方法:java
<!-- DictUtils --> <function> <description>獲取字典標籤</description> <name>getDictLabel</name> <function-class>com.thinkgem.jeesite.modules.sys.utils.DictUtils</function-class> <function-signature>java.lang.String getDictLabel(java.lang.String, java.lang.String, java.lang.String)</function-signature> <example>${fns:getDictLabel(value, type, defaultValue)}</example> </function> <function> <description>獲取字典標籤(多個)</description> <name>getDictLabels</name> <function-class>com.thinkgem.jeesite.modules.sys.utils.DictUtils</function-class> <function-signature>java.lang.String getDictLabels(java.lang.String, java.lang.String, java.lang.String)</function-signature> <example>${fns:getDictLabels(values, type, defaultValue)}</example> </function> <function> <description>獲取字典值</description> <name>getDictValue</name> <function-class>com.thinkgem.jeesite.modules.sys.utils.DictUtils</function-class> <function-signature>java.lang.String getDictValue(java.lang.String, java.lang.String, java.lang.String)</function-signature> <example>${fns:getDictValue(label, type, defaultValue)}</example> </function> <function> <description>獲取字典對象列表</description> <name>getDictList</name> <function-class>com.thinkgem.jeesite.modules.sys.utils.DictUtils</function-class> <function-signature>java.util.List getDictList(java.lang.String)</function-signature> <example>${fns:getDictList(type)}</example> </function> <function> <description>獲取字典對象列表</description> <name>getDictListJson</name> <function-class>com.thinkgem.jeesite.modules.sys.utils.DictUtils</function-class> <function-signature>java.lang.String getDictListJson(java.lang.String)</function-signature> <example>${fns:getDictListJson(type)}</example> </function>
文件位置:com.thinkgem.jeesite.modules.sys.utils.DictUtils.javagit
/** * Copyright © 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved. */ package com.thinkgem.jeesite.modules.sys.utils; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.thinkgem.jeesite.common.mapper.JsonMapper; import com.thinkgem.jeesite.common.utils.CacheUtils; import com.thinkgem.jeesite.common.utils.SpringContextHolder; import com.thinkgem.jeesite.modules.sys.dao.DictDao; import com.thinkgem.jeesite.modules.sys.entity.Dict; /** * 字典工具類 * @author ThinkGem * @version 2013-5-29 */ public class DictUtils { private static DictDao dictDao = SpringContextHolder.getBean(DictDao.class); public static final String CACHE_DICT_MAP = "dictMap"; public static String getDictLabel(String value, String type, String defaultValue){ if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(value)){ for (Dict dict : getDictList(type)){ if (type.equals(dict.getType()) && value.equals(dict.getValue())){ return dict.getLabel(); } } } return defaultValue; } public static String getDictLabels(String values, String type, String defaultValue){ if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(values)){ List<String> valueList = Lists.newArrayList(); for (String value : StringUtils.split(values, ",")){ valueList.add(getDictLabel(value, type, defaultValue)); } return StringUtils.join(valueList, ","); } return defaultValue; } public static String getDictValue(String label, String type, String defaultLabel){ if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(label)){ for (Dict dict : getDictList(type)){ if (type.equals(dict.getType()) && label.equals(dict.getLabel())){ return dict.getValue(); } } } return defaultLabel; } public static List<Dict> getDictList(String type){ @SuppressWarnings("unchecked") Map<String, List<Dict>> dictMap = (Map<String, List<Dict>>)CacheUtils.get(CACHE_DICT_MAP); if (dictMap==null){ dictMap = Maps.newHashMap(); for (Dict dict : dictDao.findAllList(new Dict())){ List<Dict> dictList = dictMap.get(dict.getType()); if (dictList != null){ dictList.add(dict); }else{ dictMap.put(dict.getType(), Lists.newArrayList(dict)); } } CacheUtils.put(CACHE_DICT_MAP, dictMap); } List<Dict> dictList = dictMap.get(type); if (dictList == null){ dictList = Lists.newArrayList(); } return dictList; } /** * 返回字典列表(JSON) * @param type * @return */ public static String getDictListJson(String type){ return JsonMapper.toJsonString(getDictList(type)); } }
頁面數據編輯和回顯:github
單選按鈕(單選): <form:radiobuttons path="check" items="${fns:getDictList('yes_no')}" itemLabel="label" itemValue="value" htmlEscape="false"/> 下拉框(單選): <form:select path="check" class="input-xlarge "> <form:option value="" label=""/> <form:options items="${fns:getDictList('yes_no')}" itemLabel="label" itemValue="value" htmlEscape="false"/> </form:select> 複選框(多選): <form:checkboxes path="goodsTypeFormatDictList" items="${fns:getDictList('map_goods_format')}" itemLabel="label" itemValue="value" htmlEscape="false"/>
頁面數據顯示:spring
單選按鈕和單選下拉框: ${fns:getDictLabel(對象.屬性, 'yes_no', '')} 複選框: ${fns:getDictLabels(對象.屬性, 'map_goods_format', '')}
控件屬性說明sql
Radio和Select比較簡單,由於存儲的都是單一值,在數據編輯方面並無須要注意的地方,只須要稍微注意一下所封裝的數據類型對應調整就能夠了。數據庫
CheckBox在數據回顯和提交時須要特別注意一下,由於封裝的形式和提交的方式稍微會有所調整,在此我從新以自定義對象舉例說明:apache
一共有3張表,TravelRout,旅遊路線表;ScenicArea,景區信息表;TravelRouteScenicArea,旅遊路線和景區信息關聯表,多對多的關係;後端
實體模型TravelRoute類中,須要ScenicArea屬性標識,用於封裝傳遞的多選數值:
private List<String> scenicAreaIdList = Lists.newArrayList(); //擁有的景區ID集合,用於數據回顯 private List<ScenicArea> scenicAreaList = Lists.newArrayList(); //擁有的景區源數據集合 public List<ScenicArea> getScenicAreaList() { return scenicAreaList; } public void setScenicAreaList(List<ScenicArea> scenicAreaList) { this.scenicAreaList = scenicAreaList; } @JsonIgnore public List<String> getScenicAreaIdList(){ List<String> scenicAreaIdList = Lists.newArrayList(); for(ScenicArea scenicArea : scenicAreaList){ scenicAreaIdList.add(scenicArea.getId()); } return scenicAreaIdList; } public void setScenicAreaIdList(List<String> scenicAreaIdList){ scenicAreaList = Lists.newArrayList(); for(String scenicAreaId : scenicAreaIdList){ ScenicArea scenicArea = new ScenicArea(); scenicArea.setId(scenicAreaId); scenicAreaList.add(scenicArea); } }
TravelRouteService類中,get方法須要獲取scenicAreaList集合進行數據填充,該數據源是利用scenicAreaId查詢TravelRouteScenicArea獲得的集合,注意:
public TravelRoute get(String id) { TravelRoute travelRoute = travelRouteDao.get(id); List<ScenicArea> list = travelRouteDao.findTravelRouteScenicAreaByTR(id); travelRoute.setScenicAreaList(list); return travelRoute; }
TravelRouteController類中,還須要針對前端所有景區數據列表作一個屬性回顯,allScenicAreas,即查詢所有景區信息列表:
@RequiresPermissions("hnly:travelRoute:view") @RequestMapping(value = "form") public String form(TravelRoute travelRoute, Model model) { model.addAttribute("travelRoute", travelRoute); model.addAttribute("allScenicAreas", scenicAreaService.findList(null)); return "modules/hnly/travelRouteForm"; }
前端JSP:
<div class="control-group"> <label class="control-label">途徑景區:</label> <div class="controls"> <form:checkboxes path="scenicAreaIdList" items="${allScenicAreas}" itemLabel="name" itemValue="id" htmlEscape="false" class="required"/> </div> </div>
執行新增或更新操做時,TravelRouteService類中,須要作響應的修改,先刪除聯合表中的數據,再添加:
@Transactional(readOnly = false) public void save(TravelRoute travelRoute) { if (StringUtils.isBlank(travelRoute.getId())){ travelRouteDao.insert(travelRoute); } else { travelRouteDao.update(travelRoute); } travelRouteDao.deleteTravelRouteScenicArea(travelRoute); travelRouteDao.insertTravelRouteScenicArea(travelRoute); }
TravelRouteDao,在聯合表中插入數據須要注意:
<!-- 刪除推薦旅遊路線和景區關聯表數據 --> <update id="deleteTravelRouteScenicArea"> DELETE FROM hnly_travel_route_scenic_area WHERE hnly_travel_route_id = #{id} </update> <!-- 插入推薦旅遊路線和景區關聯表數據 --> <insert id="insertTravelRouteScenicArea" useGeneratedKeys="true" keyProperty="id"> INSERT INTO hnly_travel_route_scenic_area(hnly_travel_route_id, hnly_scenic_area_id) <foreach collection="scenicAreaList" item="scenicArea" separator=" union all "> SELECT #{id}, #{scenicArea.id} <if test="dbName != 'mssql'"> FROM dual </if> </foreach> </insert> <!-- 根據路線ID獲取推薦旅遊路線關聯的景區數據 --> <select id="findTravelRouteScenicAreaByTR" resultType="ScenicArea"> SELECT a.hnly_scenic_area_id AS "id", sa.name AS "name", sa.addr AS "addr", sa.lat AS "lat", sa.lon AS "lon", sa.hnly_panoramic_id AS "panoramic.id" FROM hnly_travel_route_scenic_area a LEFT JOIN hnly_scenic_area sa ON sa.id = a.hnly_scenic_area_id WHERE a.hnly_travel_route_id = #{id} </select>
圖樣圖森破
圖片及文件上傳均使用的CF控件,在頁面編輯的同時就已經將圖片和文件數據上傳完了,最後表單提交的時候是一串上傳地址,因此後臺數據格式爲String字符串類型便可。
<div class="control-group"> <label class="control-label">圖片:</label> <div class="controls"> <form:hidden id="pic" path="pic" htmlEscape="false" maxlength="255" class="input-xlarge"/> <sys:ckfinder input="pic" type="images" uploadPath="/hnly/activity" maxHeight="100" maxWidth="100"/> </div> </div> <div class="control-group"> <label class="control-label">文件:</label> <div class="controls"> <form:hidden id="fil" path="fil" htmlEscape="false" maxlength="255" class="input-xlarge"/> <sys:ckfinder input="fil" type="files" uploadPath="/hnly/activity" selectMultiple="true"/> </div> </div>
由兩部分組成,form:hidden隱藏文本和sys:ckfinder控件,type分爲兩種images和files;uploadPath爲上傳路徑;selectMultiple爲是否爲文件模式的是否容許多文件上傳;maxHeight和maxWeight爲圖片模式使用的回顯圖片長寬;
若是系統中使用到時間數據格式是多樣化的,如年月日/日分等等,建議後臺和數據庫的時間數據格式設置爲文本,在頁面中取消時間格式化就行了,原系統中如何設置請自行參考,這裏我只貼修改後的。
<div class="control-group"> <label class="control-label">時間:</label> <div class="controls"> <input name="publishTime" type="text" readonly="readonly" maxlength="20" class="input-medium Wdate " value="${activity.publishTime}" onclick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',isShowClear:false});"/> </div> </div>
value,爲提交和回顯屬性,這裏我已經將格式化方法去除,再也不作格式化,且數據庫和後臺類型爲字符串類型,若是使用原格式化方法處理則必須統一數據格式,不能使用字符串類型,去除後可以使用。WdatePicker爲控件調用方式;dataFmt,可設置多種時間顯示方法;
<div class="control-group"> <label class="control-label">標題:</label> <div class="controls"> <form:input path="title" htmlEscape="false" maxlength="255" class="input-xlarge "/> </div> </div>
<div class="control-group"> <label class="control-label">內容:</label> <div class="controls"> <form:textarea path="content" htmlEscape="false" rows="4" class="input-xxlarge "/> </div> </div>