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

DW中制作树形菜单 接上一篇        二、树形菜单的制作        制作思想:在网上找到的资料那棵树全部是用表格控制实现的,我看了看代码,加上平时使用div+css布局的习惯,感觉使用表格和div结合在一起来实现树形菜单更为灵活一些。所以最后就采用了table+div+css+javascript来实现树形菜单已经其收缩效果。        下面我将源码分享给大家,可以参考参考,也许你有更好的办法 阅读详情


一、效果图:


二、自定义标签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"/>





JSP动态树形菜单实现指南 JSP(JavaServer Pages)技术是由Sun Microsystems公司倡导和许多公司参与一起建立的一种动态网页技术标准。它为创建动态交互式Web应用提供了一个易于使用的开发平台。JSP与ASP(Active Server Pages)和PHP(Hypertext Preprocessor)类似,允许开发者将Java代码嵌入到HTML页面中,从而动态生成网页内容。dtree库起源于Web前端的可视化数据展示需求,提供了一种简洁、高效的方式来在网页中展示树形结构的数据。 阅读详情

相关推荐

实现动态交互式JavaScript树形菜单

本文还有配套的精品资源,点击获取 简介:本文介绍了如何使用Java和JSP技术结合JavaScript库(例如jQuery)开发网页上的动态树形菜单。这种菜单常用于层次化数据展示,并可与后台数据库交互以动态加载节点。文章详细描述了从基本的HTML结构构建、JavaScript事件监听、AJAX数据请求处理,到后端服务器处理以及数据库设计的整个实现流程。 1. Ja...

weixin_30598047的博客 965

JSP树形菜单的实现

dtree是一个免费的javascript脚本,只需定义有限的几个参数,就可以做出漂亮的树型菜单。1)在数据库建tree_info表,有nodeId,parentNodeId,nodeName,nodeUrl四个字段,来存储节点信息。显然,如果用动态的脚本来初始化菜单数组(asp,jsp均可),那就可以很方便的实现动态的树型菜单了。dTree有点小bug,如果把css,img,js的路径改变,树就有可能不会正确显示。2)编写java类,用于从数据库找出节点信息,并且生成javascript脚本。

欢迎朋友,我是一名十多年开发经验的新手,希望多多指教。 1121

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

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

jsp页面循环添加下拉框方式

jQuery对象不可以,jQuery对象只能通过 atte或者prop方法来获取。第二个就是要理解:当遍历时,不管遍历前是什么对象,遍历时自动变为原生js对象。js原生对象可以直接通过 对象.字段来获取属性值。主要是要理解一下js原生对象和jQuery的使用。

m0_56353506的博客 696

jsp + servlet 级联菜单

jsp + servlet 级联菜单 简单适用,非常适合新手!

VMware虚拟机的安装教程

VMware 虚拟机的备份与恢复是保障数据安全和业务连续性的重要措施。综上所述,VMware 虚拟机的备份与恢复策略有多种选择,企业和用户可以根据实际需求和资源情况选择适合自己的方案,以确保虚拟机数据的安全和业务的连续性。

huanghm88的专栏 2979

jsp+bootstrap-treeview树形下拉菜单

目录前端Controller层service层Treeselect树结构实体类model类 前端 移动至输入框内自动显示,移出输入框自动隐藏 <link href="/webjars/bootstrap/3.3.6/dist/css/bootstrap.css" rel="stylesheet"> <link href="/css/bootstrap-treeview.min.css" rel="stylesheet" /> #tv { margin-top: 0; width

weixin_45304613的博客 1603

MSPM0G3507+逐飞库:5分钟搞定KEIL环境配置与LED闪烁(附常见错误解决)

本文详细介绍了如何使用MSPM0G3507微控制器和逐飞库快速配置KEIL开发环境,并实现LED闪烁功能。从芯片支持包安装、逐飞库工程配置到烧录调试,提供了完整的步骤和常见错误解决方案,帮助开发者5分钟内完成环境搭建。

lambda的博客 1195

jsp与树形菜单

1。原理简介 dtree是一个免费的javascript脚本,只需定义有限的几个参数,就可以做出漂亮的树型菜单。下载目录:http://www.destroydrop.com/javascripts/tree/ 以下是dtree的用法示例: 1)初始化菜单       var Tree = new Array;    // nodeId | parentNodeId | node

sprita1的专栏 5992

Multisim14安装失败?手把手教你彻底清理残留文件(附专用卸载工具)

本文针对Multisim14安装失败问题,提供了一套从根源解决的完整方案。文章详细分析了安装失败的三大元凶——文件残留、注册表残留和隐藏组件,并手把手指导用户使用专用卸载工具进行标准化清理,再结合手动深度清理文件系统和注册表,最终实现彻底卸载和完美重装,有效解决Multisim14安装问题。

weixin_29179311的博客 317

Cesium 模拟飞机坠毁功能

Cesium 模拟飞机坠毁功能,粒子模拟

QQhelphelp的博客 1068

bootstrap框架下用jsp自定义标签动态生成菜单树

自定义标签动态的生成菜单树思路jsp自定义标签用法 动态的生成菜单树思路 首先,这个跟前端的框架有关,如果前端用的是Easyui的话,直接从后端传递json格式的数值,发送到前端js里面进行解析,easyui里面有菜单树组件。 如果用的是bootstrap的话,也可以用treeview插件,将后端发送过来的json格式数据在js里面解析,然后动态的生成菜单树 但是:作为一个后端开发人员,可能对...

