现在的位置: 首页 > 综合 > 正文

JSP自定义标签实现多选下拉框

2012年11月22日 ⁄ 综合 ⁄ 共 10551字 ⁄ 字号 评论关闭

项目里用到了一个多选下拉框,懒得在网上找,自己试着写了个简单的先用着,贴出来给学习的童鞋参考下。

 

这段JS控制各种事件(multiSelect.js)

/**
* created by yuandong
* created date 2012-5-23
* last updated date 2012-6-8
*/
jQuery(document).ready(function()
{
    //Click event of select div
    $('.multiSelectDiv').click(function(e){
    	
    	var text = $(this).find('input[type=text]');
    	var hidden = $(this).find('input[type=hidden]');
    	var target = $(e.target); 	
    	
    	//If target is text
    	if(target.attr('type') == text.attr('type'))
    	{
    	    //Hide other div
    	    $('.multiSelectDiv').find('div').each(function(){
	    	    $(this).animate({opacity: 'hide'}, 300);
	    	});
    	
	    	var div = $(this).find('div');
	    	var offSet = text.offset();
	    	var left = offSet.left;
	    	var top = offSet.top;
	    	
	    	if(div.is(":visible"))
	    	{
	    	    div.animate({opacity: 'hide'}, 300);
	    	}
	    	else
	    	{
	    	   div.css({"top":top+20,"left":left}).animate({opacity:'show'}, 300);
	    	}
    	}
    	//If target is checkbox
    	else if(target.attr('type') == 'checkbox')
    	{
    	    var textVal = '';
    	    var hiddenVal = '';
    	    var selectDivObj = $(this);
    	    var curCheckboxCount = 0;
            var selectedCheckboxCount = 0;
    	    //Get value by selected checkbox
	    	$(this).find('input[type=checkbox][class!=selectAll]').each(function(){
	    	    
	    		if($(this).is(':checked'))
	    		{
	    		    textVal += $(this).parent().parent().find('span').text() + ',';
	    		    hiddenVal += $(this).val() + ',';
	    		    selectedCheckboxCount++;
	    		}
	    		//When exist checkbox not select,set 'select all' to not select 
	    		else
	    		{
	    		    selectDivObj.find('input[type=checkbox][class=selectAll]').attr('checked','');
	    		}
	    		curCheckboxCount++;
	    	});
	    	
	    	if(curCheckboxCount>0 && selectedCheckboxCount>0 && curCheckboxCount==selectedCheckboxCount)
	        {
	           selectDivObj.find('input[type=checkbox][class=selectAll]').attr('checked','true');
	        }
	    	
	    	text.val(textVal.substring(0,textVal.length-1));
	    	hidden.val(hiddenVal.substring(0,hiddenVal.length-1));
    	}
    	//If target is clearImg, clear text,hidden,and checkbox value
    	else if($(this).find('img').length>0  && target.attr('name') == 'clearImg')
    	{
    	    text.val('');
	    	hidden.val('');
	    	$(this).find('input[type=checkbox]').each(function(){
		       if($(this).is(":checked"))
		       {
		    	 $(this).attr("checked",'');
		       }
	    	});
    	}
    	//If target is selectImg, show select
    	else if($(this).find('img').length>0  && target.attr('name') == 'selectImg')
    	{
    	    text.click();
    	}
    });
    
    //Hide div when user click other area
    $('html').click(function(e){
    	//If not multi select div area, return 
    	if($(e.target).isChildAndSelfOf (".multiSelectDiv"))
    	{
    	    return;
    	}
    	//Else hide select div
    	else
    	{
	    	$('.multiSelectDiv').find('div').each(function(){
	    	    $(this).animate({opacity: 'hide'}, 300);
	    	});
    	}
    }); 
    
    //Select all items
    $('.selectAll').click(function(e){
        var all = $(this);
        all.parent().parent().parent().find('input[type=checkbox]').each(function(){
           if(all.is(":checked"))
           {
               $(this).attr("checked",'true');
           }
           else
           {
               $(this).attr("checked",'');
           }
        });
    });   
    
    //Check current elements 
    jQuery.fn.isChildAndSelfOf = function(b){ 
        return (this.closest(b).length > 0); 
    };
    
    //On init
    initMultiSelect();
    
});

