通过自定义标签用数据字典实现下拉框

当页面需要用到多个下拉框时,数据字典结合自定义标签可以为我们带来很大方便。自定义标签可以重复使用,相当于框架简化我们的代码。

下面总结一下关于这块我的套路。首先数据库表如下:

然后肯定得有查询字段的方法,下边我把我的代码(折叠形式)附上,仅供大家参考。

public interface IDictionaryManager {
    List<Dictionary> dictionaries(String groupValue);
    void addDataToMemory();
    Dictionary dictionary(int itemKey, String groupValue);
}

IDictionaryManager

//@Component Because the @PostConstruct will load data to Dictionary, so don‘t add the @Component(will load two times)
public class DefaultDictionaryManager implements IDictionaryManager {
    private static final Logger LOOGER = LoggerFactory.getLogger(DefaultDictionaryManager.class);

    // Logger info
    private static final String LOGGER_INFO_LOAD_DIC = "Loading Dictionary to cache.";
    private static final String LOGGER_INFO_CACHE_WITH_MAP_GROUP_BY_GROUPKEY =
            "Cache the dictionary with map group by groupKey.";
    private static final String LOGGER_INFO_CACHE_WITH_GROUPKEY_SUCCESS =
            "Cache the dictionary with map group by groupKey success.";

    // Logger error
    private static final String LOGGER_ERROR_NO_DICTIONARY_CACHED =
            "No Dictionary cached in the map, Please sure your groupKey";

    @Autowired
    private IDictionaryRepository repository;

    private static final Map<String, List<Dictionary>> CACHE = Maps.newHashMap();
    private static List<Dictionary> dictionaries = null;

    private static DefaultDictionaryManager manager = new DefaultDictionaryManager();

    private DefaultDictionaryManager() {}

    public static DefaultDictionaryManager getInstance() {
        //判断manager的实例是否为空,如果为空创建一个实例,部不为空返回实例。
        Optional<DefaultDictionaryManager> optional = Optional.fromNullable(manager);
        if (!optional.isPresent()) {
            return new DefaultDictionaryManager();
        }

        return manager;
    }

    @PostConstruct
    public void initCache() {
        dictionaries = repository.selectAll();
        addDataToMemory();
    }

    /**
     * 获得数据字典中对应group的值
     *
     * @param groupKey 数据字典中的groupKey
     * @return 如果存在这个group,返回这个group中的值,如果不存在返回一个empty List
     */
    public List<Dictionary> dictionaries(String groupKey) {
        List<Dictionary> dictionaries = CACHE.get(groupKey);

        Optional<List<Dictionary>> optional = Optional.fromNullable(dictionaries);
        if (!optional.isPresent()) {
            dictionaries = new ArrayList<Dictionary>();
        }

        return dictionaries;
    }

    //把封装到list里的每一组数据按groupvalue分类重新封装到不同的list中,然后封装到map里
    public void addDataToMemory() {
        for (Dictionary dictionary : dictionaries) {
            String groupValue = dictionary.getGroupValue();
            List<Dictionary> groupDic = CACHE.get(groupValue);

            Optional<List<Dictionary>> optional = Optional.fromNullable(groupDic);
            if (!optional.isPresent()) {
                groupDic = new ArrayList<Dictionary>();
            }

            groupDic.add(dictionary);
            CACHE.put(groupValue, groupDic);
        }
    }

    public Dictionary dictionary(int itemKey, String groupValue) {
        List<Dictionary> dictionaries = CACHE.get(groupValue);

        for (Dictionary dictionary : dictionaries) {
            if (dictionary.getItemKey() == itemKey) {
                return dictionary;
            }
        }

        return new Dictionary();
    }
}

DefaultDictionaryManager

现在有了后台支撑,就可以进行jsp的操作了。在这块我自定义了dicselect标签,这样在每次使用下拉框的时候使用自定义标签就好了,省去了再重复编写下拉框的步骤。在这里就得说一说.tag和.tld文件。前者是属于jsp文件后者是属于xml文件。

1.对于tag文件 
<%@ taglib prefix="ui" tagdir="/WEB-INF/tags" %> 
其中的tags是个目录,里面有若干tag文件。 
但使用<ti:XXXX>时,目录WEB-INF/tags下,必然有个XXXX.tag文件与之对应。