ranchill的博客 595

2025最新!视频动作识别算法的前沿研究与论文解读

2025最新!视频动作识别算法的前沿研究与论文解读 ,人工智能,计算机视觉,大模型,AI,本文聚焦2025年视频动作识别算法前沿,先介绍其定义、意义及核心挑战,再阐述传统与深度学习方法。还解读了基于Transformer、轻量化、跨模态融合和半监督学习的前沿研究,解释关键概念,列举常用数据集、评价指标,分析当前问题与未来趋势,为该领域研究提供全面参考。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 7万+

LayUI系列(二)之树形菜单的实现

layui树形菜单的实现

lijie1025的博客 1763

RT-DETR 模型剪枝优化:结构化剪枝对 R18/R50 性能的影响

本文提出分层结构化剪枝策略R18:参数量减少 42%(28M→16.2M),推理速度提升 35%(15→20.3 FPS@Jetson Nano),mAP@0.5 仅降 1.2%;R50:参数量减少 55%(170M→76.5M),推理速度提升 48%(42→62.2 FPS@T4),mAP@0.5 仅降 2.1%。核心价值:为 RT-DETR 提供“精度-效率-部署”平衡的轻量化方案,推动其在边缘设备、工业质检等场景的大规模落地。部署建议。

走向CTO的路上... 465

常用元器件使用方法36:USB转串口芯片CH340X

本文介绍了CH340X芯片的使用方法

snmplink的博客 2838

LayUI之树形菜单

树形菜单是一种常见的网页导航菜单形式,它使用树形结构来展示菜单项之间的层级关系。树形结构是一种层次化的数据结构,它由一个或多个节点组成,每个节点可以有零个或多个子节点。在树形菜单中,每个菜单项都对应树中的一个节点,菜单项之间通过父子关系来表示层级关系。树形菜单通常以一个根节点开始,根节点的子节点对应一级菜单项,每个一级菜单项又可以有自己的子节点,形成多级菜单结构。用户可以通过点击菜单项的展开/折叠按钮或者点击菜单项本身来展开或收起下级菜单项。

djssubddbj的博客 1378

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

jsp三级树形菜单,带多选后台保存代码—全选/半选和展示/隐藏

本文链接:https://blog.youkuaiyun.com/wangshao5122/article/details/102524387 jsp页面的三级树形菜单代码,后端提供java的json串格式:{result:[{region,rs:[{region,regions[]}]}]}; 以下为jsp页面代码,引用 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="c"

bngdBDT的博客 536

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Struts+Hibernate+Javascript 实现无限级树形菜单(重新上传带图片)

Struts+Hibernate+Javascript 实现无限级树形菜单 一、说明: 1、开发环境:Eclipse3.2.1+MyEclipse5.1+Tomcat5.5+Microsoft SQL Server 2000 2、主要实现技术:Struts1.2+Hibernate3.0+JavaScript+JSTL1.1+自定义标签 3、页面的树形菜

J2EE开发 6292

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

jsp树形菜单的实现

 1。原理简介 dtree是一个免费的javascript脚本,只需定义有限的几个参数,就可以做出漂亮的树型菜单。下载目录:http://www.destroydrop.com/javascripts/tree/ 以下是dtree的用法示例: 1)初始化菜单 script type="text/javascript">    var Tree = new Array;  // nodeId

BlackCatStudio 9371

Layui实现树形菜单(超详细)

一种以树状结构表示的菜单形式。通过父子关系组织菜单项,使用户能够方便地浏览和选择菜单项。树形菜单通常包含一个根节点和多个子节点,每个节点都可以包含子节点,从而形成层级结构。通常使用列表或嵌套列表的形式来实现树形菜单,如HTML中的和标签。树形菜单的优点之一是能够清晰地展现菜单间的层次和关系,使用户在浏览和选择菜单项时更加直观。

m0_73192864的博客 1978

JSP 树状菜单

1)初始化菜单     2)调用函数          显然,如果用动态的脚本来初始化菜单数组(asp,jsp均可),那就可以很方便的实现动态的树型菜单了。 2。jsp动态实现   分以下步骤实现动态的树型菜单:   1)在数据库建tree_info表,有nodeId,parentNodeId,nodeName,nodeUrl四个字段,来存储节点信息。   2)编写java类,用于从数据库找出节点

zhangwei_511304的专栏 1374

easyUI-combotree-树形下拉菜单

======================================我的================================================== Jsp标签: select id="id" class="easyui-combotree">select> JS: $('#cc').combotree({url: 'url'

zq33312757的博客 2085

WEB开发中前后台树形菜单的展示设计

在WEB开发中经常需要进行树形菜单的展示,本例通过不同角度的总结了如下三种实现方式: 通过JS的递归实现前端菜单DOM的动态创建通过JSP的include指令结合JSTL表达式语言递归实现菜单的展示通过扩展JSP的标签在后端实现菜单的DOM节点并响应给前端展示 针对第一种方法,可以采用JS的相关组件,或者使用JS的递归调用将服务端相应的数据组装成DOM节点内容,动态添加到菜单的Co

AlbenXie的博客 2525
上一篇: Javascript 将table数据导出到Excel
下一篇: JSP自定义标签(二) 联想查询
carroll0911
博客等级 码龄17年 27粉丝 41原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值