//Init select
function initMultiSelect()
{
   $('.multiSelectDiv').each(function(){
       var hiddenVal = $(this).find('input[type=hidden]').val();
       var textVal = '';
       var curCheckboxCount = 0;
       var selectedCheckboxCount = 0;
       var selectDivObj = $(this);
       //Select checkBox and set up input value after do query
       if(hiddenVal != '')
       {
	       $(this).find('input[type=checkbox][class!=selectAll]').each(function(){
	    		if(hiddenVal.indexOf($(this).val()) != -1)
	    		{
	    		    $(this).attr('checked',true);
	    		    textVal += $(this).parent().parent().find('span').text() + ',';
	    		    selectedCheckboxCount ++;
	    		}
	    		curCheckboxCount ++;
	       });
	       $(this).find('input[type=text]').val(textVal.substring(0,textVal.length-1));
	       //If checkbox count of current select is equals selected checkbox count,checked 'select all' 
	       if(curCheckboxCount>0 && selectedCheckboxCount>0 && curCheckboxCount==selectedCheckboxCount)
	       {
	           selectDivObj.find('input[type=checkbox][class=selectAll]').attr('checked','true');
	       }
       }
       
       //Set up the width of the select div
       var textWidth = 0;
       var img1Width = 0;
       var img2Width = 0;
       
       var textObj = $(this).find('input[type=text]');
       textWidth = textObj.width();
       
       var img1Obj = $(this).find('img');
       var tempImgObj = new Image(); 
       tempImgObj.src = img1Obj.attr( 'src');
       img1Width = tempImgObj.width;
       
       var img2Obj = img1Obj.next('img');
       tempImgObj.src = img2Obj.attr( 'src');
       img2Width = tempImgObj.width;
       
       $(this).width(textWidth + img1Width + img2Width + 10);
   });
}

标签类:

public class MultiSelectTaglib extends TagSupport 
{
    //下拉框数据,初始化下拉框的数据
    private List<LabelValueBean> items;
    //名称参数,传到后台的名称
    private String nameParams;
    //id参数,传到后台的id
    private String idParams;
    //当前id的值,主要用于查询后再次选中查询前的checkbox
    private String curIdVal;
    //样式,设置文本框样式
    private String textStyle;
    //是否只读(可选),设置文本框只读属性,默认只读
    private boolean readonly = true;
    //是否需要放大镜(可选),设置是否有放大镜图标,默认有放大镜图标
    private boolean hasSelectImg = true;
    //是否需要清空图标(可选),设置是否有清空图标,默认有清空图标
    private boolean hasClearImg = true;
    //下拉框高度(可选),设置高度后,超过高度后会显示下拉框
    private String selectHeight; 
    //下拉框宽度(可选),设置宽度后,超过高度后会显示下拉框,默认200px
    private String selectWidth;
    //是否需要全选功能(可选)
    private boolean hasAllSelector;
    
    //国际化用到的参数
    private final String SELECT_ALL = "select_all";
    private final String RESOURCE_NAME = "ssb_application_resource";
    /**
     * 重写doStartTag
     */
    public int doStartTag() 
    {        
        //得到资源文件
        Locale locale =  pageContext.getRequest().getLocale();
        ResourceBundle bundle = ResourceBundle.getBundle(RESOURCE_NAME, locale);
        Map<String, String> messages = new HashMap<String, String>();
        messages.put(SELECT_ALL, bundle.getString("multiSelect.selectAll"));
        
        JspWriter out = pageContext.getOut();
        
        if (out != null) 
        {
            try 
            {    
                out.print(getContentString(messages));
            } catch (IOException e) 
            {                
                PPMLog.debug("多选下拉框标签异常: " + e.getMessage());
            }
        }

        return SKIP_BODY;
    }
    
