该标签主要实现以下功能:当父下拉框的当前值发生变化时,会自动更新子下拉框的数据项。该标签也可以作为一般的下拉框来使用。以下列出详细的说明及其源代码:
一、标签属性说明
<cjm:chainSelect isTopSelect="true" name="org" entityName="Organization" keyField="orgId"
descField="name" childSelectName="uid" orderBy="orgId asc" allowEmpty="false"/>
<cjm:chainSelect name="uid" entityName="User" keyField="username" descField="fullname"
params="org.orgId=#PARENT_KEY#"/>
name:下拉框名称。
isTopSelect:指定是否是顶层下拉框,即联动是否从该下拉框开始。可选值为true 或 false,默认值为false。
entityName:指定下拉框数据的实体名称。
keyField:指定与下拉框KEY值绑定的字段。
descField:指定与下拉框DESC值绑定的字段。
orderBy:指定下拉框数据的排序字段。如orgId asc等。
params:指定下拉框数据过滤的参数键值对。格式:参数名1=参数值1&参数名2=参数值2&参数名3=参数值3等。被联动的下拉框引用父下拉框的当前值需要用"#PARENT_KEY#"来表示。
childSelectName:指定被联动的下拉框的名称。没有被联动的下拉框时,不需要设置该属性。
allowEmpty:指定下拉框是否允许空值。可选值为true 或 false。默认值为true。
cdata:指定控件的其他属性。比如,class、style等。
二、标签源代码
public class ChainSelectTag extends BaseBodyTagSupport {
private String name;
private String isTopSelect;
private String entityName;
private String keyField;
private String descField;
private String orderBy;
private String params;
private String childSelectName;
private String allowEmpty;
private String cdata;
......
public int doEndTag() throws JspException {
String currentValue = "";
try{
currentValue = CommonUtil.trim(getValueStack().findString(name));
//去掉两端的 & 符号
params = CommonUtil.trim(params);
if(CommonUtil.isNotEmpty(params)){
while(params.startsWith("&")){
params = params.substring(1);
}
while(params.endsWith("&")){
params = params.substring(0, params.length()-1);
}
params = TagUtil.translateVariables(params, getValueStack());
}
allowEmpty = CommonUtil.trim(allowEmpty);
if(CommonUtil.isEmpty(allowEmpty)) allowEmpty = "true"; //默认为true
}catch(Exception ex){
throw new JspException(ex);
}
Map dataModel = new HashMap();
dataModel.put("name", CommonUtil.trim(name));
dataModel.put("currentValue", CommonUtil.trim(currentValue));
dataModel.put("isTopSelect", CommonUtil.trim(isTopSelect));
dataModel.put("entityName", CommonUtil.trim(entityName));
dataModel.put("keyField", CommonUtil.trim(keyField));
dataModel.put("descField", CommonUtil.trim(descField));
dataModel.put("orderBy", orderBy);
dataModel.put("params", CommonUtil.trim(params));
dataModel.put("childSelectName", CommonUtil.trim(childSelectName));
dataModel.put("allowEmpty", allowEmpty);
dataModel.put("cdata", cdata);
try{
String ret = render(pageContext.getServletContext(), dataModel, "taglib/ChainSelect.ftl");
pageContext.getOut().println(ret);
}catch(Exception ex){
throw new JspException(ex);
}
return EVAL_PAGE;
}
}
三、标签模板源代码
<#assign paramStr = "">
<#if params?has_content>
<#assign paramList = params?split("&")>
<#list paramList as p>
<#assign paramStr = paramStr + "_CHAIN_PARAM_" + p>
<#if p_index lt (paramList?size-1)>
<#assign paramStr = paramStr + "&">
</#if>
</#list>
</#if>
<select name="${name}" entityName="${entityName?if_exists}" keyField="${keyField?if_exists}" descField="${descField?if_exists}" orderBy="${orderBy?if_exists}" currentValue="${currentValue?if_exists}" params="${paramStr}" allowEmpty="${allowEmpty}" ${cdata?if_exists} <#if childSelectName?has_content> childSelectName="${childSelectName?if_exists}"</#if>></select>
<#if isTopSelect?if_exists == "true">
<script language="javascript">
addInitChainSelectEvent('chainSelect("${name}", "${paramStr}")');
</script>
</#if>