Jeesite 表单控件使用方法 Spring-MVC form、JSTL1.1

在这里会简述及展示,部分表单控件如何应用以及后端数据如何处理和应用。

框架使用Spring封装的一系列表单标签。

Spring MVC form声明

<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>

JSTL 1.1声明

  • 文件位置:WEB-INF/tlds/fns.tld

    涉及方法:

<!-- 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>

DictUtils字典工具类

    文件位置:com.thinkgem.jeesite.modules.sys.utils.DictUtils.java

/**
 * Copyright &copy; 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));
	}
	
}

Radio单选框、Select下拉框、CheckBox复选框

  • 数据库存储:Varchar
  • 后台数据:String
  • 前端回显列表数据集合:List<Dict>
  • 前端回显目标数据:Radio-String;Select-String;CheckBox-List<String>或List<Dict>
  • 前端提交:String

    页面数据编辑和回显:

单选按钮(单选):
<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"/>

    页面数据显示:

单选按钮和单选下拉框:
${fns:getDictLabel(对象.属性, 'yes_no', '')}
复选框:
${fns:getDictLabels(对象.属性, 'map_goods_format', '')}

    控件属性说明

  • path,属性名称或目标数据名称;
  • items,源数据集合,封装源数据类型为List<Dict>或自定义数据类型;
  • itemLabel,指定属性值为Dict对象的label属性或自定义;
  • itemValue,指定数值为Dict对象的value属性或自定义;

CheckBox-多选说明及案例

    Radio和Select比较简单,因为存储的都是单一值,在数据编辑方面并没有需要注意的地方,只需要稍微注意一下所封装的数据类型对应调整就可以了。

    CheckBox在数据回显和提交时需要特别注意一下,因为封装的形式和提交的方式稍微会有所调整,在此我重新以自定义对象举例说明:

    一共有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>

    图样图森破

154228_ZX5o_1262063.png

Ckfinder-图片及文件上传控件

    图片及文件上传均使用的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为图片模式使用的回显图片长宽;

WdatePicker-时间选择控件

    如果系统中使用到时间数据格式是多样化的,如年月日/日分等等,建议后台和数据库的时间数据格式设置为文本,在页面中取消时间格式化就好了,原系统中如何设置请自行参考,这里我只贴修改后的。

<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,可设置多种时间显示方法;

Input-普通文本

<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>

Textarea-多行文本

<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>

 

 

转载于:https://my.oschina.net/discussjava/blog/1558018

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值