2.对于tld文件 
在jsp中可以引用TLD文件,如 
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%> 
但是这个http://struts.apache.org/tags-html对应着什么呢? 
jsp会在当前目录的\WEB-INF下找所有tld文件,确认这个URL对应哪个TLD文件。 
当找到struts-html.tld文件时,发现其中的内与这个URL对应。 
但使用<html:YYYYY>时,这个TLD文件中必然有个YYYY项与之对应。

在用户在jsp页面中使用标签时,系统首先会先到web.xml文件中的 <taglib>标签中的《taglib-uri》和《taglib-location》这两对标签找到相对应的扩展名为tld文件,然后在 tld文件中的映射再找到相对应的taglib类。

下边附上我的配置代码:

<%@tag pageEncoding="UTF-8"%>
<%@ taglib prefix="dict" uri="http://www.lgb.com/tags/dic" %>
<%@ attribute name="id" type="java.lang.String" required="false"%>
<%@ attribute name="name" type="java.lang.String" required="true"%>
<%@ attribute name="key" type="java.lang.String" required="true"%>
<%@ attribute name="value" type="java.lang.String" required="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%
    String tagId = id;
    String tagName = name;

    if (id == null){
        tagId = tagName;
    }

    request.setAttribute("tagId", tagId);
    request.setAttribute("tagName", tagName);
%>

<select class="form-control" id="${tagId}" name="${name}">
    <c:forEach items="${dict:list(key)}" var="dict" varStatus="status">
        <c:choose>
             <c:when test="${status.first eq true}">
                <c:choose>
                       <c:when test="${dict.itemKey eq value}">
                        <option selected="selected" value="${dict.itemKey}" >${dict.itemValue}</option>
                       </c:when>
                       <c:otherwise>
                           <option value="${dict.itemKey}">${dict.itemValue}</option>
                       </c:otherwise>
                   </c:choose>
            </c:when>
               <c:otherwise>
                   <c:choose>
                       <c:when test="${dict.itemKey eq value}">
                        <option selected="selected" value="${dict.itemKey}" >${dict.itemValue}</option>
                       </c:when>
                       <c:otherwise>
                           <option value="${dict.itemKey}" >${dict.itemValue}</option>
                       </c:otherwise>
                   </c:choose>
               </c:otherwise>
        </c:choose>
    </c:forEach>
</select>

dicselect.tag

<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
         http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
        version="2.0">

    <tlib-version>1.0</tlib-version>
    <short-name>DictionaryTag</short-name>
    <uri>http://www.lgb.com/tags/dic</uri>

    <function>
        <name>list</name>
        <function-class>com.lgb.arc.web.tag.DictionaryTag</function-class>
        <function-signature>java.util.List list(java.lang.String)</function-signature>
    </function>

    <function>
        <name>show</name>
        <function-class>com.lgb.arc.web.tag.DictionaryTag</function-class>
        <function-signature>java.lang.String show(java.lang.String, int)</function-signature>
    </function>
</taglib>

dictionary.tld

<%@tag pageEncoding="UTF-8"%>
<%@ taglib prefix="dict" uri="http://www.lgb.com/tags/dic" %>
<%@ attribute name="groupValue" type="java.lang.String" required="true"%>
<%@ attribute name="itemKey" type="java.lang.Integer" required="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

${dict:show(groupVaule, itemKey)}

diclabel.tag

<%@tag pageEncoding="UTF-8"%>
<%@ taglib prefix="dict" uri="http://www.lgb.com/tags/dic" %>
<%@ attribute name="groupValue" type="java.lang.String" required="true"%>
<%@ attribute name="itemKey" type="java.lang.Integer" required="true"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<td>${dict:show(groupValue, itemKey)}</td>

dictd.tag

以及还要在web.xml文件里进行配置,下边附上我的配置代码:

<jsp-config>  <taglib>    <taglib-uri>http://www.lgb.com/tags/dic</taglib-uri>    <taglib-location>/WEB-INF/tags/dictionary.tld</taglib-location>  </taglib></jsp-config>

这样自定义标签就完成了。我们就可以在jsp页面中使用我们的自定义标签。

