freemarker+jstl自定义标签实现动态表单的显示

上一篇文章中,已经对freemarker做了简单的了解;动态表单的概念大家也应该不陌生了,在《浅析动态表单》文章中已经做了一定的分析;jstl自定义标签也比较熟悉了,在此之前已经使用多次了。今天我们就使用freemarker+jstl自定义标签实现动态表单的显示。

下面是我总结的使用动态表单的主要步骤,大家做个参考:


1、定义Map对象

本例在SSH项目里面实现,所以需要配置ActionForm,Document为本例的应用,其对应的ActionForm中另外添加类型为Map的props属性,用来获得与设置模板的变量:

public class DocumentActionForm extends ActionForm {
	private int id;
	/**
	 * 页面上通过:
	 * 
	 * 			------->getProps().put(KEY,value)
	 */
	private Map props = new HashMap();
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Map getProps() {
		return props;
	}
	public void setProps(Map props) {
		this.props = props;
	}
}



2、定义模板

我们将模板都定义成.ftl文件,便于嵌套使用。下面列出了本例子当中的一些模板:


document_form.ftl:该模板定义表单域内容,也就是说,本例子主要通过该模板进行动态显示。根据用户相应的操作,该模板会根据fieldInput中的template属性,调用不同的子模板。


<#assign i = 0>
<#list form.fields as field>
	<#assign i = i + 1>
	<#if field_index % 2 = 0>
	
	<#if i = 2 || !field_has_next>
	<#assign i = 0>
	
${field.fieldLabel} <#include "${field.fieldInput.template}">


下面分别是file.ftl、select.ftl和text.ftl对应的子模板:





3、读取模板的方法:

FreeMarkerManager类里面定义了加载模板、设置对象包装器、设置异常处理器等一系列模板处理的步骤,也就是包含了对对模板的处理。

public class FreeMarkerManager {
	private static Configuration cfg =new Configuration();
	static{
		//定义模板的位置:从类路径中,相对于FreeMarkerManager所在的路径加载模板
		cfg.setTemplateLoader(new ClassTemplateLoader(FreeMarkerManager.class, "templates"));
		//设置对象包装器
		cfg.setObjectWrapper(new DefaultObjectWrapper());
		//设置异常处理器
		cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
	}
	public static Configuration getConfiguration(){
		return cfg;
	}
}


4、JSTL自定义函数的实现

本方法里面得到模板配置对象,对模板进行解释,进行输出。

/**
 * 用于freemarker的jstl界面显示函数
 * @author lzq
 *
 */
public class DynaFormFunction {
	private static FormManager formManager;
	private static String defaultTemplate="document_form.ftl"; 
	public static String form(int workflowId){
		try {
			//查找表单定义
			FlowForm form = formManager.findForm(workflowId);
			if (form == null) {
				return null;
			}
			//得到模板配置
			Configuration cfg =FreeMarkerManager.getConfiguration();
			Template template = null;
			if (form.getTemplate() == null || form.getTemplate().trim().equals("")) {
				template = cfg.getTemplate(defaultTemplate);
			}else {
				template = cfg.getTemplate(form.getTemplate());
			}
			//最终输出的位置
			Writer out = new StringWriter();
			//数据模型
			Map rootMap = new HashMap();
			rootMap.put("form", form);
			//模板引擎,解释模板
			template.process(rootMap, out);
			return out.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	public void setFormManager(FormManager formManager) {
		DynaFormFunction.formManager = formManager;
	}
	public void setDefaultTemplate(String defaultTemplate) {
		DynaFormFunction.defaultTemplate = defaultTemplate;
	}
}


JSTL自定义标签的对应的配置my.tld文件:



  1.1
  my
  http://www.lzq.com/functions
  
    form
    com.lzq.web.DynaFormFunction
    java.lang.String form(int)
  


页面调用JSTL:

${my:form(documentForm.workflowId) }


如此,便能在页面上显示动态的表单了。

你可能感兴趣的:(【Web语言】)