    /**
     * 拼接显示的多选框域
     * @return
     */
    private String getContentString(Map<String, String> messages)
    {
        //用户存放HTML内容串
        StringBuffer contentStr = new StringBuffer() ;
       //如果没设置宽度,默认200px
        if(StringHelper.isEmpty(selectWidth))
        {
            selectWidth = "200px";
        }
        
        //contentStr.append("<div class=\"multiSelectDiv\" style=\"width:" + selectWidth + "\">")
        contentStr.append("<div class=\"multiSelectDiv\">")
                  .append("<input type=\"text\" name=\"").append(nameParams).append("\"");
        //如果需要把文本框设置为只读
        if(readonly)
        {
            contentStr.append("readonly=\"readonly\"");
        }
        //文本框默认样式
        String textDefStyle = "width:200px";
        contentStr.append(" style=\"").append(StringHelper.isEmpty(textStyle) ? textDefStyle : textStyle).append("\"/>")
                  .append("<input type=\"hidden\" name=\"").append(idParams).append("\" value=\"" + curIdVal + "\"/>");
        
        HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
        if(hasSelectImg)
        {
            String imgPath = request.getContextPath() + "/images/projectinfo/search.gif";
            contentStr.append("<img src=\"" + imgPath + "\" class=\"icon\" style=\"cursor:pointer\" name=\"selectImg\"/>");
        }
        //如果需要清除图标
        if(hasClearImg)
        {
            String imgPath = request.getContextPath() + "/images/clear.gif";
            
            contentStr.append("<img src=\"" + imgPath + "\" class=\"icon\" style=\"cursor:pointer\" name=\"clearImg\"/>");
        }
        
        /*
         * 如果以后要支持自定义其他样式,可以将这里的高度和宽度去掉, 直接自定义下拉框的样式,
         * 注意这里默认的"display:none;position: absolute;"是必需的样式,如果自定义里有同样属性定义,会直接覆盖同名属性的值.
         * 这里为了使用简便,暂时不支持
         String selectDefStyle = "display:none;position: absolute;";        
         contentStr.append(" style=\"").append(StringHelper.isEmpty(selectStyle) ? selectDefStyle+selectStyle : selectStyle).append("\"/>");
        */
        
        contentStr.append("<div style=\"display:none;position: absolute;"); 
        //如果设置了下拉框高度
        if(StringHelper.isNotEmpty(selectHeight))
        {
            contentStr.append("overflow:auto;height:" + selectHeight + ";");
        }
        
        contentStr.append("width:" + selectWidth + ";");
        contentStr.append("\">");
        contentStr.append("   <table  cellspacing=\"1\" class=\"tb_datalist\">");
        //如果list不为空,生成下拉列表
        if(items.isEmpty())
        {
            contentStr.append("<tr><td><td></tr>");
        }
        else
        {
            //如果需要全选功能
            if(hasAllSelector)
            {
                contentStr.append("<tr class=\"tr_title\">");
                contentStr.append("<td width=\"10%\">")
                .append("   <input class=\"selectAll\" value=\"\" type=\"checkbox\"/></td>");
                contentStr.append("<td width=\"90%\"><span>").append(messages.get(SELECT_ALL)).append("</span></td>");
                contentStr.append("</tr>");
            }
            //生成下拉列表
            for(LabelValueBean labelVal:items)
            {
                if(labelVal != null)
                {
                    contentStr.append("<tr>");
                    contentStr.append("<td width=\"10%\">")
                    .append("   <input type=\"checkbox\"  value=\"" + labelVal .getValue()+ "\"/></td>");
                    contentStr.append("<td width=\"90%\">").append("<span>" + labelVal.getLabel() + "</span></td>");
                    contentStr.append("</tr>");
                }
            }
        }
        contentStr.append("</table>");
        contentStr.append("</div>");
        contentStr.append("</div>");
                
        return contentStr.toString() ;
    }


    public void release() {
        super.release();
    }

    public void setNameParams(String nameParams)
    {
        this.nameParams = nameParams;
    }

    public void setStyle(String textStyle)
    {
        this.textStyle = textStyle;
    }

    public void setIdParams(String idParams)
    {
        this.idParams = idParams;
    }

    public void setCurIdVal(String curIdVal)
    {
        this.curIdVal = curIdVal;
    }

    public void setItems(List<LabelValueBean> items)
    {
        this.items = items;
    }

    public void setHasClearImg(Boolean hasClearImg)
    {
        this.hasClearImg = hasClearImg;
    }

    public void setSelectWidth(String selectWidth)
    {
        this.selectWidth = selectWidth;
    }

    public void setSelectHeight(String selectHeight)
    {
        this.selectHeight = selectHeight;
    }

    public void setHasAllSelector(boolean hasAllSelector)
    {
        this.hasAllSelector = hasAllSelector;
    }

    
}

tld文件(multiSelect.tld):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
	<tlibversion>1.0</tlibversion>
	<jspversion>1.1</jspversion>
	<shortname>multiSelectTaglib</shortname>
	<uri>/multiSelectTaglib</uri>
	
	<tag>
		<name>multiSelect</name>
		<tagclass>com.zte.ppm.baseutil.business.multiSelectTaglib.service.MultiSelectTaglib</tagclass>
		<bodycontent>JSP</bodycontent>
		<info>check if the user have the right access</info>
		<attribute>
			<name>items</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>curIdVal</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>idParams</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>nameParams</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>textStyle</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>readonly</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>hasSelectImg</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>hasClearImg</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>selectHeight</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>selectWidth</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>hasAllSelector</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>
</taglib>

 

使用时导入相应tld文件和JS文件以及jQuery包:

<%@ taglib uri="/WEB-INF/multiSelect.tld" prefix="mSelect"%>

<script type="text/javascript" src="${appRoot}/js/multiSelect.js"></script>

<script type="text/javascript" src="${appRoot}/js/jquery/jquery-1.4.2.min.js"></script>

使用方法:

<mSelect:multiSelect nameParams="con.unitName" items="${dpgReportForm.operateUnitList}"
                  curIdVal="${dpgReportForm.con.unitName}" idParams="con.unitName"
                  hasClearImg="true" selectHeight="200px" hasAllSelector="true"/>

 

效果:

 

如果要实现注释中说的自定义下拉框样式且将全选选择框置顶,可以另外定义两个div,一个放全选按钮,一个放下面的选择数据。

抱歉!评论已关闭.