(本文代码 仅供参考)

咆哮吧! 青春!

时间: 2024-08-21 19:09:17

通过自定义标签用数据字典实现下拉框的相关文章

自定义弹出窗口,实现可输入可过滤自动选择下拉框

/** jQuery dialog windows * author : piyg Copyright(c) : 2014-09-01 09:28 Version 1.0-pre 自定义定时定频弹出窗口: 用法: 在自身jsp页面调用 showDialog(title,fn1,fn2),showProcessDialog(title,fn1,fn2)方法. title: 自定义窗口头信息. fn1 ,fn2 自定义回调函数,分别绑定2个按钮事件 fn1: "继续提交"按钮事件. fn2

select、autocomplete标签下拉框

select标签为标准的下拉框,生成HTML里的<select>标签.qutocomplete标签为具有自动完成功能的下拉框,能根据所填的内容筛选下拉框内容.使用autocomplete标签必须使用Ajax主题,因为它用到了DOJO的JavaScript库. 1 <body> 2 <% 3 List<String> provinceList = new ArrayList<String>(); // List对象,存放省份 4 provinceList

最完美的select下拉框美化

很多人为 select 的诸多不完善而头痛,如无法自定义样式. IE6 中无法被浮动层遮住等等.下面介绍一款堪称最完美的下拉框组件: UU 人下拉框 特点 1 :美化的并且可自定义的外观 UU 人下拉框使用 JS 进行渲染.当页面引入了脚本和 CSS 后,页面中的下拉框都会变成如下外观:精心开发5年的UI前端框架! 该外观是由 CSS 和图片控制.通过修改 CSS 可以很方便地实现更改外观. UU 人下拉框不存在 IE6 中无法被浮动层遮住等问题. 特点 2 :使用简单 UU 人下拉框代码写法与

layui下拉框实现级联

<!DOCTYPE html><html><head> <meta charset="utf-8" /> <link href="../layui/css/layui.css" rel="stylesheet" /> <script src="../layui/layui.js"></script> <script src=".

Struts2 自定义下拉框标签Tag

自定义标签主要包括三个步骤: 1.编写java类,继承TagSupport类: 2.创建tld文件,影射标签名和标签的java类: 3.jsp页面引入tld. 例子:自定义下拉框标签 如果页面上有下拉选择框,通常最好的解决方法是使用数据字典,因为有可能多个页面 使用同一个下拉框,便于后台统一维护. 自定义Tag类 import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.

自定义Angular指令与jQuery实现的Bootstrap风格数据双向绑定的单选&amp;多选下拉框

先说点闲话,熟悉Angular的猿们会喜欢这个插件的. 00.本末倒置 不得不承认我是一个喜欢本末倒置的人,学生时代就喜欢先把晚交的作业先做,留着马上就要交的作业不做,然后慢悠悠做完不重要的作业,卧槽,XX作业马上要交了,赶紧补补补.如今做这个项目,因为没找到合适的多选下拉Web插件,又不想用html自带的丑陋的<select multiple></select>,自己花了一整天时间做了一个.或许这样占用的主要功能开发的时间,开发起来会更有紧迫感吧.感觉自己是个抖M自虐倾向,并且伴

elect美化自定义下拉框样式

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>张力仪</title></he

自定义控件基础01_菜单轮__viewPager_下拉框_自定义开关

1,自定义控件分类: 1.1组合控件:由安卓中原生的控件组合起来,配合动画达成的效果 1.2自定义控件 1.3组合控件案例演示: 案例:优酷菜单demo 三层圆环,按下menu键会通过动画效果消失在界面,点击小房子和中层圆环,最外层圆环消失 ①布局实现: 三层相对布局相互叠加(因为图片背景是透明的,所以可以叠加显示) 由于三个布局是叠加显示的,所以这个菜单选项要使用一个占据焦点比较强的(不然有可能点击不到)ImageButton控件 控件上background=”@android:color/t

selenium处理select标签的下拉框

有时候我们会碰到<select></select>标签的下拉框.直接点击下拉框中的选项不一定可行.Selenium专门提供了Select类来处理下拉框. <select id="status" class="form-control valid" onchange="" name="status"> <option value=""></option&g