JSP自定义标签(一) 树形下拉选择菜单

来源:互联网 发布:javascript xml 编辑:程序博客网 时间:2024/05/01 21:28


一、效果图:


二、自定义标签JAVA代码:

package com.moonNigh.tagSupport;import java.io.IOException;import javax.servlet.http.HttpServletRequest;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.tagext.TagSupport;/** * * @author HHB * * 树形下拉选择控件 * */public class SelectorTag extends TagSupport {    private static final long serialVersionUID = 9878861374414215L;        //标签name属性    private String name;        //所需图片的路径    private String imgPath;        //所需javascript文件的路径    private String scriptPaht;        //所需css文件的路径    private String cssPath;        //项目的根路径    private String rootPath;        //标签的value属性    private String value;    private String text;    private String path;        /*     * 标签的actionUrl属性     * 联想查询结果数据通过向actionUrl属性指定的url请求得到     */    private String actionUrl;        private HttpServletRequest request=null;            public String getActionUrl() {        return actionUrl;    }    public void setActionUrl(String actionUrl) {        this.actionUrl = actionUrl;    }    public String getValue() {        return value;    }    public void setValue(String value) {        this.value = value;    }    public String getImgPath() {        return imgPath;    }    public void setImgPath(String imgPath) {        this.imgPath = imgPath;    }    public String getScriptPaht() {        return scriptPaht;    }        public void setScriptPaht(String scriptPaht) {        this.scriptPaht = scriptPaht;    }    public String getCssPath() {        return cssPath;    }        public void setCssPath(String cssPath) {        this.cssPath = cssPath;    }            public String getText() {        return text;    }    public void setText(String text) {        this.text = text;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public SelectorTag()    {            }            /**     * 初始化变量     */    private void initAbttributes()    {        request=(HttpServletRequest)this.pageContext.getRequest();        rootPath=request.getContextPath();        this.imgPath="/images/";        this.scriptPaht="/js/";        this.cssPath="/css/";            }    @Override    public int doStartTag() throws JspException {        initAbttributes();        path=rootPath+"/jsp/tags/treeSelectorPage.jsp?id="+id+"&actionUrl="+actionUrl;        JspWriter out=pageContext.getOut();        try {            String tName=name;            //引入javascript文件            out.println("<script type='text/javascript' charset='GB2312' src='"+rootPath+scriptPaht+"selector.js'></script>");                        //引入css文件            out.println("<link rel='stylesheet' href='"+rootPath+cssPath+"selector.css' type='text/css' />");                        StringBuilder tag=new StringBuilder("<input type='text' ");            tag.append("id='").append(id).append("'");            tag.append(" value='").append(text==null?"":text).append("'");            tag.append(" onclick='return showSelector(\"");            tag.append(id).append("\",\"").append(path).append("\")' readonly>");            tag.append("<input type='hidden' name='")            .append(tName).append("' id='").append(id).append("_value")            .append("' value='").append(value==null?"":value).append("'>");            out.println(tag.toString());        } catch (IOException e) {            e.printStackTrace();        }        return SKIP_BODY;    }        }


三、树形结构所属jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!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 runat="server">    <style type="text/css">    .btn-unfold {BACKGROUND: url(../images/bg10.png) no-repeat; FLOAT: left; WIDTH: 13px; MARGIN-RIGHT: 5px; HEIGHT: 13px}.btn-fold {BACKGROUND: url(../images/bg09.png) no-repeat; FLOAT: left; WIDTH: 13px; MARGIN-RIGHT: 5px; HEIGHT: 13px}    </style>   <script type='text/javascript' src='../../js/treeCreator.js'></script>   <script type='text/javascript' src='../../js/jquery-1.3.2.js'></script></head><body style="margin-left: 0px;margin-right: 0px;margin-top: 0px">    <form id="form1" runat="server">    <div>    </div>    </form>    <%String para="";    String actionUrl="";para=request.getParameter("id");actionUrl=request.getParameter("actionUrl");%>    <script language="javascript">    $.get("<%=(basePath+actionUrl) %>", function(data,status){    xmlParser(data,'<%=para %>');    });    </script></body></html>



三、js代码:selector.j

function closeHandler(cal) {  cal.hide();                        // hide the selector}/*function selected(cal, date) { }*//* * 显示下拉框 */function showSelector(id,path,ref) {  var selector=window["selector_"+id];  var el = document.getElementById(id);  if (selector) {    // we already have some selector created    if(ref&&ref===true)    {        selector.frame.src=path;    }    //selector.hide();                 // so we hide it first.  } else {    // first-time call, create the selector.    var selec = new Selector();    selec.textId=id;    selec.id="selector_"+id;    selec.valueId=id+"_value";    selec.path=path;    // uncomment the following line to hide the week numbers    // cal.weekNumbers = false;    selector = selec;                  // remember it in the global var    selec.create();  }  selector.sel = el;                 // inform it what input field we use  // the reference element that we pass to showAtElement is the button that  // triggers the selector.  In this example we align the selector bottom-right  // to the button.  selector.showAtElement(el, "Bl");        // show the selector  return false;}Selector = function () {    // member variables    this.activeDiv = null;    this.timeout = null;    this.dragging = false;    this.hidden = false;    this.isPopup = true;    // HTML elements    this.element = null;    this.containFrame=null;    this.textId=null;    this.id=null;    this.valueId=null;    this.path=null;    this.frame=null;}Selector.is_ie = ( /msie/i.test(navigator.userAgent) &&!/opera/i.test(navigator.userAgent) );Selector.getAbsolutePos = function(el) {    var r = { x: el.offsetLeft, y: el.offsetTop };    if (el.offsetParent) {        var tmp = Selector.getAbsolutePos(el.offsetParent);        r.x += tmp.x;        r.y += tmp.y;    }    //alert(r.x+":"+r.y);        return r;};Selector.isRelated = function (el, evt) {    var related = evt.relatedTarget;    if (!related) {        var type = evt.type;        if (type == "mouseover") {            related = evt.fromElement;        } else if (type == "mouseout") {            related = evt.toElement;        }    }    while (related) {        if (related == el) {            return true;        }        related = related.parentNode;    }    return false;};Selector.removeClass = function(el, className) {    if (!(el && el.className)) {        return;    }    var cls = el.className.split(" ");    var ar = new Array();    for (var i = cls.length; i > 0;) {        if (cls[--i] != className) {            ar[ar.length] = cls[i];        }    }    el.className = ar.join(" ");};Selector.addClass = function(el, className) {    Selector.removeClass(el, className);    el.className += " " + className;};Selector.createElement = function(type, parent) {    var el = null;    if (document.createElementNS) {        // use the XHTML namespace; IE won't normally get here unless        // _they_ "fix" the DOM2 implementation.        el = document.createElementNS("http://www.w3.org/1999/xhtml", type);    } else {        el = document.createElement(type);    }    if (typeof parent != "undefined") {        parent.appendChild(el);    }    return el;};/** Calls the second user handler (closeHandler). * 添加事件 *  */Selector.addEvent = function(el, evname, func) {    if (el.attachEvent) { // IE        el.attachEvent("on" + evname, func);    } else if (el.addEventListener) { // Gecko / W3C        el.addEventListener(evname, func, true);    } else { // Opera (or old browsers)        el["on" + evname] = func;    }};/* * 删除事件 */Selector.removeEvent = function(el, evname, func) {    //alert(el.detachEvent);    if (el.detachEvent) { // IE        el.detachEvent("on" + evname, func);    } else if (el.removeEventListener) { // Gecko / W3C        el.removeEventListener(evname, func, true);    } else { // Opera (or old browsers)        el["on" + evname] = null;    }};Selector.prototype.create = function (_par) {    var parent = null;    if (! _par) {        // default parent is the document body, in which case we create        // a popup selector.        parent = document.getElementsByTagName("body")[0];        this.isPopup = true;    } else {        parent = _par;        this.isPopup = false;    }    var div = document.createElement("div");    var selectIframe = Selector.createElement("iframe");    selectIframe.style.width="100%";    selectIframe.style.height="100%";    selectIframe.style.display="block";    selectIframe.scrolling="auto";    selectIframe.style.border="0px";    selectIframe.id=this.textId+"_frm";    this.containFrame=selectIframe;    //selectIframe.style.border="1px";    selectIframe.src=this.path;    var span=document.createElement("span");    span.innerHTML="test";    //div.appendChild(span);    this.frame=selectIframe;    div.appendChild(selectIframe);    this.element = div;    div.className = "selector";    if (this.isPopup) {        div.style.position = "absolute";        div.style.display = "none";    }    parent.appendChild(this.element);};Selector.prototype.destroy = function () {    var el = this.element.parentNode;    el.removeChild(this.element);    Selector._C = null;};/** *  Hides the Selector.  Also removes any "hilite" from the class of any TD *  element. *  隐藏下拉框 */Selector.prototype.hide = function () {    if (this.isPopup) {        //Selector.removeEvent(document, "keydown", Selector._keyEvent);        //Selector.removeEvent(document, "keypress", Selector._keyEvent);        Selector.removeEvent(document, "mousedown", function(){window[this.id].hide();});    }    this.element.style.display = "none";    this.hidden = true;    this.hideShowCovered();};Selector.prototype.showAt = function (x, y) {    var s = this.element.style;    s.left = x + "px";    s.top = y + "px";    this.show();};/** 下拉框相对指定控件的显示位置. */Selector.prototype.showAtElement = function (el, opts) {    var p = Selector.getAbsolutePos(el);    //alert(p.x+'-'+p.y);    if (!opts || typeof opts != "string") {        this.showAt(p.x, p.y + el.offsetHeight);        return true;    }    this.show();    var w = this.element.offsetWidth;    var h = this.element.offsetHeight;    this.hide();    var valign = opts.substr(0, 1);    var halign = "l";    if (opts.length > 1) {        halign = opts.substr(1, 1);    }    // 垂直对齐方式        switch (valign) {        case "T": p.y -= h; break;        case "B": p.y += el.offsetHeight; break;        case "C": p.y += (el.offsetHeight - h) / 2; break;        case "t": p.y += el.offsetHeight - h; break;        case "b": break; // already there        }    // 水平对齐方式    switch (halign) {        case "L": p.x -= w; break;        case "R": p.x += el.offsetWidth; break;        case "C": p.x += (el.offsetWidth - w) / 2; break;        case "r": p.x += el.offsetWidth - w; break;        case "l": break; // already there    }    this.showAt(p.x, p.y);};Selector.prototype.show = function () {    this.element.style.display = "block";    this.hidden = false;        if (this.isPopup) {        window[this.id] = this;        var tId=this.id;        //Calendar.addEvent(document, "keydown", Calendar._keyEvent);        //Calendar.addEvent(document, "keypress", Calendar._keyEvent);        Selector.addEvent(document, "mousedown", function(){window[tId].hide();});    }        this.hideShowCovered();};Selector.prototype.hideShowCovered = function () {    function getStyleProp(obj, style){        var value = obj.style[style];        if (!value) {            if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C                value = document.defaultView.                    getComputedStyle(obj, "").getPropertyValue(style);            } else if (obj.currentStyle) { // IE                value = obj.currentStyle[style];            } else {                value = obj.style[style];            }        }        return value;    };    var tags = new Array("applet", "select");    var el = this.element;    var p = Selector.getAbsolutePos(el);    var EX1 = p.x;    var EX2 = el.offsetWidth + EX1;    var EY1 = p.y;    var EY2 = el.offsetHeight + EY1;    for (var k = tags.length; k > 0; ) {        var ar = document.getElementsByTagName(tags[--k]);        var cc = null;        for (var i = ar.length; i > 0;) {            cc = ar[--i];            p = Selector.getAbsolutePos(cc);            var CX1 = p.x;            var CX2 = cc.offsetWidth + CX1;            var CY1 = p.y;            var CY2 = cc.offsetHeight + CY1;            if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {                if (!cc.__msh_save_visibility) {                    cc.__msh_save_visibility = getStyleProp(cc, "visibility");                }                cc.style.visibility = cc.__msh_save_visibility;            } else {                if (!cc.__msh_save_visibility) {                    cc.__msh_save_visibility = getStyleProp(cc, "visibility");                }                cc.style.visibility = "hidden";            }        }    }};



四、js代码:treeCreator.js

      

var blank=".   ";        var blankTimes=1;        var blankSize=30;                var idIndex=0;        var totalWidth=0;        var imgpath="/MoonNighTags/images/";        /*         *  加载xml字符串返回XMLDocument对象         */        function loadXML(xmlStr)        {            if(!window.DOMParser && window.ActiveXObject){   //window.DOMParser ÅжÏÊÇ·ñÊÇ·Çieä¯ÀÀÆ÷                var xmlDomVersions = ['MSXML.2.DOMDocument.6.0','MSXML.2.DOMDocument.3.0','Microsoft.XMLDOM'];                for(var i=0;i<xmlDomVersions.length;i++){                    try{                        xmlDoc = new ActiveXObject(xmlDomVersions[i]);                        xmlDoc.async = false;                        xmlDoc.loadXML(xmlStr);                        break;                    }catch(e){                    }                }            }            else if(window.DOMParser && document.implementation && document.implementation.createDocument){                try{                    domParser = new DOMParser();                    xmlDoc = domParser.parseFromString(xmlStr,"text/xml");                }catch(e){                }            }            else{                return null;            }            return xmlDoc;        }                /*         * 解析xml字符串生成属性结构         */        function xmlParser(xmlStr,textId)        {            var childs=null;            var root=null;            var xmlDoc=loadXML(xmlStr);            root=xmlDoc.documentElement;            childs=root.childNodes;            var topDiv=document.createElement("div");            topDiv.id='topdiv';            document.body.appendChild(topDiv);            dealWithNode(root,0,topDiv,textId);            topDiv.style.width='100%';                    }                /*         * 根据节点及其子节点生成树         */        function dealWithNode(node,blankTimes,container,textId)        {            var children=null;            var childCount=0;            var isLeaf=false;                        var htmlnode=null;            var textnode=null;                        var bl_times=blankTimes;            var bl_str="";                        var node_value="";            var node_id="";                        if(node)            {                isLeaf=isLeafNode(node);                var str="";                var spaceLength=0;                if(idIndex>0)                {                   str=getSpaceString(1);                }                if(bl_times>0)                {                       spaceLength=bl_times*blankSize;                }                node_id=node_value=getAttributValue(node,"id");                if(!node_id||node_id=="")                {                    node_id=idIndex+1;                }                if(isLeaf)                {                    if(node.nodeType==3)                    {                        node_value=node.nodeValue;                    }                    else                    {                        node_value=node.firstChild.nodeValue;                    }                    idIndex++;                    node_value=str+node_value;                    htmlnode=createItem(node_value,node_id,container,isLeaf,textId);                                        htmlnode.style.paddingLeft=spaceLength+'px';                }                else                {                    node_value=getAttributValue(node,"value");                    idIndex++;                    node_value=str+node_value;                    htmlnode=createItem(node_value,node_id,container,isLeaf,textId);                    htmlnode.style.paddingLeft=spaceLength+'px';                    var cContainer=createChildContainer("div"+node_id,container);                    cContainer.style.paddingLeft=bl_times*blankSize;                    cContainer.style.width='100%';                    children=node.childNodes;                    if(getBrowser()=="MSIE")                    {                        bl_times=1;                    }                    else                    {                        bl_times+=1;                    }                                        if(children&&children.length>0)                    {                        for(var i=0;i<children.length;i++)                        {                            dealWithNode(children[i],bl_times,cContainer,textId);                        }                    }                }                            }        }                /*         * 判断节点是否是叶子节点         */        function isLeafNode(node)        {            var children=null;            if(node)            {                if(node.nodeType==3)                {                    return true;                }                else                {                    children=node.childNodes;                    if(children.length==1&&children[0].nodeType==3)                    {                        return true;                    }                    else                    {                        return false;                    }                }            }            return true;        }                        /*         * 获取自定节点的指定属性值         */        function getAttributValue(node,attrName)        {            var attributes=null;            var attr=null;            if(node)            {                attributes=node.attributes;                if(attributes&&attributes.length>0)                {                    for(var attrI=0;attrI<attributes.length;attrI++)                    {                        attr=attributes[attrI];                        if(attr&&attr.nodeName==attrName)                        {                            return attr.nodeValue;                        }                    }                }            }            return null;        }                /*         * 创建树形结构中每个节点的项         */        function createItem(itemText,idStr,parentContainer,isLeaf,textId)        {            var htmlnode=null;            var textnode=null;            var imgnode=null;            var titlenode=null;            var imgsrc=imgpath+"bg09.png";            if(isLeaf)            {                imgsrc=imgpath+"bg10.png";            }            htmlnode=document.createElement("div");            htmlnode.id="span"+idStr;            //htmlnode.href="#";            //htmlnode.style.paddingLeft="200";            //htmlnode.expanded="fales";            //图片            imgnode=document.createElement("img");            imgnode.setAttribute("src",imgsrc);            imgnode.setAttribute("flag",isLeaf);            imgnode.setAttribute("isLeaf",isLeaf);            myAttachEvent(imgnode,'click',open_closeClick);            //文字–            titlenode=document.createElement("div");            titlenode.style.display="inline";            titlenode.style.cursor="pointer";            titlenode.id=idStr;            textnode=document.createTextNode(itemText);            titlenode.appendChild(textnode);            myAttachEvent(titlenode,'click',function(){                var srcObj;                if(typeof(event)!="undefined")                {                    srcObj=event.srcElement;                }                else                {                    srcObj=this;                }                itemClick(srcObj,textId);});                        htmlnode.appendChild(imgnode);            htmlnode.appendChild(titlenode);                        parentContainer.appendChild(htmlnode);            return htmlnode;        }                /*         * 创建包含节点下子树的容器         */        function createChildContainer(idStr,parentContainer)        {            var cContainer=null;            cContainer=document.createElement("div");            cContainer.id=idStr;            cContainer.style.display="none";            cContainer.style.whiteSpace='nowrap';            parentContainer.appendChild(cContainer);            return cContainer;        }                /*         * 单击图片时触发的事件         * 展开或收起该节点的子树         */        function open_closeClick(arg)        {            var srcObj;            if(typeof(event)!="undefined")            {                srcObj=event.srcElement;            }            else            {                srcObj=this;            }            var flag=srcObj.getAttribute("flag");            if(srcObj.getAttribute("isLeaf")=="true")            {                return;            }            if(flag=="true"){                srcObj.src=imgpath+"bg09.png";                srcObj.setAttribute("flag","false")            }else{                srcObj.src=imgpath+"bg10.png";                srcObj.setAttribute("flag","true");            }                        var conId=srcObj.parentNode.id.replace("span","div");            //alert(conId);            var container=document.getElementById(conId);            if(container)            {                if(container.style.display=="block")                    container.style.display="none";                else                    container.style.display="block";            }        }                /*         * 点击树中节点上选项时触发事件时调用该方法         * 关闭下拉框         */        function itemClick(srcObj,pid)        {                        if(window.parent)            {                window.parent.document.getElementById(pid).value=srcObj.innerHTML;                window.parent.document.getElementById(pid+'_value').value=srcObj.id;                if(window.parent["selector_"+pid])                    window.parent["selector_"+pid].hide();            }        }                /*         * 绑定事件         */        var myAttachEvent = function(obj, evt, fn){                            if (obj.addEventListener)                                obj.addEventListener(evt, fn, false);                            else if (obj.attachEvent)                                obj.attachEvent("on" + evt, fn);                }                    function Integration_InterceptCellEvent(id, evt, func)        {            if (func.constructor == Function)            {                document.write('<scr' + 'ipt for="' + id + '" event="' + evt + '">'                        + 'Array.prototype.push.call(arguments, "' + evt + '");'                        + func.toString().match(/\s*Function\s+(\S*)\s*\(/i)[1]                        + '.apply(this, arguments);'                        + '</sc' + 'ript>');            }        }                function getSpaceString(strlength)        {                var str="";                for(var strIndex=0;strIndex<strlength;strIndex++)                {                        str+=" ";                }                return str;        }        function getShortFileName(fileName)        {            var name="";            var index=-1;                    }                /*         * 获取浏览器类型         */        function getBrowser()        {           var OsObject = "";             if(navigator.userAgent.indexOf("MSIE")>0) {                  return "MSIE";             }             if(isFirefox=navigator.userAgent.indexOf("Firefox")>0){                  return "Firefox";             }             if(isSafari=navigator.userAgent.indexOf("Safari")>0) {                  return "Safari";             }              if(isCamino=navigator.userAgent.indexOf("Camino")>0){                  return "Camino";             }             if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){                  return "Gecko";             }             return "others";        }


五、tld文件标签定义:

<tag>
      <name>selector</name>
      <tag-class>com.moonNigh.tagSupport.SelectorTag</tag-class>
      <body-content>empty</body-content>
      <small-icon></small-icon>
      <large-icon></large-icon>
      <description></description>
      <attribute>
          <name>id</name>
          <required>true</required>
      </attribute>
      <attribute>
          <name>name</name>
          <required>true</required>
      </attribute>
      <attribute>
          <name>value</name>
          <required>false</required>
          <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
          <name>text</name>
          <required>false</required>
          <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
          <name>actionUrl</name>
          <required>false</required>
          <rtexprvalue>true</rtexprvalue>
      </attribute>
      <example></example>
  </tag>

六、CSS代码:

.selector {  position: relative;  display: none;  border:2px solid #C9D7F1;  font-size: 11px;  color: #666;  cursor: default; background:white;/*  font-family:tahoma,verdana,sans-serif;*/  font-family:arial;  margin-top:2px;  width: 150px;  height: 200px;}


七、自定义的用于输出生成树形结构的XML的Servlet或Action:

package com.moonNigh.servlet;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class GetTreeXML extends HttpServlet {    /**     *     */    private static final long serialVersionUID = 1L;    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp)            throws ServletException, IOException {        this.doPost(req, resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp)            throws ServletException, IOException {        // TODO Auto-generated method stub        resp.setCharacterEncoding("UTF-8");        resp.setContentType("UTF-8");        PrintWriter out=resp.getWriter();        StringBuilder sb=new StringBuilder();        sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");        sb.append("<xmlRoot value=\"中国\" id=\"china\">");        sb.append("<child value=\"四川\" id=\"sc\">");        sb.append("<child id=\"ctu\">成都</child>");        sb.append("</child><child id=\"gz\">贵州</child></xmlRoot>");        out.write(sb.toString());        out.flush();    }}


八、测试JSP标签使用

<c:selector id="ctest" name="test" actionUrl="getTreeXml"/>





原创粉丝点击