首页 > 代码库 > jsp 自定义标签实现表格转载http://blog.csdn.net/chenshuang_com

jsp 自定义标签实现表格转载http://blog.csdn.net/chenshuang_com

  1. package com.ts.taglib.html;  
  2.   
  3. import java.lang.reflect.Field;  
  4.   
  5. import javax.servlet.jsp.tagext.BodyTagSupport;  
  6. /** 
  7.  * 事件处理 
  8.  * @author 陈双 
  9.  * @date 2012-09-22 
  10.  * @mail chenshuang_com@sina.com 
  11.  */  
  12. public abstract class BaseHandlerTag extends BodyTagSupport{  
  13.     private static final long serialVersionUID = 715968190636480266L;  
  14.     private String onclick;  
  15.     private String ondblclick;  
  16.     private String onmouseover;  
  17.     private String onmouseout;  
  18.     private String onmousedown;  
  19.     private String onmouseup;  
  20.     private String onmousemove;  
  21.     private String onkeydown;  
  22.     private String onkeyup;  
  23.     private String onkeypress;  
  24.     private String onfocus;  
  25.     private String onblur;  
  26.     private String onchange;  
  27.     private String onselect;  
  28.     private String styleId;  
  29.     private String style;  
  30.     private String styleClass;  
  31.     private boolean readonly;  
  32.     private boolean disabled;  
  33.     public BaseHandlerTag()  
  34.     {  
  35.         super();  
  36.         init();  
  37.     }  
  38.     public void init()  
  39.     {  
  40.         onclick=null;  
  41.         ondblclick=null;  
  42.         onmouseover=null;  
  43.         onmouseout=null;  
  44.         onmousedown=null;  
  45.         onmouseup=null;  
  46.         onmousemove=null;  
  47.         onkeydown=null;  
  48.         onkeyup=null;  
  49.         onkeypress=null;  
  50.         onfocus=null;  
  51.         onblur=null;  
  52.         onchange=null;  
  53.         onselect=null;  
  54.         readonly=false;  
  55.         disabled=false;  
  56.     }  
  57.     public String getOnclick() {  
  58.         return onclick;  
  59.     }  
  60.     public void setOnclick(String onclick) {  
  61.         this.onclick = onclick;  
  62.     }  
  63.     public String getOndblclick() {  
  64.         return ondblclick;  
  65.     }  
  66.     public void setOndblclick(String ondblclick) {  
  67.         this.ondblclick = ondblclick;  
  68.     }  
  69.     public String getOnmouseover() {  
  70.         return onmouseover;  
  71.     }  
  72.     public void setOnmouseover(String onmouseover) {  
  73.         this.onmouseover = onmouseover;  
  74.     }  
  75.     public String getOnmouseout() {  
  76.         return onmouseout;  
  77.     }  
  78.     public void setOnmouseout(String onmouseout) {  
  79.         this.onmouseout = onmouseout;  
  80.     }  
  81.     public String getOnmousedown() {  
  82.         return onmousedown;  
  83.     }  
  84.     public void setOnmousedown(String onmousedown) {  
  85.         this.onmousedown = onmousedown;  
  86.     }  
  87.     public String getOnmouseup() {  
  88.         return onmouseup;  
  89.     }  
  90.     public void setOnmouseup(String onmouseup) {  
  91.         this.onmouseup = onmouseup;  
  92.     }  
  93.     public String getOnmousemove() {  
  94.         return onmousemove;  
  95.     }  
  96.     public void setOnmousemove(String onmousemove) {  
  97.         this.onmousemove = onmousemove;  
  98.     }  
  99.     public String getOnkeydown() {  
  100.         return onkeydown;  
  101.     }  
  102.     public void setOnkeydown(String onkeydown) {  
  103.         this.onkeydown = onkeydown;  
  104.     }  
  105.     public String getOnkeyup() {  
  106.         return onkeyup;  
  107.     }  
  108.     public void setOnkeyup(String onkeyup) {  
  109.         this.onkeyup = onkeyup;  
  110.     }  
  111.     public String getOnkeypress() {  
  112.         return onkeypress;  
  113.     }  
  114.     public void setOnkeypress(String onkeypress) {  
  115.         this.onkeypress = onkeypress;  
  116.     }  
  117.     public String getOnfocus() {  
  118.         return onfocus;  
  119.     }  
  120.     public void setOnfocus(String onfocus) {  
  121.         this.onfocus = onfocus;  
  122.     }  
  123.     public String getOnblur() {  
  124.         return onblur;  
  125.     }  
  126.     public void setOnblur(String onblur) {  
  127.         this.onblur = onblur;  
  128.     }  
  129.     public String getOnchange() {  
  130.         return onchange;  
  131.     }  
  132.     public void setOnchange(String onchange) {  
  133.         this.onchange = onchange;  
  134.     }  
  135.     public String getOnselect() {  
  136.         return onselect;  
  137.     }  
  138.     public void setOnselect(String onselect) {  
  139.         this.onselect = onselect;  
  140.     }  
  141.     public String getStyleId() {  
  142.         return styleId;  
  143.     }  
  144.     public void setStyleId(String styleId) {  
  145.         this.styleId = styleId;  
  146.     }  
  147.     public String getStyle() {  
  148.         return style;  
  149.     }  
  150.     public void setStyle(String style) {  
  151.         this.style = style;  
  152.     }  
  153.     public String getStyleClass() {  
  154.         return styleClass;  
  155.     }  
  156.     public void setStyleClass(String styleClass) {  
  157.         this.styleClass = styleClass;  
  158.     }  
  159.     public boolean isReadonly() {  
  160.         return readonly;  
  161.     }  
  162.     public void setReadonly(boolean readonly) {  
  163.         this.readonly = readonly;  
  164.     }  
  165.     public boolean isDisabled() {  
  166.         return disabled;  
  167.     }  
  168.     public void setDisabled(boolean disabled) {  
  169.         this.disabled = disabled;  
  170.     }  
  171.     public String prepareStyles()  
  172.     {  
  173.         StringBuffer handlers=new StringBuffer();  
  174.         prepareAttribute(handlers,"id",getStyleId());  
  175.         prepareAttribute(handlers,"style",getStyle());  
  176.         prepareAttribute(handlers,"class",getStyleClass());  
  177.         return handlers.toString();  
  178.     }  
  179.     public String prepareEvents()  
  180.     {  
  181.         StringBuffer handlers=new StringBuffer();  
  182.         prepareMouseEvents(handlers);  
  183.         prepareKeyEvents(handlers);  
  184.         prepareFocusEvents(handlers);  
  185.         prepareTextEvents(handlers);  
  186.         return handlers.toString();  
  187.     }  
  188.     public void prepareMouseEvents(StringBuffer handlers)  
  189.     {  
  190.         prepareAttribute(handlers,"onclick",getOnclick());  
  191.         prepareAttribute(handlers,"ondblclick",getOndblclick());  
  192.         prepareAttribute(handlers,"onmouseover",getOnmouseover());  
  193.         prepareAttribute(handlers,"onmouseout",getOnmouseout());  
  194.         prepareAttribute(handlers,"onmousedown",getOnmousedown());  
  195.         prepareAttribute(handlers,"onmouseup",getOnmouseup());  
  196.         prepareAttribute(handlers,"onmousemove",getOnmousemove());  
  197.     }  
  198.     public void prepareKeyEvents(StringBuffer handlers)  
  199.     {  
  200.         prepareAttribute(handlers,"onkeydown",getOnkeydown());  
  201.         prepareAttribute(handlers,"onkeyup",getOnkeyup());  
  202.         prepareAttribute(handlers,"onkeypress",getOnkeypress());  
  203.     }  
  204.     public void prepareFocusEvents(StringBuffer handlers)  
  205.     {  
  206.         prepareAttribute(handlers,"onfocus",getOnfocus());  
  207.         prepareAttribute(handlers,"onblur",getOnblur());  
  208.         if(isReadonly())  
  209.         {  
  210.             handlers.append(" readonly=\"readonly\"");  
  211.         }  
  212.         if(isDisabled())  
  213.         {  
  214.             handlers.append(" disabled=\"disabled\"");  
  215.         }  
  216.     }  
  217.     public void prepareTextEvents(StringBuffer handlers)  
  218.     {  
  219.         prepareAttribute(handlers,"onselect",getOnselect());  
  220.         prepareAttribute(handlers,"onchange",getOnchange());  
  221.     }  
  222.     public void prepareAttribute(StringBuffer handler,String property,Object value)  
  223.     {  
  224.         if(handler!=null&&property!=null&&value!=null)  
  225.         {  
  226.             handler.append(" ");  
  227.             handler.append(property);  
  228.             handler.append("=\"");  
  229.             handler.append(value);  
  230.             handler.append("\"");  
  231.         }  
  232.     }  
  233.     /** 
  234.      * 取值 
  235.      * @param name 
  236.      * @return 
  237.      * @throws SecurityException 
  238.      * @throws IllegalArgumentException 
  239.      * @throws NoSuchFieldException 
  240.      * @throws IllegalAccessException 
  241.      */  
  242.     public Object findValue(String name) throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException  
  243.     {  
  244.         String[] elements=name.split("\\.");  
  245.         if(elements!=null&&elements.length>0)  
  246.         {  
  247.             Object bean=pageContext.getAttribute(elements[0],2);  
  248.             if(elements.length>2)  
  249.             {  
  250.                 for(int i=1;i<elements.length;i++)  
  251.                 {  
  252.                     bean=getValue(bean, elements[i]);  
  253.                 }  
  254.                 return bean;  
  255.             }  
  256.             else  
  257.             {  
  258.                 return getValue(bean, elements[1]);  
  259.             }  
  260.         }  
  261.         return null;  
  262.     }  
  263.     public Object getValue(Object bean,String property) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException  
  264.     {  
  265.         if(bean!=null&&property!=null)  
  266.         {  
  267.             Field field=bean.getClass().getDeclaredField(property);  
  268.             field.setAccessible(true);  
  269.             return field.get(bean);  
  270.         }  
  271.         return null;  
  272.     }  
  273.     public void release() {  
  274.         // TODO Auto-generated method stub   
  275.         super.release();  
  276.         init();  
  277.     }  
  278. }  
  279. package com.ts.taglib.html;  
  280.   
  281. import java.io.IOException;  
  282. import java.text.SimpleDateFormat;  
  283. import java.util.ArrayList;  
  284. import java.util.List;  
  285. import java.util.Map;  
  286.   
  287. import javax.servlet.jsp.JspException;  
  288.   
  289. import com.ts.taglib.data.Column;  
  290. import com.ts.taglib.data.DataGrid;  
  291.   
  292. /** 
  293.  * 表格控件 
  294.  * @author 陈双 
  295.  * @date 2012-09-22 
  296.  * @mail chenshuang_com@sina.com 
  297.  * 
  298.  */  
  299. public class TableTag extends BaseHandlerTag {  
  300.   
  301.     private static final long serialVersionUID = -5642687627324772161L;  
  302.     private String name;//名称   
  303.     private String width;//宽度   
  304.     private String height;//高度   
  305.     private String data;//取数   
  306.     private boolean multiple;//是否多行勾选框   
  307.     public TableTag()  
  308.     {  
  309.         super();  
  310.         name=null;  
  311.         width=null;  
  312.         height=null;  
  313.         data=http://www.mamicode.com/null;  
  314.         multiple=false;  
  315.     }  
  316.     public String getName() {  
  317.         return name;  
  318.     }  
  319.     public void setName(String name) {  
  320.         this.name = name;  
  321.     }  
  322.     public String getWidth() {  
  323.         return width;  
  324.     }  
  325.     public void setWidth(String width) {  
  326.         this.width = width;  
  327.     }  
  328.     public String getHeight() {  
  329.         return height;  
  330.     }  
  331.     public void setHeight(String height) {  
  332.         this.height = height;  
  333.     }  
  334.     public String getData() {  
  335.         return data;  
  336.     }  
  337.     public void setData(String data) {  
  338.         this.data = data;  
  339.     }  
  340.     public boolean isMultiple() {  
  341.         return multiple;  
  342.     }  
  343.     public void setMultiple(boolean multiple) {  
  344.         this.multiple = multiple;  
  345.     }  
  346.     public int doEndTag() throws JspException {  
  347.         try {  
  348.             pageContext.getOut().print(createTable());  
  349.         } catch (IOException e) {  
  350.               
  351.             throw new JspException(e.getMessage());  
  352.         }  
  353.         return 6;  
  354.     }  
  355.     public int doStartTag() throws JspException {  
  356.         pageContext.setAttribute("columnHeader"new ArrayList(),2);  
  357.         return 1;  
  358.     }  
  359.     /** 
  360.      * 实现方式由Java构建所需的数据然后调用js创建表格 
  361.      * @return 
  362.      * @throws JspException 
  363.      */  
  364.     public String createTable()throws JspException  
  365.     {  
  366.         StringBuffer handlers=new StringBuffer("<div id=\"main_grid_");  
  367.         handlers.append(getName());  
  368.         handlers.append("\"");  
  369.         handlers.append(" style=\"border:solid 1 #cccccc;");  
  370.         handlers.append("width:");  
  371.         handlers.append(getWidth());  
  372.         handlers.append(";height:");  
  373.         handlers.append(Integer.parseInt(getHeight())+25);  
  374.         handlers.append(";\">\n");  
  375.         handlers.append("<script type=\"text/javascript\" charset=\"utf-8\">\n");  
  376.         //处理数据   
  377.         List headerList=(List) pageContext.getAttribute("columnHeader"2);  
  378.         if(headerList==null||headerList.size()==0)  
  379.         {  
  380.             throw new JspException("Table name is "+name+",列数必须大于0!");  
  381.         }  
  382.         handlers.append(getColumns(headerList));  
  383.         List list=(List) pageContext.getAttribute(data, 2);  
  384.         handlers.append(getRows(list));  
  385.         //调用js生成表格对象   
  386.         handlers.append("CreateTable(‘");  
  387.         handlers.append(getName());  
  388.         handlers.append("‘,‘main_grid_");  
  389.         handlers.append(getName());  
  390.         handlers.append("‘,");  
  391.         handlers.append(getWidth());  
  392.         handlers.append(",");  
  393.         handlers.append(getHeight());  
  394.         handlers.append(",");  
  395.         handlers.append(isMultiple());  
  396.         handlers.append(",getColumns_grid_");  
  397.         handlers.append(getName());  
  398.         handlers.append("(),getRows_grid_");  
  399.         handlers.append(getName());  
  400.         handlers.append("());\n</script>\n");  
  401.         handlers.append("<table cellspacing=0 height=25 width=");  
  402.         handlers.append(getWidth());  
  403.         handlers.append(" >\n<tr>\n<td style=\"height:18px;cursor:default;font-size:12px;font-family:verdana;text-align:right;\">共");  
  404.         Object total=pageContext.getAttribute("total"2);  
  405.         if(total==null)  
  406.         {  
  407.             total=0;  
  408.         }  
  409.         handlers.append(total);  
  410.         handlers.append("页  当前显示第");  
  411.         Object current=pageContext.getAttribute("current",2);  
  412.         if(current==null)  
  413.         {  
  414.             current=0;  
  415.         }  
  416.         handlers.append(current);  
  417.         handlers.append("页  <a href=http://www.mamicode.com/"javascript:lastPage();\">上页</a> <a href=http://www.mamicode.com/"javascript:nextPage();\">下页</a>  <input type=\"hidden\" name=\"currentPage\"/>第<input name=\"toPage\" type=\"text\" size=3/>页</td>\n</tr>\n</table>\n");  
  418.         handlers.append("</div>\n");  
  419.         return handlers.toString();  
  420.     }  
  421.     /** 
  422.      * 构建所有的列 
  423.      * @param list 
  424.      * @return 
  425.      * @throws JspException 
  426.      */  
  427.     private String getColumns(List list) throws JspException  
  428.     {  
  429.         StringBuffer columns=new StringBuffer();  
  430.         if(list!=null&&list.size()>0)  
  431.         {  
  432.             columns.append("function getColumns_grid_");  
  433.             columns.append(name);  
  434.             columns.append("()\n{\n");  
  435.             columns.append("var columns=new Array();\n");  
  436.             for(int i=0;i<list.size();i++)  
  437.             {  
  438.                 Column column=(Column) list.get(i);  
  439.                 columns.append("var gridColumn");  
  440.                 columns.append(i);  
  441.                 columns.append("=new GridColumn(‘");  
  442.                 columns.append(column.getName());  
  443.                 columns.append("‘,‘");  
  444.                 columns.append(column.getLabel());  
  445.                 columns.append("‘,‘");  
  446.                 columns.append(column.getType());  
  447.                 columns.append("‘,");  
  448.                 columns.append(column.getWidth());  
  449.                 columns.append(",");  
  450.                 columns.append(column.getHeight());  
  451.                 columns.append(",");  
  452.                 columns.append("null");  
  453.                 columns.append(",");  
  454.                 columns.append(column.isHidden());  
  455.                 columns.append(",");  
  456.                 columns.append(column.isDisabled());  
  457.                 columns.append(",");  
  458.                 columns.append(column.isSum());  
  459.                 columns.append(",");  
  460.                 columns.append(column.getSize());  
  461.                 columns.append(",");  
  462.                 columns.append(column.getColspan());  
  463.                 if(column.getOndblclick()!=null)  
  464.                 {  
  465.                     columns.append(",\"");  
  466.                     columns.append(column.getOndblclick());  
  467.                     columns.append("\",");  
  468.                 }  
  469.                 else  
  470.                 {  
  471.                     columns.append(",");  
  472.                     columns.append("null,");  
  473.                 }  
  474.                 if(column.getDrillEvent()!=null)  
  475.                 {  
  476.                     columns.append("\"");  
  477.                     columns.append(column.getDrillEvent());  
  478.                     columns.append("\");\n");  
  479.                 }  
  480.                 else  
  481.                 {  
  482.                     columns.append("null);\n");  
  483.                 }  
  484.                 columns.append("columns[");  
  485.                 columns.append(i);  
  486.                 columns.append("]=gridColumn");  
  487.                 columns.append(i);  
  488.                 columns.append(";\n");  
  489.             }  
  490.             columns.append("return columns;\n}");  
  491.         }  
  492.         return columns.toString();  
  493.     }  
  494.     /** 
  495.      * 构建rows数据集将Java中的List<map>转成javascript中List<Map>形式 
  496.      * @param list列表 
  497.      * @return 
  498.      */  
  499.     public String getRows(List list)  
  500.     {  
  501.         StringBuffer handlers=new StringBuffer("\n function getRows_grid_");  
  502.         handlers.append(getName());  
  503.         handlers.append("()\n{\n");  
  504.         SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");  
  505.         handlers.append("var rows=new List();\n");  
  506.         if(list!=null&&list.size()>0)  
  507.         {  
  508.             for(int i=0;i<list.size();i++)  
  509.             {  
  510.                 handlers.append("var map");  
  511.                 handlers.append(i);  
  512.                 handlers.append("=new Map();\n");  
  513.                 Map row=(Map) list.get(i);  
  514.                 for(Object key:row.keySet())  
  515.                 {  
  516.                     handlers.append("map");  
  517.                     handlers.append(i);  
  518.                     handlers.append(".put(‘");  
  519.                     handlers.append(key);  
  520.                     if(row.get(key)==null)  
  521.                     {  
  522.                         handlers.append("‘,");  
  523.                         handlers.append(row.get(key));  
  524.                         handlers.append(");\n");  
  525.                     }  
  526.                     else  
  527.                     {  
  528.                         Object param=row.get(key);  
  529.                         handlers.append("‘,‘");  
  530.                         if(param.getClass().getName().equals("java.sql.Timestamp")||param.getClass().getName().equals("java.util.Date"))  
  531.                         {  
  532.                             handlers.append(dateFormat.format(param));  
  533.                         }  
  534.                         else  
  535.                         {  
  536.                             handlers.append(row.get(key));  
  537.                         }  
  538.                         handlers.append("‘);\n");  
  539.                     }  
  540.                       
  541.                 }  
  542.                 handlers.append("rows.add(map");  
  543.                 handlers.append(i);  
  544.                 handlers.append(");\n");  
  545.             }  
  546.         }  
  547.         handlers.append("return rows;\n");  
  548.         handlers.append("\n}\n");  
  549.         return handlers.toString();  
  550.     }  
  551.     public void release() {  
  552.           
  553.         super.release();  
  554.         name=null;  
  555.         width=null;  
  556.         height=null;  
  557.         data=http://www.mamicode.com/null;  
  558.         multiple=false;  
  559.     }  
  560. }  
  561. <P> </P><P>package com.ts.taglib.html;</P><P>import java.util.List;</P><P>import javax.servlet.jsp.JspException;  
  562. import javax.servlet.jsp.tagext.TagSupport;</P><P>import com.ts.taglib.data.Column;  
  563. /** 
  564.  * 构建列控件 
  565.  * @author 陈双 
  566.  * @date 2012-09-23 
  567.  * @mail <A href="mailto:chenshuang_com@sina.com">chenshuang_com@sina.com</A> 
  568.  */  
  569. public class ColumnTag extends TagSupport {</P><P> private static final long serialVersionUID = 5477014869077280329L;  
  570.     private String name;//名称   
  571.     private String label;//标签   
  572.     private String type;//类型   
  573.     private String width;//宽度   
  574.     private String height;//高度   
  575.     private String size;//字符个数   
  576.  private String data;//如果是combox时,选项取数来源   
  577.  private String colspan;//跨列   
  578.  private String ondblclick;//双击事件,只是针对参照列   
  579.  private String drillEvent;//数据钻取时调用的函数    
  580.  private boolean hidden;//是否隐藏   
  581.  private boolean disabled;//是否可用   
  582.  private boolean sum;//是否汇总   
  583.  public ColumnTag()  
  584.     {  
  585.      super();  
  586.      name=null;  
  587.      label=null;  
  588.      type=null;  
  589.      width=null;  
  590.      height=null;  
  591.      size="14";  
  592.      data=http://www.mamicode.com/null;  
  593.      colspan=null;  
  594.      ondblclick=null;  
  595.      drillEvent=null;  
  596.      hidden=false;  
  597.      disabled=false;  
  598.      sum=false;  
  599.     }  
  600.  public String getName() {  
  601.   return name;  
  602.  }  
  603.  public void setName(String name) {  
  604.   this.name = name;  
  605.  }  
  606.  public String getLabel() {  
  607.   return label;  
  608.  }  
  609.  public void setLabel(String label) {  
  610.   this.label = label;  
  611.  }  
  612.  public String getType() {  
  613.   return type;  
  614.  }  
  615.  public void setType(String type) {  
  616.   this.type = type;  
  617.  }  
  618.  public String getWidth() {  
  619.   return width;  
  620.  }</P><P> public void setWidth(String width) {  
  621.   this.width = width;  
  622.  }</P><P> public String getHeight() {  
  623.   return height;  
  624.  }</P><P> public void setHeight(String height) {  
  625.   this.height = height;  
  626.  }  
  627.     public String getSize() {  
  628.   return size;  
  629.  }  
  630.  public void setSize(String size) {  
  631.   this.size = size;  
  632.  }  
  633.  public String getData() {  
  634.   return data;  
  635.  }  
  636.  public void setData(String data) {  
  637.   this.data = data;  
  638.  }  
  639.  public String getColspan() {  
  640.   return colspan;  
  641.  }</P><P> public void setColspan(String colspan) {  
  642.   this.colspan = colspan;  
  643.  }  
  644.  public String getOndblclick() {  
  645.   return ondblclick;  
  646.  }  
  647.  public void setOndblclick(String ondblclick) {  
  648.   this.ondblclick = ondblclick;  
  649.  }  
  650.  public String getDrillEvent() {  
  651.   return drillEvent;  
  652.  }  
  653.  public void setDrillEvent(String drillEvent) {  
  654.   this.drillEvent = drillEvent;  
  655.  }  
  656.  public boolean isHidden() {  
  657.   return hidden;  
  658.  }  
  659.  public void setHidden(boolean hidden) {  
  660.   this.hidden = hidden;  
  661.  }  
  662.  public boolean isDisabled() {  
  663.   return disabled;  
  664.  }  
  665.  public void setDisabled(boolean disabled) {  
  666.   this.disabled = disabled;  
  667.  }  
  668.  public boolean isSum() {  
  669.   return sum;  
  670.  }</P><P> public void setSum(boolean sum) {  
  671.   this.sum = sum;  
  672.  }  
  673.  public int doEndTag() throws JspException {  
  674.   Column column=new Column();  
  675.   column.setName(name);  
  676.   column.setLabel(label);  
  677.   column.setType(type);  
  678.   column.setWidth(width);  
  679.   column.setHeight(height);  
  680.   column.setSize(size);  
  681.   column.setData(data);  
  682.   column.setColspan(colspan);  
  683.   column.setOndblclick(ondblclick);  
  684.   column.setDrillEvent(drillEvent);  
  685.   column.setHidden(hidden);  
  686.   column.setDisabled(disabled);  
  687.   column.setSum(sum);  
  688.   List list=(List)pageContext.getAttribute("columnHeader"2);  
  689.   list.add(column);  
  690.   return 6;  
  691.  }  
  692.  public int doStartTag() throws JspException {  
  693.     
  694.   return 0;  
  695.  }  
  696.  public void release() {</P><P>  super.release();  
  697.   name=null;  
  698.      label=null;  
  699.      type=null;  
  700.      width=null;  
  701.      height=null;  
  702.      data=http://www.mamicode.com/null;  
  703.      colspan=null;  
  704.      size=null;  
  705.      ondblclick=null;  
  706.      drillEvent=null;  
  707.      hidden=false;  
  708.      disabled=false;  
  709.      sum=false;  
  710.  }  
  711. }  
  712. </P><P> </P><P>package com.ts.taglib.data;</P><P>import java.io.Serializable;  
  713. /** 
  714.  * 列数据 
  715.  * @author 陈双 
  716.  * @date 2012-09-23 
  717.  * @mail <A href="mailto:chenshuang_com@sina.com">chenshuang_com@sina.com</A> 
  718.  */  
  719. public class Column implements Serializable {</P><P> private static final long serialVersionUID = -2581722061552795107L;  
  720.  private String name;//名称   
  721.  private String label;//标签   
  722.  private String type;//类型   
  723.  private String width;//宽度   
  724.  private String height;//高度   
  725.  private String size;//字符个数   
  726.  private String data;//如果是combox时,选项取数来源   
  727.  private String colspan;//跨列   
  728.  private String rowspan;//跨行   
  729.  private String ondblclick;//双击事件,只是针对参照列   
  730.  private String drillEvent;//数据钻取时调用的函数    
  731.  private boolean hidden;//是否隐藏   
  732.  private boolean disabled;//是否可用   
  733.  private boolean sum;//是否汇总   
  734.  public String getName() {  
  735.   return name;  
  736.  }  
  737.  public void setName(String name) {  
  738.   this.name = name;  
  739.  }  
  740.  public String getLabel() {  
  741.   return label;  
  742.  }  
  743.  public void setLabel(String label) {  
  744.   this.label = label;  
  745.  }  
  746.  public String getType() {  
  747.   return type;  
  748.  }  
  749.  public void setType(String type) {  
  750.   this.type = type;  
  751.  }  
  752.  public String getWidth() {  
  753.   return width;  
  754.  }  
  755.  public void setWidth(String width) {  
  756.   this.width = width;  
  757.  }  
  758.  public String getHeight() {  
  759.   return height;  
  760.  }  
  761.  public void setHeight(String height) {  
  762.   this.height = height;  
  763.  }  
  764.  public String getSize() {  
  765.   return size;  
  766.  }  
  767.  public void setSize(String size) {  
  768.   this.size = size;  
  769.  }  
  770.  public String getData() {  
  771.   return data;  
  772.  }  
  773.  public void setData(String data) {  
  774.   this.data = data;  
  775.  }  
  776.  public String getColspan() {  
  777.   return colspan;  
  778.  }  
  779.  public void setColspan(String colspan) {  
  780.   this.colspan = colspan;  
  781.  }  
  782.  public String getRowspan() {  
  783.   return rowspan;  
  784.  }  
  785.  public void setRowspan(String rowspan) {  
  786.   this.rowspan = rowspan;  
  787.  }  
  788.  public String getOndblclick() {  
  789.   return ondblclick;  
  790.  }  
  791.  public void setOndblclick(String ondblclick) {  
  792.   this.ondblclick = ondblclick;  
  793.  }  
  794.  public String getDrillEvent() {  
  795.   return drillEvent;  
  796.  }  
  797.  public void setDrillEvent(String drillEvent) {  
  798.   this.drillEvent = drillEvent;  
  799.  }  
  800.  public boolean isHidden() {  
  801.   return hidden;  
  802.  }  
  803.  public void setHidden(boolean hidden) {  
  804.   this.hidden = hidden;  
  805.  }  
  806.  public boolean isDisabled() {  
  807.   return disabled;  
  808.  }  
  809.  public void setDisabled(boolean disabled) {  
  810.   this.disabled = disabled;  
  811.  }  
  812.  public boolean isSum() {  
  813.   return sum;  
  814.  }  
  815.  public void setSum(boolean sum) {  
  816.   this.sum = sum;  
  817.  }  
  818. }</P><P>package com.ts.taglib.data;</P><P>import java.io.Serializable;  
  819. import java.util.List;  
  820. import java.util.Map;  
  821. /** 
  822.  * 用于构建多级表头动态列表格对象 
  823.  * @author 陈双 
  824.  * @date 2012-09-22 
  825.  * @mail <A href="mailto:chenshuang_com@sina.com">chenshuang_com@sina.com</A> 
  826.  * 
  827.  */  
  828. public class DataGrid implements Serializable {</P><P> private static final long serialVersionUID = 3814622301555705194L;  
  829.     private String name;//名称   
  830.     private String width;//宽度   
  831.     private String height;//高度   
  832.     private boolean multiple;//多行数据是否有勾选框   
  833.     private List<Column[]> columns;//多级动态列   
  834.     private List<Map<String,Object>> data;//行数据   
  835.  private String dblclick;//双击事件   
  836.     public String getName() {  
  837.   return name;  
  838.  }  
  839.  public void setName(String name) {  
  840.   this.name = name;  
  841.  }  
  842.  public String getWidth() {  
  843.   return width;  
  844.  }  
  845.  public void setWidth(String width) {  
  846.   this.width = width;  
  847.  }  
  848.  public String getHeight() {  
  849.   return height;  
  850.  }  
  851.  public void setHeight(String height) {  
  852.   this.height = height;  
  853.  }  
  854.  public boolean isMultiple() {  
  855.   return multiple;  
  856.  }  
  857.  public void setMultiple(boolean multiple) {  
  858.   this.multiple = multiple;  
  859.  }  
  860.  public List<Column[]> getColumns() {  
  861.   return columns;  
  862.  }  
  863.  public void setColumns(List<Column[]> columns) {  
  864.   this.columns = columns;  
  865.  }  
  866.  public List<Map<String, Object>> getData() {  
  867.   return data;  
  868.  }  
  869.  public void setData(List<Map<String, Object>> data) {  
  870.   this.data = data;  
  871.  }  
  872.  public String getDblclick() {  
  873.   return dblclick;  
  874.  }  
  875.  public void setDblclick(String dblclick) {  
  876.   this.dblclick = dblclick;  
  877.  }  
  878.    
  879. }  
  880. </P><P>  
  881.  </P>  
package com.ts.taglib.html;

import java.lang.reflect.Field;

import javax.servlet.jsp.tagext.BodyTagSupport;
/**
 * 事件处理
 * @author 陈双
 * @date 2012-09-22
 * @mail chenshuang_com@sina.com
 */
public abstract class BaseHandlerTag extends BodyTagSupport{
    private static final long serialVersionUID = 715968190636480266L;
    private String onclick;
    private String ondblclick;
    private String onm ouseover;
    private String onm ouseout;
    private String onm ousedown;
    private String onm ouseup;
    private String onm ousemove;
    private String onkeydown;
    private String onkeyup;
    private String onkeypress;
    private String onfocus;
    private String onblur;
    private String onchange;
    private String onselect;
    private String styleId;
    private String style;
    private String styleClass;
    private boolean readonly;
    private boolean disabled;
    public BaseHandlerTag()
    {
    	super();
    	init();
    }
    public void init()
    {
    	onclick=null;
    	ondblclick=null;
    	onmouseover=null;
    	onmouseout=null;
    	onmousedown=null;
    	onmouseup=null;
    	onmousemove=null;
    	onkeydown=null;
    	onkeyup=null;
    	onkeypress=null;
    	onfocus=null;
    	onblur=null;
    	onchange=null;
    	onselect=null;
    	readonly=false;
    	disabled=false;
    }
	public String getOnclick() {
		return onclick;
	}
	public void setOnclick(String onclick) {
		this.onclick = onclick;
	}
	public String getOndblclick() {
		return ondblclick;
	}
	public void setOndblclick(String ondblclick) {
		this.ondblclick = ondblclick;
	}
	public String getOnmouseover() {
		return onm ouseover;
	}
	public void setOnmouseover(String onm ouseover) {
		this.onmouseover = onm ouseover;
	}
	public String getOnmouseout() {
		return onm ouseout;
	}
	public void setOnmouseout(String onm ouseout) {
		this.onmouseout = onm ouseout;
	}
	public String getOnmousedown() {
		return onm ousedown;
	}
	public void setOnmousedown(String onm ousedown) {
		this.onmousedown = onm ousedown;
	}
	public String getOnmouseup() {
		return onm ouseup;
	}
	public void setOnmouseup(String onm ouseup) {
		this.onmouseup = onm ouseup;
	}
	public String getOnmousemove() {
		return onm ousemove;
	}
	public void setOnmousemove(String onm ousemove) {
		this.onmousemove = onm ousemove;
	}
	public String getOnkeydown() {
		return onkeydown;
	}
	public void setOnkeydown(String onkeydown) {
		this.onkeydown = onkeydown;
	}
	public String getOnkeyup() {
		return onkeyup;
	}
	public void setOnkeyup(String onkeyup) {
		this.onkeyup = onkeyup;
	}
	public String getOnkeypress() {
		return onkeypress;
	}
	public void setOnkeypress(String onkeypress) {
		this.onkeypress = onkeypress;
	}
	public String getOnfocus() {
		return onfocus;
	}
	public void setOnfocus(String onfocus) {
		this.onfocus = onfocus;
	}
	public String getOnblur() {
		return onblur;
	}
	public void setOnblur(String onblur) {
		this.onblur = onblur;
	}
	public String getOnchange() {
		return onchange;
	}
	public void setOnchange(String onchange) {
		this.onchange = onchange;
	}
	public String getOnselect() {
		return onselect;
	}
	public void setOnselect(String onselect) {
		this.onselect = onselect;
	}
	public String getStyleId() {
		return styleId;
	}
	public void setStyleId(String styleId) {
		this.styleId = styleId;
	}
	public String getStyle() {
		return style;
	}
	public void setStyle(String style) {
		this.style = style;
	}
	public String getStyleClass() {
		return styleClass;
	}
	public void setStyleClass(String styleClass) {
		this.styleClass = styleClass;
	}
	public boolean isReadonly() {
		return readonly;
	}
	public void setReadonly(boolean readonly) {
		this.readonly = readonly;
	}
	public boolean isDisabled() {
		return disabled;
	}
	public void setDisabled(boolean disabled) {
		this.disabled = disabled;
	}
	public String prepareStyles()
	{
		StringBuffer handlers=new StringBuffer();
		prepareAttribute(handlers,"id",getStyleId());
		prepareAttribute(handlers,"style",getStyle());
		prepareAttribute(handlers,"class",getStyleClass());
		return handlers.toString();
	}
	public String prepareEvents()
	{
		StringBuffer handlers=new StringBuffer();
		prepareMouseEvents(handlers);
		prepareKeyEvents(handlers);
		prepareFocusEvents(handlers);
		prepareTextEvents(handlers);
		return handlers.toString();
	}
	public void prepareMouseEvents(StringBuffer handlers)
	{
		prepareAttribute(handlers,"onclick",getOnclick());
		prepareAttribute(handlers,"ondblclick",getOndblclick());
		prepareAttribute(handlers,"onmouseover",getOnmouseover());
		prepareAttribute(handlers,"onmouseout",getOnmouseout());
		prepareAttribute(handlers,"onmousedown",getOnmousedown());
		prepareAttribute(handlers,"onmouseup",getOnmouseup());
		prepareAttribute(handlers,"onmousemove",getOnmousemove());
	}
	public void prepareKeyEvents(StringBuffer handlers)
	{
		prepareAttribute(handlers,"onkeydown",getOnkeydown());
		prepareAttribute(handlers,"onkeyup",getOnkeyup());
		prepareAttribute(handlers,"onkeypress",getOnkeypress());
	}
	public void prepareFocusEvents(StringBuffer handlers)
	{
		prepareAttribute(handlers,"onfocus",getOnfocus());
		prepareAttribute(handlers,"onblur",getOnblur());
		if(isReadonly())
		{
			handlers.append(" readonly=\"readonly\"");
		}
		if(isDisabled())
		{
			handlers.append(" disabled=\"disabled\"");
		}
	}
	public void prepareTextEvents(StringBuffer handlers)
	{
		prepareAttribute(handlers,"onselect",getOnselect());
		prepareAttribute(handlers,"onchange",getOnchange());
	}
	public void prepareAttribute(StringBuffer handler,String property,Object value)
	{
		if(handler!=null&&property!=null&&value!=null)
		{
			handler.append(" ");
			handler.append(property);
			handler.append("=\"");
			handler.append(value);
			handler.append("\"");
		}
	}
	/**
	 * 取值
	 * @param name
	 * @return
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 */
	public Object findValue(String name) throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException
	{
		String[] elements=name.split("\\.");
		if(elements!=null&&elements.length>0)
		{
			Object bean=pageContext.getAttribute(elements[0],2);
			if(elements.length>2)
			{
				for(int i=1;i<elements.length;i++)
				{
					bean=getValue(bean, elements[i]);
				}
				return bean;
			}
			else
			{
				return getValue(bean, elements[1]);
			}
		}
		return null;
	}
	public Object getValue(Object bean,String property) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
	{
		if(bean!=null&&property!=null)
		{
			Field field=bean.getClass().getDeclaredField(property);
			field.setAccessible(true);
			return field.get(bean);
		}
		return null;
	}
	public void release() {
		// TODO Auto-generated method stub
		super.release();
		init();
	}
}
package com.ts.taglib.html;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.JspException;

import com.ts.taglib.data.Column;
import com.ts.taglib.data.DataGrid;

/**
 * 表格控件
 * @author 陈双
 * @date 2012-09-22
 * @mail chenshuang_com@sina.com
 *
 */
public class TableTag extends BaseHandlerTag {

	private static final long serialVersionUID = -5642687627324772161L;
    private String name;//名称
    private String width;//宽度
    private String height;//高度
    private String data;//取数
    private boolean multiple;//是否多行勾选框
	public TableTag()
    {
    	super();
    	name=null;
    	width=null;
    	height=null;
    	data=http://www.mamicode.com/null;"columnHeader", new ArrayList(),2);
		return 1;
	}
	/**
	 * 实现方式由Java构建所需的数据然后调用js创建表格
	 * @return
	 * @throws JspException
	 */
	public String createTable()throws JspException
	{
		StringBuffer handlers=new StringBuffer("<div id=\"main_grid_");
		handlers.append(getName());
		handlers.append("\"");
		handlers.append(" style=\"border:solid 1 #cccccc;");
		handlers.append("width:");
		handlers.append(getWidth());
		handlers.append(";height:");
		handlers.append(Integer.parseInt(getHeight())+25);
		handlers.append(";\">\n");
		handlers.append("<script type=\"text/javascript\" charset=\"utf-8\">\n");
		//处理数据
		List headerList=(List) pageContext.getAttribute("columnHeader", 2);
		if(headerList==null||headerList.size()==0)
		{
			throw new JspException("Table name is "+name+",列数必须大于0!");
		}
		handlers.append(getColumns(headerList));
		List list=(List) pageContext.getAttribute(data, 2);
		handlers.append(getRows(list));
		//调用js生成表格对象
		handlers.append("CreateTable(‘");
		handlers.append(getName());
		handlers.append("‘,‘main_grid_");
		handlers.append(getName());
		handlers.append("‘,");
		handlers.append(getWidth());
		handlers.append(",");
		handlers.append(getHeight());
		handlers.append(",");
		handlers.append(isMultiple());
		handlers.append(",getColumns_grid_");
		handlers.append(getName());
		handlers.append("(),getRows_grid_");
		handlers.append(getName());
		handlers.append("());\n</script>\n");
		handlers.append("<table cellspacing=0 height=25 width=");
		handlers.append(getWidth());
		handlers.append(" >\n<tr>\n<td style=\"height:18px;cursor:default;font-size:12px;font-family:verdana;text-align:right;\">共");
		Object total=pageContext.getAttribute("total", 2);
		if(total==null)
		{
			total=0;
		}
		handlers.append(total);
		handlers.append("页  当前显示第");
		Object current=pageContext.getAttribute("current",2);
		if(current==null)
		{
			current=0;
		}
		handlers.append(current);
		handlers.append("页  <a href=http://www.mamicode.com/"javascript:lastPage();\">上页</a> <a href=http://www.mamicode.com/"javascript:nextPage();\">下页</a>  <input type=\"hidden\" name=\"currentPage\"/>第<input name=\"toPage\" type=\"text\" size=3/>页</td>\n</tr>\n</table>\n");
		handlers.append("</div>\n");
		return handlers.toString();
	}
	/**
	 * 构建所有的列
	 * @param list
	 * @return
	 * @throws JspException
	 */
	private String getColumns(List list) throws JspException
	{
		StringBuffer columns=new StringBuffer();
		if(list!=null&&list.size()>0)
		{
			columns.append("function getColumns_grid_");
			columns.append(name);
			columns.append("()\n{\n");
			columns.append("var columns=new Array();\n");
			for(int i=0;i<list.size();i++)
			{
				Column column=(Column) list.get(i);
				columns.append("var gridColumn");
				columns.append(i);
				columns.append("=new GridColumn(‘");
				columns.append(column.getName());
				columns.append("‘,‘");
				columns.append(column.getLabel());
				columns.append("‘,‘");
				columns.append(column.getType());
				columns.append("‘,");
				columns.append(column.getWidth());
				columns.append(",");
				columns.append(column.getHeight());
				columns.append(",");
				columns.append("null");
				columns.append(",");
				columns.append(column.isHidden());
				columns.append(",");
				columns.append(column.isDisabled());
				columns.append(",");
				columns.append(column.isSum());
				columns.append(",");
				columns.append(column.getSize());
				columns.append(",");
				columns.append(column.getColspan());
				if(column.getOndblclick()!=null)
				{
					columns.append(",\"");
					columns.append(column.getOndblclick());
					columns.append("\",");
				}
				else
				{
					columns.append(",");
					columns.append("null,");
				}
				if(column.getDrillEvent()!=null)
				{
					columns.append("\"");
					columns.append(column.getDrillEvent());
					columns.append("\");\n");
				}
				else
				{
					columns.append("null);\n");
				}
				columns.append("columns[");
				columns.append(i);
				columns.append("]=gridColumn");
				columns.append(i);
				columns.append(";\n");
			}
		    columns.append("return columns;\n}");
		}
		return columns.toString();
	}
	/**
	 * 构建rows数据集将Java中的List<map>转成javascript中List<Map>形式
	 * @param list列表
	 * @return
	 */
	public String getRows(List list)
	{
		StringBuffer handlers=new StringBuffer("\n function getRows_grid_");
		handlers.append(getName());
		handlers.append("()\n{\n");
		SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		handlers.append("var rows=new List();\n");
		if(list!=null&&list.size()>0)
		{
			for(int i=0;i<list.size();i++)
			{
				handlers.append("var map");
				handlers.append(i);
				handlers.append("=new Map();\n");
				Map row=(Map) list.get(i);
				for(Object key:row.keySet())
				{
					handlers.append("map");
					handlers.append(i);
					handlers.append(".put(‘");
					handlers.append(key);
					if(row.get(key)==null)
					{
						handlers.append("‘,");
						handlers.append(row.get(key));
						handlers.append(");\n");
					}
					else
					{
						Object param=row.get(key);
						handlers.append("‘,‘");
						if(param.getClass().getName().equals("java.sql.Timestamp")||param.getClass().getName().equals("java.util.Date"))
						{
							handlers.append(dateFormat.format(param));
						}
						else
						{
							handlers.append(row.get(key));
						}
						handlers.append("‘);\n");
					}
					
				}
				handlers.append("rows.add(map");
				handlers.append(i);
				handlers.append(");\n");
			}
		}
		handlers.append("return rows;\n");
		handlers.append("\n}\n");
		return handlers.toString();
	}
	public void release() {
		
		super.release();
		name=null;
    	width=null;
    	height=null;
    	data=http://www.mamicode.com/null;>
 

package com.ts.taglib.html;

import java.util.List;

import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport;

import com.ts.taglib.data.Column; /**  * 构建列控件  * @author 陈双  * @date 2012-09-23  * @mail chenshuang_com@sina.com  */ public class ColumnTag extends TagSupport {

 private static final long serialVersionUID = 5477014869077280329L;     private String name;//名称     private String label;//标签     private String type;//类型     private String width;//宽度     private String height;//高度     private String size;//字符个数  private String data;//如果是combox时,选项取数来源  private String colspan;//跨列  private String ondblclick;//双击事件,只是针对参照列  private String drillEvent;//数据钻取时调用的函数  private boolean hidden;//是否隐藏  private boolean disabled;//是否可用  private boolean sum;//是否汇总  public ColumnTag()     {      super();      name=null;      label=null;      type=null;      width=null;      height=null;      size="14";      data=http://www.mamicode.com/null;>

 public void setWidth(String width) {   this.width = width;  }

 public String getHeight() {   return height;  }

 public void setHeight(String height) {   this.height = height;  }     public String getSize() {   return size;  }  public void setSize(String size) {   this.size = size;  }  public String getData() {   return data;  }  public void setData(String data) {   this.data = http://www.mamicode.com/data;>

 public void setColspan(String colspan) {   this.colspan = colspan;  }  public String getOndblclick() {   return ondblclick;  }  public void setOndblclick(String ondblclick) {   this.ondblclick = ondblclick;  }  public String getDrillEvent() {   return drillEvent;  }  public void setDrillEvent(String drillEvent) {   this.drillEvent = drillEvent;  }  public boolean isHidden() {   return hidden;  }  public void setHidden(boolean hidden) {   this.hidden = hidden;  }  public boolean isDisabled() {   return disabled;  }  public void setDisabled(boolean disabled) {   this.disabled = disabled;  }  public boolean isSum() {   return sum;  }

 public void setSum(boolean sum) {   this.sum = sum;  }  public int doEndTag() throws JspException {   Column column=new Column();   column.setName(name);   column.setLabel(label);   column.setType(type);   column.setWidth(width);   column.setHeight(height);   column.setSize(size);   column.setData(data);   column.setColspan(colspan);   column.setOndblclick(ondblclick);   column.setDrillEvent(drillEvent);   column.setHidden(hidden);   column.setDisabled(disabled);   column.setSum(sum);   List list=(List)pageContext.getAttribute("columnHeader", 2);   list.add(column);   return 6;  }  public int doStartTag() throws JspException {      return 0;  }  public void release() {

  super.release();   name=null;      label=null;      type=null;      width=null;      height=null;      data=http://www.mamicode.com/null;>

 

package com.ts.taglib.data;

import java.io.Serializable; /**  * 列数据  * @author 陈双  * @date 2012-09-23  * @mail chenshuang_com@sina.com  */ public class Column implements Serializable {

 private static final long serialVersionUID = -2581722061552795107L;  private String name;//名称  private String label;//标签  private String type;//类型  private String width;//宽度  private String height;//高度  private String size;//字符个数  private String data;//如果是combox时,选项取数来源  private String colspan;//跨列  private String rowspan;//跨行  private String ondblclick;//双击事件,只是针对参照列  private String drillEvent;//数据钻取时调用的函数  private boolean hidden;//是否隐藏  private boolean disabled;//是否可用  private boolean sum;//是否汇总  public String getName() {   return name;  }  public void setName(String name) {   this.name = name;  }  public String getLabel() {   return label;  }  public void setLabel(String label) {   this.label = label;  }  public String getType() {   return type;  }  public void setType(String type) {   this.type = type;  }  public String getWidth() {   return width;  }  public void setWidth(String width) {   this.width = width;  }  public String getHeight() {   return height;  }  public void setHeight(String height) {   this.height = height;  }  public String getSize() {   return size;  }  public void setSize(String size) {   this.size = size;  }  public String getData() {   return data;  }  public void setData(String data) {   this.data = http://www.mamicode.com/data;>

package com.ts.taglib.data;

import java.io.Serializable; import java.util.List; import java.util.Map; /**  * 用于构建多级表头动态列表格对象  * @author 陈双  * @date 2012-09-22  * @mail chenshuang_com@sina.com  *  */ public class DataGrid implements Serializable {

 private static final long serialVersionUID = 3814622301555705194L;     private String name;//名称     private String width;//宽度     private String height;//高度     private boolean multiple;//多行数据是否有勾选框     private List<Column[]> columns;//多级动态列     private List<Map<String,Object>> data;//行数据  private String dblclick;//双击事件     public String getName() {   return name;  }  public void setName(String name) {   this.name = name;  }  public String getWidth() {   return width;  }  public void setWidth(String width) {   this.width = width;  }  public String getHeight() {   return height;  }  public void setHeight(String height) {   this.height = height;  }  public boolean isMultiple() {   return multiple;  }  public void setMultiple(boolean multiple) {   this.multiple = multiple;  }  public List<Column[]> getColumns() {   return columns;  }  public void setColumns(List<Column[]> columns) {   this.columns = columns;  }  public List<Map<String, Object>> getData() {   return data;  }  public void setData(List<Map<String, Object>> data) {   this.data = http://www.mamicode.com/data;>

 

[java] view plain copy print ?
  1. js代码:  
js代码:
[java] view plain copy print ?
  1. <P>//===========================================================================   
  2. /** 
  3.  *表格操作 
  4.  <A href="mailto:*@author">*@author</A> 陈双 
  5.  <A href="mailto:*@date">*@date</A> 2012-09-26 
  6.  <A href="mailto:*@mail">*@mail</A> <A href="mailto:chenshuang_com@sina.com">chenshuang_com@sina.com</A> 
  7.  */  
  8. //===========================================================================   
  9. var globeVariable=new Map();//全局变量列表   
  10. /** 
  11.  * 注册全局变量 
  12.  * @param object 对象id 
  13.  * @param property 变量名称 
  14.  * @param value 值 
  15.  * @return 
  16.  */  
  17. function put(object,property,value)  
  18. {  
  19.  globeVariable.put(object+"_"+property,value);  
  20. }  
  21. /** 
  22.  * 取出全局变量 
  23.  * @param object 对象id 
  24.  * @param property 变量名称 
  25.  * @return 
  26.  */  
  27. function get(object,property)  
  28. {  
  29.  return globeVariable.get(object+"_"+property);  
  30. }  
  31. /** 
  32.  * 获取选中行单元格的值 
  33.  * @param id 表格id 
  34.  * @param cellIndex 单元格索引 
  35.  * @param isMultiple 是否有勾选框 
  36.  * @return Array 选中行的id值的集合 
  37.  */  
  38. function getSelectedCellValue(id,cellIndex,isMultiple){  
  39.  if(!id)return null;  
  40.  var values=new Array();//所有选中的id值   
  41.  if(isMultiple)  
  42.  {  
  43.   var checkList=document.getElementsByName(id+"chbox");  
  44.   var rows=new Array();//选中的行集合   
  45.   var index=-1;  
  46.   if(checkList && checkList.length>0)  
  47.   {  
  48.    for(var i=0;i<checkList.length;i++)  
  49.    {  
  50.     if(checkList[i].checked)  
  51.     {  
  52.      index++;  
  53.      rows[index]=checkList[i].parentNode.parentNode;  
  54.     }  
  55.    }  
  56.   }  
  57.   if(rows.length==0)  
  58.   {  
  59.    alert("请选中一行!");  
  60.    return null;  
  61.   }  
  62.   else  
  63.   {  
  64.    for(var i=0;i<rows.length;i++)  
  65.    {  
  66.     values[i]=rows[i].cells[parseInt(cellIndex)+2].innerText;  
  67.    }  
  68.    return values;  
  69.   }  
  70.  }  
  71.  else  
  72.  {  
  73.   var _current_row=get(id,‘_current_row‘);  
  74.   if(_current_row==null)  
  75.   {  
  76.    alert("请选择一行!");  
  77.    return null;  
  78.   }  
  79.   else  
  80.   {  
  81.    values[0]=document.getElementById(id).rows[_current_row].cells[parseInt(cellIndex)+1].innerText;  
  82.    return values;  
  83.   }  
  84.  }  
  85.  return null;  
  86. }  
  87. /** 
  88.  * 创建可编辑的表格对象,并添加到指定的父节点中 
  89.  * @param id 表格名称 
  90.  * @param parentId 父节点id 
  91.  * @param width 表格宽度 
  92.  * @param height 表格高度 
  93.  * @param isMultiple 多行是否有勾选框 
  94.  * @param columns 表格所有的列,以数组的形式保存GridColumn对象 
  95.  * @param rows 数据列表,它是以集合List的形式保存Map,其中key是name,value是值 
  96.  * @param status 表格状态值: read只读,update可修改,insert新增 
  97.  */  
  98. function CreateTable(id,parentId,width,height,isMultiple,columns,rows)  
  99. {  
  100.  if((!id)|(!parentId)||(!width)||(!height)||(!columns)||(!rows))  
  101.  {  
  102.   return;  
  103.  }  
  104.  var _sum_columns=null;//汇总列   
  105.  var _isHbar=false;//是否有横向滚动条   
  106.  var flag=false;//默认没有跨列操作   
  107.  var first="";//声明第一列表   
  108.  var title="";//标题表   
  109.  var data=http://www.mamicode.com/"";//数据表   
  110.  var sum="";//汇总表   
  111.  var columnWidth=125;//默认列宽   
  112.  for(var i=0;i<columns.length;i++)  
  113.  {//检查是否有跨列操作   
  114.   if(columns[i].colspan)  
  115.   {  
  116.    flag=true;  
  117.    break;  
  118.   }  
  119.  }  
  120.  put(id, ‘flag‘, flag);  
  121.  //构建标题列   
  122.  if(flag)  
  123.  {//有跨列操作   
  124.   for(var i=0;i<2;i++)  
  125.   {  
  126.    if(i==0)  
  127.    {  
  128.     title="<tr><td class=‘firstcolumn‘ rowspan=‘2‘>&nbsp;</td>";  
  129.     if(isMultiple)  
  130.     {  
  131.      title+="<td class=‘column‘ width=‘30‘ rowspan=‘2‘ align=‘center‘><input name=‘checkbox‘ type=‘checkbox‘ onclick=\"checkAllForGrid(this.checked,‘"+id+"chbox‘);\"/></td>";  
  132.     }  
  133.    }  
  134.    else  
  135.    {  
  136.     title+="<tr>";  
  137.    }  
  138.    for(var j=0;j<columns.length;j++)  
  139.    {  
  140.     if(columns[j].colspan)  
  141.     {//执行跨列   
  142.      if(i==0)  
  143.      {//第一行   
  144.       title+="<td class=‘column‘ align=‘center‘ colspan=‘"+columns[j].colspan+"‘";  
  145.       if(columns[j].width)  
  146.       {  
  147.        title+=" width=‘"+(columns[j].width*parseInt(columns[j].colspan))+"‘";  
  148.       }  
  149.       else  
  150.       {  
  151.        title+=" width=‘"+(columnWidth*parseInt(columns[j].colspan))+"‘";  
  152.       }  
  153.       title+=">"+(columns[j].label.split(",")[0])+"</td>";  
  154.      }  
  155.      else  
  156.      {//第二行   
  157.       title+="<td class=‘column‘ align=‘center‘";  
  158.       if(columns[j].hidden)  
  159.       {  
  160.        columns[j].width=1;  
  161.        title+=" style=\"border:none;\"";  
  162.       }  
  163.       if(columns[j].width)  
  164.       {  
  165.        title+=" width=‘"+columns[j].width+"‘";  
  166.       }  
  167.       else  
  168.       {  
  169.        title+=" width=‘"+columnWidth+"‘";  
  170.       }  
  171.       title+=">"+(columns[j].label.split(",")[1])+"</td>";  
  172.      }  
  173.     }  
  174.     else   
  175.     {//执行跨行   
  176.      var rs=columns[j].label.indexOf(‘,‘);//是否是跨列   
  177.      if(i==0)  
  178.      {//跨行操作   
  179.       if(rs==-1)  
  180.       {//跨行   
  181.        title+="<td class=‘column‘ align=‘center‘ rowspan=‘2‘";  
  182.        if(columns[j].hidden)  
  183.        {  
  184.         columns[j].width=1;  
  185.         title+=" style=\"border:none;\"";  
  186.        }  
  187.        if(columns[j].width)  
  188.        {  
  189.         title+=" width=‘"+columns[j].width+"‘";  
  190.        }  
  191.        else  
  192.        {  
  193.         title+=" width=‘"+columnWidth+"‘";  
  194.        }  
  195.        title+=">"+columns[j].label+"</td>";  
  196.       }  
  197.      }  
  198.      else  
  199.      {//跨列操作   
  200.       if(rs!=-1)  
  201.       {//跨行   
  202.        title+="<td class=‘column‘ align=‘center‘";  
  203.        if(columns[j].hidden)  
  204.        {  
  205.         columns[j].width=1;  
  206.         title+=" style=\"border:none;\"";  
  207.        }  
  208.        if(columns[j].width)  
  209.        {  
  210.         title+=" width=‘"+columns[j].width+"‘";  
  211.        }  
  212.        else  
  213.        {  
  214.         title+=" width=‘"+columnWidth+"‘";  
  215.        }  
  216.        title+=">"+(columns[j].label.split(‘,‘)[1])+"</td>";  
  217.       }  
  218.      }  
  219.     }  
  220.    }  
  221.    if(i==0)  
  222.    {//最后一列   
  223.     title+="<td class=‘lastcolumn‘ rowspan=‘2‘>&nbsp;</td></tr>";  
  224.    }  
  225.    else  
  226.    {  
  227.     title+="</tr>";  
  228.    }  
  229.   }  
  230.  }  
  231.  else  
  232.  {//正常情况   
  233.   title="<tr><td class=‘firstcolumn‘>&nbsp;</td>";  
  234.   if(isMultiple)  
  235.   {  
  236.    title+="<td class=‘column‘ width=‘30‘ align=‘center‘><input name=‘checkbox‘ type=‘checkbox‘ onclick=\"checkAllForGrid(this.checked,‘"+id+"chbox‘);\"/></td>";  
  237.   }  
  238.   for(var i=0;i<columns.length;i++)  
  239.   {  
  240.    title+="<td class=‘column‘ align=‘center‘";  
  241.    if(columns[i].hidden)  
  242.    {  
  243.     columns[i].width=1;  
  244.     title+=" style=\"border:none;\"";  
  245.    }  
  246.    if(columns[i].width)  
  247.    {  
  248.     title+=" width=‘"+columns[i].width+"‘";  
  249.    }  
  250.    else  
  251.    {  
  252.     title+=" width=‘"+columnWidth+"‘";  
  253.    }   
  254.    title+=" onclick=\"sortTableForGrid(‘"+id+"‘,"+i+","+isMultiple+");\"";  
  255.    title+=">"+columns[i].label+"<span></span></td>";  
  256.   }  
  257.   title+="<td class=‘lastcolumn‘>&nbsp;</td></tr>";  
  258.  }  
  259.  if(columns&&columns.length>0)  
  260.  {//汇总表格   
  261.   sum="<tr><td class=‘firstcolumn‘>汇总</td>";  
  262.   if(isMultiple)  
  263.   {  
  264.    sum+="<td class=‘column‘ width=‘30‘>&nbsp;</td>";  
  265.   }  
  266.   for(var i=0;i<columns.length;i++)  
  267.   {  
  268.    sum+="<td class=‘column‘ align=‘center‘";  
  269.    if(columns[i].hidden)  
  270.    {  
  271.     columns[i].width=1;  
  272.     sum+=" style=\"border:none;\"";  
  273.    }  
  274.    if(columns[i].width)  
  275.    {  
  276.     sum+=" width=‘"+columns[i].width+"‘";  
  277.    }  
  278.    else  
  279.    {  
  280.     sum+=" width=‘"+columnWidth+"‘";  
  281.    }   
  282.    sum+=">&nbsp;</td>";  
  283.   }  
  284.   sum+="<td class=‘lastcolumn‘>&nbsp;</td></tr>";  
  285.  }  
  286.  if(rows&&rows.size()>0)  
  287.  {//构建第一列和数据表格   
  288.   if(flag)  
  289.   {  
  290.    first="<tr><td>&nbsp;</td></tr>";  
  291.    first+="<tr><td>&nbsp;</td></tr>";  
  292.   }  
  293.   else  
  294.   {  
  295.    first="<tr><td>&nbsp;</td></tr>";  
  296.   }  
  297.     
  298.   for(var i=0;i<rows.size();i++)  
  299.   {  
  300.    first+="<tr><td style=‘border-right:none;‘>"+(i+1)+"</td></tr>";  
  301.    data+="<tr><td class=‘firstcolumn‘ style=‘border-bottom-color:#cccccc;‘>"+(i+1)+"</td>";  
  302.    if(isMultiple)  
  303.    {  
  304.     data+="<td width=‘30‘ align=‘center‘><input type=‘checkbox‘ name=‘"+id+"chbox‘/></td>";  
  305.    }  
  306.    var rowId="rowid_"+(i+1);  
  307.    var map=rows.get(i);  
  308.    for(var j=0;j<columns.length;j++)  
  309.    {  
  310.     data+="<td";  
  311.     if(columns[j].hidden)  
  312.     {  
  313.      columns[j].width=1;  
  314.      data+=" style=\"border-right:none;\"";  
  315.     }  
  316.     if(columns[j].width)  
  317.     {  
  318.      data+=" width=‘"+columns[j].width+"‘";  
  319.     }  
  320.     else  
  321.     {  
  322.      data+=" width=‘"+columnWidth+"‘";  
  323.     }  
  324.     data+=">";  
  325.     data+=map.get(columns[j].name)==null?"&nbsp;":map.get(columns[j].name);  
  326.     data+="</td>";  
  327.    }  
  328.    data+="<td class=‘lastdata‘>";  
  329.    data+="<input name=‘rowid‘ type=‘hidden‘ value=http://www.mamicode.com/‘"+(rowId)+"‘/>";  
  330.    data+="&nbsp;</td></tr>";  
  331.   }  
  332.  }  
  333.  //构建汇总列   
  334.     _sum_columns=new Array();//初始化   
  335.  var k=0;  
  336.  for(var i=0;i<columns.length;i++)  
  337.  {  
  338.   if(columns[i].sum&&(columns[i].type=="int"||columns[i].type=="number"))  
  339.   {  
  340.    if(isMultiple)  
  341.    {  
  342.     _sum_columns[k]=i+2;  
  343.    }  
  344.    else  
  345.    {  
  346.     _sum_columns[k]=i+1;  
  347.    }  
  348.    k++;  
  349.   }  
  350.  }  
  351.  put(id,‘_sum_columns‘,_sum_columns);  
  352.  var allWidth=0;  
  353.  for(var i=0;i<columns.length;i++)  
  354.  {  
  355.   if(columns[i].width)  
  356.   {  
  357.    allWidth+=parseInt(columns[i].width);  
  358.   }  
  359.   else   
  360.   {  
  361.    allWidth+=parseInt(columnWidth);  
  362.   }  
  363.  }  
  364.  allWidth+=30;  
  365.  if(isMultiple)  
  366.  {  
  367.   allWidth+=30;  
  368.  }  
  369.  var total=1;  
  370.  if(allWidth>width)  
  371.  {  
  372.   total=2;  
  373.   _isHbar=true;  
  374.  }  
  375.  put(id, ‘_isHbar‘, _isHbar);  
  376.  //构建隐藏行   
  377.  for(var i=0;i<total;i++)  
  378.  {  
  379.   data+="<tr><td style=\"border:0;\">&nbsp;</td>";  
  380.   for(var j=0;j<columns.length;j++)  
  381.   {  
  382.    data+="<td style=\"border:0;\">&nbsp;</td>";  
  383.   }  
  384.   data+="<td style=\"border:0;\">&nbsp;</td>";  
  385.   first+="<tr><td style=\"border:0;background-color:white;\">&nbsp;</td></tr>";  
  386.  }  
  387.  var title_html="<table id=‘header_"+id+"‘ cellspacing=‘0‘ cellpadding=‘0‘ class=‘titlecolumn‘>"+title+"</table>";  
  388.  var first_html="<table id=‘first_"+id+"‘ cellspacing=‘0‘ cellpadding=‘0‘ class=‘slidecolumn‘>"+first+"</table>";  
  389.  var data_html="<table id=‘"+id+"‘ cellspacing=‘0‘ cellpadding=‘0‘ class=‘datacolumn‘>";  
  390.  data_html+=title+data+"</table>";  
  391.  var sum_html="<table id=‘sum_"+id+"‘ cellspacing=‘0‘"+" cellpadding=‘0‘ style=‘width:100%;position:absolute;top:";  
  392.  if(_isHbar)  
  393.  {  
  394.   sum_html+=+(parseInt(height)-18-17);  
  395.  }  
  396.  else  
  397.  {  
  398.   sum_html+=(parseInt(height)-17);  
  399.  }  
  400.  sum_html+=";left:0;z-index:4;‘/>"+sum+"</table>";  
  401.  _execute(id, parentId, width, height, first_html+title_html+data_html+sum_html,isMultiple);  
  402.  sumRowForGrid(id);  
  403. }  
  404. /** 
  405.  * 列结构 
  406.  * @param name名称 
  407.  * @param label 标签 
  408.  * @param type 类型 
  409.  * @param width 宽度 
  410.  * @param height 高度 
  411.  * @param data 列数据来源是一个数组 
  412.  * @param hidden 是否隐藏 
  413.  * @param disabled 是否可用 
  414.  * @param sum 是否汇总 
  415.  * @param size 字符个数 
  416.  * @param colspan 跨列 
  417.  * @param rowspan 跨行 
  418.  * @param ondblclick 鼠标双击事件 
  419.  * @param drillEvent 数据钻取处理函数 
  420.  */  
  421. function GridColumn(name,label,type,width,height,data,hidden,disabled,sum,size,colspan,ondblclick,drillEvent)  
  422. {  
  423.  this.name=name;  
  424.  this.label=label;  
  425.  this.type=type;  
  426.  this.width=width;  
  427.  this.height=height;  
  428.  this.data=http://www.mamicode.com/data;
  429.  this.hidden=hidden;  
  430.  this.disabled=disabled;  
  431.  this.sum=sum;  
  432.  this.size=size;  
  433.  this.colspan=colspan;  
  434.  this.ondblclick=ondblclick;  
  435.  this.drillEvent=drillEvent;  
  436. }  
  437. /** 
  438.  <A href="mailto:*@param">*@param</A> 排序 
  439.  <A href="mailto:*@param">*@param</A> id为表格id 
  440.  <A href="mailto:*@param">*@param</A> index:列索引 
  441.  <A href="mailto:*@param">*@param</A> sort:asc是升序,dsc是降序 
  442.  <A href="mailto:*@param">*@param</A> isMultiple是否多行 
  443.  */  
  444. function sortTableForGrid(id,index,isMultiple)  
  445. {  
  446.  var flag=get(id, ‘flag‘);  
  447.  var _isHbar=get(id, ‘_isHbar‘);  
  448.  var tr=new Array();//行集合   
  449.  var td=new Array();//列集合   
  450.  var temp;//临时单元格   
  451.     var table=document.getElementById(id);  
  452.     var header=document.getElementById("header_"+id);  
  453.     var sort;  
  454.     if(flag)  
  455.     {  
  456.      return;  
  457.     }  
  458.     if(isMultiple)  
  459.     {  
  460.      index+=2;  
  461.     }  
  462.     else  
  463.     {  
  464.      index+=1;  
  465.     }  
  466.     var html=header.rows[0].cells[index].childNodes[1].innerHTML;  
  467.     if(html=="")  
  468.     {  
  469.        sort="asc";  
  470.        header.rows[0].cells[index].childNodes[1].innerHTML="▲";  
  471.     }  
  472.     else if(html=="▲")  
  473.     {  
  474.        sort="dsc";  
  475.        header.rows[0].cells[index].childNodes[1].innerHTML="▼";  
  476.     }  
  477.     else if(html=="▼")  
  478.     {  
  479.        sort="asc";  
  480.        header.rows[0].cells[index].childNodes[1].innerHTML="▲";  
  481.     }  
  482.     var k=1;  
  483.     if(isMultiple)  
  484.     {  
  485.      k=2;  
  486.     }  
  487.     for(var i=k;i<header.rows[0].cells.length-1;i++)  
  488.     {  
  489.        if(i!=index)  
  490.        {  
  491.            header.rows[0].cells[i].childNodes[1].innerHTML="";  
  492.        }  
  493.     }  
  494.     if(_isHbar)  
  495.     {  
  496.      for(var i=1;i<table.rows.length-3;i++)  
  497.         {  
  498.            tr[i-1]=table.rows[i];  
  499.            td[i-1]=table.rows[i].cells[index];  
  500.         }  
  501.     }  
  502.     else  
  503.     {  
  504.      for(var i=1;i<table.rows.length-2;i++)  
  505.         {  
  506.            tr[i-1]=table.rows[i];  
  507.            td[i-1]=table.rows[i].cells[index];  
  508.         }  
  509.     }  
  510.       
  511.     var isNumber=false;//是数字   
  512.     for(var i=0;i<td.length;i++)  
  513.     {  
  514.        if(!checkValueForGrid(td[i].innerHTML))  
  515.        {  
  516.        isNumber=true;//字符串   
  517.           break;  
  518.        }  
  519.     }  
  520.     //开始比较数据   
  521.     for(var i=0;i<td.length;i++)  
  522.     {  
  523.          for(var j=0;j<td.length;j++)  
  524.          {  
  525.             if(isNumber)  
  526.             {//字符串比较   
  527.                 if(sort=="asc")  
  528.                 {  
  529.                      if(td[i].innerHTML<td[j].innerHTML)  
  530.                      {  
  531.                          temp=td[i];  
  532.                          td[i]=td[j];  
  533.                          td[j]=temp;  
  534.                      }  
  535.                 }  
  536.                 else if(sort=="dsc")  
  537.                 {  
  538.                     if(td[i].innerHTML>td[j].innerHTML)  
  539.                      {  
  540.                          temp=td[i];  
  541.                          td[i]=td[j];  
  542.                          td[j]=temp;  
  543.                      }  
  544.                 }  
  545.             }  
  546.             else  
  547.             {//数字比较   
  548.                if(sort=="asc")  
  549.                 {  
  550.                      if(parseFloat(td[i].innerHTML)<parseFloat(td[j].innerHTML))  
  551.                      {  
  552.                          temp=td[i];  
  553.                          td[i]=td[j];  
  554.                          td[j]=temp;  
  555.                      }  
  556.                 }  
  557.                 else if(sort=="dsc")  
  558.                 {  
  559.                     if(parseFloat(td[i].innerHTML)>parseFloat(td[j].innerHTML))  
  560.                      {  
  561.                          temp=td[i];  
  562.                          td[i]=td[j];  
  563.                          td[j]=temp;  
  564.                      }  
  565.                 }  
  566.             }  
  567.          }  
  568.     }  
  569.     var cellCount=table.rows[0].cells.length;  
  570.     var tempTR=new Array();//临时行   
  571.     for(var i=0;i<tr.length;i++)  
  572.     {  
  573.         var tempTD=new Array();//临时列集合   
  574.         for(var j=k;j<cellCount-1;j++)  
  575.         {  
  576.            tempTD[j]=td[i].parentNode.cells[j].innerHTML;  
  577.         }  
  578.         tempTR[i]=tempTD;  
  579.     }  
  580.     for(var i=0;i<tr.length;i++)  
  581.     {  
  582.        for(var j=k;j<cellCount-1;j++)  
  583.        {  
  584.            tr[i].cells[j].innerHTML=tempTR[i][j];  
  585.        }  
  586.     }  
  587. }  
  588. /** 
  589.  *汇总行 
  590.  <A href="mailto:*@param">*@param</A> id 表格id 
  591.  <A href="mailto:*@param">*@param</A> columns 汇总列数组 
  592.  */  
  593. function sumRowForGrid(id)  
  594. {  
  595.    var columns=get(id,‘_sum_columns‘);  
  596.    var _isHbar=get(id,‘_isHbar‘);  
  597.    var flag=get(id,‘flag‘);  
  598.    if(columns==undefined||columns.length==0)  
  599.    {  
  600.         return;  
  601.    }  
  602.    var sumTR=new Array();//汇总行临时数据   
  603.    var table=document.getElementById(id);  
  604.    var sum_table=document.getElementById("sum_"+id);  
  605.    if((_isHbar&&flag==false&&table.rows.length==3)||(_isHbar&&flag&&table.rows.length==4)||(!_isHbar&&flag&&table.rows.length==3)||(!_isHbar&&!flag&&table.rows.length==2))  
  606.    {  
  607.     for(var i=0;i<columns.length;i++)  
  608.     {  
  609.      sum_table.rows[0].cells[columns[i]].innerHTML=‘&nbsp;‘;  
  610.     }  
  611.     return;  
  612.    }  
  613.    var index=1;  
  614.    if(flag)  
  615.    {  
  616.     index=2;  
  617.    }  
  618.    var end=table.rows.length-1;  
  619.    if(_isHbar)  
  620.    {  
  621.      end=table.rows.length-2;  
  622.    }  
  623.    for(var i=index;i<end;i++)  
  624.    {  
  625.        for(var j=0;j<columns.length;j++)  
  626.        {  
  627.           var value=http://www.mamicode.com/table.rows[i].cells[columns[j]].innerText;
  628.           if(!checkValueForGrid(value))  
  629.           {  
  630.              value=http://www.mamicode.com/"0";  
  631.           }  
  632.           if(sumTR[j]==undefined)  
  633.           {  
  634.               sumTR[j]=value;  
  635.           }  
  636.           else if(sumTR[j]!="")  
  637.           {  
  638.               sumTR[j]=parseFloat(sumTR[j])+parseFloat(value);  
  639.           }  
  640.        }  
  641.    }  
  642.    //填充汇总行   
  643.    for(var i=0;i<columns.length;i++)  
  644.    {  
  645.     sum_table.rows[0].cells[columns[i]].innerHTML=sumTR[i];  
  646.    }  
  647. }  
  648. /** 
  649.  *检查value是否为数字,返回true是数字,返回false为字符串 
  650.  <A href="mailto:*@param">*@param</A> value要检查的值 
  651.  */  
  652. function checkValueForGrid(value)  
  653. {  
  654.   if(value && value.length>0)  
  655.   {  
  656.     var newValue=http://www.mamicode.com/value.replace(/s+/g,"");  
  657.     value=http://www.mamicode.com/newValue;
  658.   }  
  659.   else  
  660.   {  
  661.    return false;  
  662.   }  
  663.   if(value.length>0 && value.indexOf(‘.‘)!=-1)  
  664.   {//判断是否是小数   
  665.    var express=/^\d+.\d+$/;//匹配小数   
  666.    if(express.test(value)){  
  667.      return true;  
  668.    }  
  669.    else  
  670.    {  
  671.     return false;  
  672.    }  
  673.   }  
  674.   else  
  675.   {  
  676.    var express=/^\d+$/;  
  677.    if(express.test(value))  
  678.    {  
  679.     return true;  
  680.    }  
  681.    else  
  682.    {  
  683.     return false;  
  684.    }  
  685.   }  
  686.   return false;   
  687. }  
  688. /** 
  689.  * 全选 
  690.  <A href="mailto:*@param">*@param</A> checked是否选中true为选中,false没选中 
  691.  <A href="mailto:*@param">*@param</A> name 名称 
  692.  */  
  693. function checkAllForGrid(checked,name)  
  694. {  
  695.  var checkList=document.getElementsByName(name);  
  696.  if(checkList && checkList.length>0)  
  697.  {  
  698.   for(var i=0;i<checkList.length;i++)  
  699.   {  
  700.    checkList[i].checked=checked;  
  701.   }  
  702.  }  
  703. }</P><P>/** 
  704.  * 构建表格以及滚动条 
  705.  * @param id 表格id 
  706.  * @param parentId 父节点,将建构建好的表格节点添加到父节点中 
  707.  * @param width 表格宽度 
  708.  * @param height 表格高度 
  709.  * @param ondblclick 表格双击事件 
  710.  * @param html (构建好的表格=序列号表格+表头表格+数据表格+汇总表格) 
  711.  * @return 
  712.  */  
  713. function _execute(id,parentId,width,height,html,isMultiple)  
  714. {  
  715.  /** 
  716.   * 定义构建表格需要的变量 
  717.   */  
  718.  var _first_object=null;//第一列,序数表格   
  719.  var _header_object=null;//表头   
  720.  var _data_object=null;//数据表格   
  721.  var _sum_object=null;//汇总表格   
  722.  var _hbar_object=null;//横向滚动条   
  723.  var _vbar_object=null;//纵向滚动条   
  724.  var _current_row=null;//当前选中行   
  725.  var mainFrame=document.createElement("DIV");  
  726.  mainFrame.id="DIV_"+id;  
  727.  mainFrame.style.width=width;  
  728.  mainFrame.style.height=height;  
  729.  mainFrame.className="datagrid";  
  730.  mainFrame.onmousedown=function (e){//鼠标按下事件   
  731.   e=e||window.event;  
  732.   _selectedRow(e,id,isMultiple);//选中行   
  733.  }  
  734.  mainFrame.innerHTML=html;  
  735.  /* 
  736.   * 添加滚动事件,根据IE的冒泡特性子节点事件触发自后如果父节点也有相同的事件 
  737.   * 就会接着执行父节点的事件 
  738.   */  
  739.  _addScrollEvent(mainFrame,id);  
  740.  //构建横向滚动条   
  741.  var hbar=document.createElement("DIV");  
  742.  hbar.id="hbar";  
  743.  hbar.style.position="absolute";  
  744.  hbar.style.width="100%";  
  745.  hbar.style.height="17px";  
  746.  hbar.style.overflowX="auto";  
  747.  hbar.style.top=height-17;  
  748.  hbar.style.zIndex="10";  
  749.  hbar.onscroll=function(){  
  750.   _h_scroll(id);//横向滚动   
  751.  }  
  752.  hbar.innerHTML="<div style=\"width:100%;height:1px;overflow-y:hidden;\">&nbsp;</div>";  
  753.  //构建纵向滚动条   
  754.  var vbar=document.createElement("DIV");  
  755.  vbar.id="vbar";  
  756.  vbar.style.position="absolute";  
  757.  vbar.style.width="17px";  
  758.  vbar.style.height="100%";  
  759.  vbar.style.overflowY="auto";  
  760.  vbar.style.left=width-17;  
  761.  vbar.style.zIndex="10";  
  762.  vbar.onscroll=function(){  
  763.   _v_scroll(id);//纵向滚动   
  764.  }  
  765.  vbar.innerHTML="<div style=\"width:1px;height:100%;overflow-x:hidden;\">&nbsp;</div>";  
  766.  //将表格和滚动条组合在一起   
  767.  mainFrame.appendChild(hbar);  
  768.  mainFrame.appendChild(vbar);  
  769.  //将构建好的表格节点追加到父节点中   
  770.  document.getElementById(parentId).appendChild(mainFrame);  
  771.  _first_object=document.getElementById("first_"+id);//第一列,序数表格   
  772.  _header_object=document.getElementById("header_"+id);//表头   
  773.  _data_object=document.getElementById(id);//数据表格   
  774.  _sum_object=document.getElementById("sum_"+id);//汇总表格   
  775.  _hbar_object=hbar;//横向滚动条   
  776.  _vbar_object=vbar;//纵向滚动条   
  777.  /* 
  778.   * 注册全局变量 
  779.   */  
  780.  put(id,‘_first_object‘,_first_object);  
  781.  put(id,‘_header_object‘,_header_object);  
  782.  put(id,‘_data_object‘,_data_object);  
  783.  put(id,‘_sum_object‘,_sum_object);  
  784.  put(id,‘_hbar_object‘,_hbar_object);  
  785.  put(id,‘_vbar_object‘,_vbar_object);  
  786.  var bt=_getCurrentStyle(mainFrame,"borderTopWidth");  
  787.  var bb=_getCurrentStyle(mainFrame,"borderBottomWidth");  
  788.  var bl=_getCurrentStyle(mainFrame,"borderLeftWidth");  
  789.  var br=_getCurrentStyle(mainFrame,"borderRightWidth");  
  790.  _hbar_object.style.top=parseInt(_hbar_object.style.top)-parseInt(bt)-parseInt(bb);  
  791.  _vbar_object.style.left=parseInt(_vbar_object.style.left)-parseInt(bl)-parseInt(br);  
  792.  _block_scroll(id);//设置滚动块   
  793. }  
  794. /** 
  795.  * 当鼠标按下时选中行 
  796.  * @param e 
  797.  * @return 
  798.  */  
  799. function _selectedRow(e,id,isMultiple)  
  800. {  
  801.  if(isMultiple)  
  802.   return;  
  803.  var td_object=e.srcElement?e.srcElement:e.target;  
  804.  var _data_object=get(id,‘_data_object‘);  
  805.  var table=document.getElementById(id);  
  806.  if(td_object.parentNode.tagName=="TR")  
  807.  {  
  808.   var tr_object=td_object.parentNode;  
  809.   var rowIndex=tr_object.rowIndex;//行索引   
  810.   var _current_row=get(id,‘_current_row‘);  
  811.   var flag=get(id,‘flag‘);  
  812.   var _isHbar=get(id,‘_isHbar‘);  
  813.   if(flag)  
  814.   {  
  815.    if(rowIndex==0||rowIndex==1)  
  816.    {  
  817.     return;  
  818.    }  
  819.   }  
  820.   else  
  821.   {  
  822.    if(rowIndex==0)  
  823.    {  
  824.     return;  
  825.    }  
  826.   }  
  827.   if(_isHbar)  
  828.   {  
  829.    if(rowIndex==table.rows.length-1||rowIndex==table.rows.length-2)  
  830.    {  
  831.     return;  
  832.    }  
  833.   }  
  834.   else  
  835.   {  
  836.    if(rowIndex==table.rows.length-1)  
  837.    {  
  838.     return;  
  839.    }  
  840.   }  
  841.   if(_current_row!=null)  
  842.   {//取消之前的选中行状态   
  843.    _data_object.rows[_current_row].className="";  
  844.   }  
  845.   //重新设置选中行状态   
  846.   _data_object.rows[rowIndex].className="selectedrow";  
  847.   _current_row=rowIndex;  
  848.   put(id,‘_current_row‘,_current_row);  
  849.  }  
  850. }  
  851. /** 
  852.  * 添加滚动事件监听器 
  853.  * @param element要添加事件的父节点 
  854.  * @return 
  855.  */  
  856. function _addScrollEvent(element,id)  
  857. {  
  858.  var handler=function(e)  
  859.  {  
  860.   _mouseScrollEvent.call(this, e,id);  
  861.  }  
  862.  if(document.attachEvent)  
  863.  {//微软自定义的添加事件监听器   
  864.   element.attachEvent("onmousewheel",handler);  
  865.  }  
  866.  else  
  867.  {//W3C规范定义的添加事件监听器   
  868.   element.addEventListener("DOMMouseScroll",handler,false);  
  869.  }  
  870. }  
  871. /** 
  872.  * 鼠标轮滚动事件和列表事件 
  873.  * @param e 
  874.  * @return 
  875.  */  
  876. function _mouseScrollEvent(e,id)  
  877. {  
  878.  e=e||window.event;  
  879.  var _vbar_object=get(id,‘_vbar_object‘);  
  880.  if(e.wheelDelta<=0 || e.detail>0)  
  881.  {  
  882.   _vbar_object.scrollTop+=18;//设置滚动步长为一行的高度   
  883.  }  
  884.  else  
  885.  {  
  886.   _vbar_object.scrollTop-=18;  
  887.  }  
  888. }  
  889. /** 
  890.  * 横向滚动 
  891.  * @return 
  892.  */  
  893. function _h_scroll(id)  
  894. {  
  895.  var _hbar_object=get(id,‘_hbar_object‘);  
  896.  var _header_object=get(id,‘_header_object‘);  
  897.  var _data_object=get(id,‘_data_object‘);  
  898.  var _sum_object=get(id,‘_sum_object‘);  
  899.  _header_object.style.left=-(_hbar_object.scrollLeft);  
  900.  _data_object.style.left=-(_hbar_object.scrollLeft);  
  901.  _sum_object.style.left=-(_hbar_object.scrollLeft);  
  902. }  
  903. /** 
  904.  *纵向滚动 
  905.  * @return 
  906.  */  
  907. function _v_scroll(id)  
  908. {  
  909.  var _vbar_object=get(id,‘_vbar_object‘);  
  910.  var _first_object=get(id,‘_first_object‘);  
  911.  var _data_object=get(id,‘_data_object‘);  
  912.  _first_object.style.top=-(_vbar_object.scrollTop);  
  913.  _data_object.style.top=-(_vbar_object.scrollTop);  
  914. }  
  915. /** 
  916.  * 取出当前元素非style定义的样式 
  917.  * @param element 
  918.  * @param property 
  919.  * @return 
  920.  */  
  921. function _getCurrentStyle(element,property)  
  922. {  
  923.  if(element.currentStyle)  
  924.  {//元素中非style定义的样式,包括内嵌样式和外部样式表中定义的样式   
  925.   return element.currentStyle[property];  
  926.  }  
  927.  else if(window.getComputedStyle)  
  928.  {//firefox的方式   
  929.   property=property.replace(/([A-Z])/g, "-$1").toLowerCase();  
  930.   return window.getComputedStyle(element,null).getPropertyValue(property);  
  931.  }  
  932.  else  
  933.  {  
  934.   return null;  
  935.  }  
  936. }  
  937. /** 
  938.  * 设置滚动块 
  939.  * @return 
  940.  */  
  941. function _block_scroll(id)  
  942. {  
  943.  var _hbar_object=get(id,‘_hbar_object‘);  
  944.  var _vbar_object=get(id,‘_vbar_object‘);  
  945.  var _data_object=get(id,‘_data_object‘);  
  946.  _hbar_object.style.display="block";  
  947.  _vbar_object.style.display="block";  
  948.  _hbar_object.childNodes[0].style.width=_data_object.offsetWidth;  
  949.  _vbar_object.childNodes[0].style.height=_data_object.offsetHeight;  
  950.  if(_hbar_object.childNodes[0].offsetWidth<=_hbar_object.offsetWidth)  
  951.  {  
  952.   _hbar_object.style.display="none";  
  953.  }  
  954.  if(_vbar_object.childNodes[0].offsetHeight<=_vbar_object.offsetHeight)  
  955.  {  
  956.   _vbar_object.style.display="none";  
  957.  }  
  958. }</P>  

//=========================================================================== /**  *表格操作  *@author 陈双  *@date 2012-09-26  *@mail chenshuang_com@sina.com  */ //=========================================================================== var globeVariable=new Map();//全局变量列表 /**  * 注册全局变量  * @param object 对象id  * @param property 变量名称  * @param value 值  * @return  */ function put(object,property,value) {  globeVariable.put(object+"_"+property,value); } /**  * 取出全局变量  * @param object 对象id  * @param property 变量名称  * @return  */ function get(object,property) {  return globeVariable.get(object+"_"+property); } /**  * 获取选中行单元格的值  * @param id 表格id  * @param cellIndex 单元格索引  * @param isMultiple 是否有勾选框  * @return Array 选中行的id值的集合  */ function getSelectedCellValue(id,cellIndex,isMultiple){  if(!id)return null;  var values=new Array();//所有选中的id值  if(isMultiple)  {   var checkList=document.getElementsByName(id+"chbox");   var rows=new Array();//选中的行集合   var index=-1;   if(checkList && checkList.length>0)   {    for(var i=0;i<checkList.length;i++)    {     if(checkList[i].checked)     {      index++;      rows[index]=checkList[i].parentNode.parentNode;     }    }   }   if(rows.length==0)   {    alert("请选中一行!");    return null;   }   else   {    for(var i=0;i<rows.length;i++)    {     values[i]=rows[i].cells[parseInt(cellIndex)+2].innerText;    }    return values;   }  }  else  {   var _current_row=get(id,‘_current_row‘);   if(_current_row==null)   {    alert("请选择一行!");    return null;   }   else   {    values[0]=document.getElementById(id).rows[_current_row].cells[parseInt(cellIndex)+1].innerText;    return values;   }  }  return null; } /**  * 创建可编辑的表格对象,并添加到指定的父节点中  * @param id 表格名称  * @param parentId 父节点id  * @param width 表格宽度  * @param height 表格高度  * @param isMultiple 多行是否有勾选框  * @param columns 表格所有的列,以数组的形式保存GridColumn对象  * @param rows 数据列表,它是以集合List的形式保存Map,其中key是name,value是值  * @param status 表格状态值: read只读,update可修改,insert新增  */ function CreateTable(id,parentId,width,height,isMultiple,columns,rows) {  if((!id)|(!parentId)||(!width)||(!height)||(!columns)||(!rows))  {   return;  }  var _sum_columns=null;//汇总列  var _isHbar=false;//是否有横向滚动条  var flag=false;//默认没有跨列操作  var first="";//声明第一列表  var title="";//标题表  var data="";//数据表  var sum="";//汇总表  var columnWidth=125;//默认列宽  for(var i=0;i<columns.length;i++)  {//检查是否有跨列操作   if(columns[i].colspan)   {    flag=true;    break;   }  }  put(id, ‘flag‘, flag);  //构建标题列  if(flag)  {//有跨列操作   for(var i=0;i<2;i++)   {    if(i==0)    {     title="<tr><td class=‘firstcolumn‘ rowspan=‘2‘>&nbsp;</td>";     if(isMultiple)     {      title+="<td class=‘column‘ width=‘30‘ rowspan=‘2‘ align=‘center‘><input name=‘checkbox‘ type=‘checkbox‘ onclick=\"checkAllForGrid(this.checked,‘"+id+"chbox‘);\"/></td>";     }    }    else    {     title+="<tr>";    }    for(var j=0;j<columns.length;j++)    {     if(columns[j].colspan)     {//执行跨列      if(i==0)      {//第一行       title+="<td class=‘column‘ align=‘center‘ colspan=‘"+columns[j].colspan+"‘";       if(columns[j].width)       {        title+=" width=‘"+(columns[j].width*parseInt(columns[j].colspan))+"‘";       }       else       {        title+=" width=‘"+(columnWidth*parseInt(columns[j].colspan))+"‘";       }       title+=">"+(columns[j].label.split(",")[0])+"</td>";      }      else      {//第二行       title+="<td class=‘column‘ align=‘center‘";       if(columns[j].hidden)       {        columns[j].width=1;        title+=" style=\"border:none;\"";       }       if(columns[j].width)       {        title+=" width=‘"+columns[j].width+"‘";       }       else       {        title+=" width=‘"+columnWidth+"‘";       }       title+=">"+(columns[j].label.split(",")[1])+"</td>";      }     }     else     {//执行跨行      var rs=columns[j].label.indexOf(‘,‘);//是否是跨列      if(i==0)      {//跨行操作       if(rs==-1)       {//跨行        title+="<td class=‘column‘ align=‘center‘ rowspan=‘2‘";        if(columns[j].hidden)        {         columns[j].width=1;         title+=" style=\"border:none;\"";        }        if(columns[j].width)        {         title+=" width=‘"+columns[j].width+"‘";        }        else        {         title+=" width=‘"+columnWidth+"‘";        }        title+=">"+columns[j].label+"</td>";       }      }      else      {//跨列操作       if(rs!=-1)       {//跨行        title+="<td class=‘column‘ align=‘center‘";        if(columns[j].hidden)        {         columns[j].width=1;         title+=" style=\"border:none;\"";        }        if(columns[j].width)        {         title+=" width=‘"+columns[j].width+"‘";        }        else        {         title+=" width=‘"+columnWidth+"‘";        }        title+=">"+(columns[j].label.split(‘,‘)[1])+"</td>";       }      }     }    }    if(i==0)    {//最后一列     title+="<td class=‘lastcolumn‘ rowspan=‘2‘>&nbsp;</td></tr>";    }    else    {     title+="</tr>";    }   }  }  else  {//正常情况   title="<tr><td class=‘firstcolumn‘>&nbsp;</td>";   if(isMultiple)   {    title+="<td class=‘column‘ width=‘30‘ align=‘center‘><input name=‘checkbox‘ type=‘checkbox‘ onclick=\"checkAllForGrid(this.checked,‘"+id+"chbox‘);\"/></td>";   }   for(var i=0;i<columns.length;i++)   {    title+="<td class=‘column‘ align=‘center‘";    if(columns[i].hidden)    {     columns[i].width=1;     title+=" style=\"border:none;\"";    }    if(columns[i].width)    {     title+=" width=‘"+columns[i].width+"‘";    }    else    {     title+=" width=‘"+columnWidth+"‘";    }     title+=" onclick=\"sortTableForGrid(‘"+id+"‘,"+i+","+isMultiple+");\"";    title+=">"+columns[i].label+"<span></span></td>";   }   title+="<td class=‘lastcolumn‘>&nbsp;</td></tr>";  }  if(columns&&columns.length>0)  {//汇总表格   sum="<tr><td class=‘firstcolumn‘>汇总</td>";   if(isMultiple)   {    sum+="<td class=‘column‘ width=‘30‘>&nbsp;</td>";   }   for(var i=0;i<columns.length;i++)   {    sum+="<td class=‘column‘ align=‘center‘";    if(columns[i].hidden)    {     columns[i].width=1;     sum+=" style=\"border:none;\"";    }    if(columns[i].width)    {     sum+=" width=‘"+columns[i].width+"‘";    }    else    {     sum+=" width=‘"+columnWidth+"‘";    }     sum+=">&nbsp;</td>";   }   sum+="<td class=‘lastcolumn‘>&nbsp;</td></tr>";  }  if(rows&&rows.size()>0)  {//构建第一列和数据表格   if(flag)   {    first="<tr><td>&nbsp;</td></tr>";    first+="<tr><td>&nbsp;</td></tr>";   }   else   {    first="<tr><td>&nbsp;</td></tr>";   }      for(var i=0;i<rows.size();i++)   {    first+="<tr><td style=‘border-right:none;‘>"+(i+1)+"</td></tr>";    data+="<tr><td class=‘firstcolumn‘ style=‘border-bottom-color:#cccccc;‘>"+(i+1)+"</td>";    if(isMultiple)    {     data+="<td width=‘30‘ align=‘center‘><input type=‘checkbox‘ name=‘"+id+"chbox‘/></td>";    }    var rowId="rowid_"+(i+1);    var map=rows.get(i);    for(var j=0;j<columns.length;j++)    {     data+="<td";     if(columns[j].hidden)     {      columns[j].width=1;      data+=" style=\"border-right:none;\"";     }     if(columns[j].width)     {      data+=" width=‘"+columns[j].width+"‘";     }     else     {      data+=" width=‘"+columnWidth+"‘";     }     data+=">";     data+=map.get(columns[j].name)==null?"&nbsp;":map.get(columns[j].name);     data+="</td>";    }    data+="<td class=‘lastdata‘>";    data+="<input name=‘rowid‘ type=‘hidden‘ value=http://www.mamicode.com/‘"+(rowId)+"‘/>";    data+="&nbsp;</td></tr>";   }  }  //构建汇总列     _sum_columns=new Array();//初始化  var k=0;  for(var i=0;i<columns.length;i++)  {   if(columns[i].sum&&(columns[i].type=="int"||columns[i].type=="number"))   {    if(isMultiple)    {     _sum_columns[k]=i+2;    }    else    {     _sum_columns[k]=i+1;    }    k++;   }  }  put(id,‘_sum_columns‘,_sum_columns);  var allWidth=0;  for(var i=0;i<columns.length;i++)  {   if(columns[i].width)   {    allWidth+=parseInt(columns[i].width);   }   else   {    allWidth+=parseInt(columnWidth);   }  }  allWidth+=30;  if(isMultiple)  {   allWidth+=30;  }  var total=1;  if(allWidth>width)  {   total=2;   _isHbar=true;  }  put(id, ‘_isHbar‘, _isHbar);  //构建隐藏行  for(var i=0;i<total;i++)  {   data+="<tr><td style=\"border:0;\">&nbsp;</td>";   for(var j=0;j<columns.length;j++)   {    data+="<td style=\"border:0;\">&nbsp;</td>";   }   data+="<td style=\"border:0;\">&nbsp;</td>";   first+="<tr><td style=\"border:0;background-color:white;\">&nbsp;</td></tr>";  }  var title_html="<table id=‘header_"+id+"‘ cellspacing=‘0‘ cellpadding=‘0‘ class=‘titlecolumn‘>"+title+"</table>";  var first_html="<table id=‘first_"+id+"‘ cellspacing=‘0‘ cellpadding=‘0‘ class=‘slidecolumn‘>"+first+"</table>";  var data_html="<table id=‘"+id+"‘ cellspacing=‘0‘ cellpadding=‘0‘ class=‘datacolumn‘>";  data_html+=title+data+"</table>";  var sum_html="<table id=‘sum_"+id+"‘ cellspacing=‘0‘"+" cellpadding=‘0‘ style=‘width:100%;position:absolute;top:";  if(_isHbar)  {   sum_html+=+(parseInt(height)-18-17);  }  else  {   sum_html+=(parseInt(height)-17);  }  sum_html+=";left:0;z-index:4;‘/>"+sum+"</table>";  _execute(id, parentId, width, height, first_html+title_html+data_html+sum_html,isMultiple);  sumRowForGrid(id); } /**  * 列结构  * @param name名称  * @param label 标签  * @param type 类型  * @param width 宽度  * @param height 高度  * @param data 列数据来源是一个数组  * @param hidden 是否隐藏  * @param disabled 是否可用  * @param sum 是否汇总  * @param size 字符个数  * @param colspan 跨列  * @param rowspan 跨行  * @param ondblclick 鼠标双击事件  * @param drillEvent 数据钻取处理函数  */ function GridColumn(name,label,type,width,height,data,hidden,disabled,sum,size,colspan,ondblclick,drillEvent) {  this.name=name;  this.label=label;  this.type=type;  this.width=width;  this.height=height;  this.data=http://www.mamicode.com/data;"header_"+id);     var sort;     if(flag)     {      return;     }     if(isMultiple)     {      index+=2;     }     else     {      index+=1;     }     var html=header.rows[0].cells[index].childNodes[1].innerHTML;     if(html=="")     {        sort="asc";        header.rows[0].cells[index].childNodes[1].innerHTML="▲";     }     else if(html=="▲")     {        sort="dsc";        header.rows[0].cells[index].childNodes[1].innerHTML="▼";     }     else if(html=="▼")     {        sort="asc";        header.rows[0].cells[index].childNodes[1].innerHTML="▲";     }     var k=1;     if(isMultiple)     {      k=2;     }     for(var i=k;i<header.rows[0].cells.length-1;i++)     {        if(i!=index)        {            header.rows[0].cells[i].childNodes[1].innerHTML="";        }     }     if(_isHbar)     {      for(var i=1;i<table.rows.length-3;i++)         {            tr[i-1]=table.rows[i];            td[i-1]=table.rows[i].cells[index];         }     }     else     {      for(var i=1;i<table.rows.length-2;i++)         {            tr[i-1]=table.rows[i];            td[i-1]=table.rows[i].cells[index];         }     }         var isNumber=false;//是数字     for(var i=0;i<td.length;i++)     {        if(!checkValueForGrid(td[i].innerHTML))        {        isNumber=true;//字符串           break;        }     }     //开始比较数据     for(var i=0;i<td.length;i++)     {          for(var j=0;j<td.length;j++)          {             if(isNumber)             {//字符串比较                 if(sort=="asc")                 {                      if(td[i].innerHTML<td[j].innerHTML)                      {                          temp=td[i];                          td[i]=td[j];                          td[j]=temp;                      }                 }                 else if(sort=="dsc")                 {                     if(td[i].innerHTML>td[j].innerHTML)                      {                          temp=td[i];                          td[i]=td[j];                          td[j]=temp;                      }                 }             }             else             {//数字比较                if(sort=="asc")                 {                      if(parseFloat(td[i].innerHTML)<parseFloat(td[j].innerHTML))                      {                          temp=td[i];                          td[i]=td[j];                          td[j]=temp;                      }                 }                 else if(sort=="dsc")                 {                     if(parseFloat(td[i].innerHTML)>parseFloat(td[j].innerHTML))                      {                          temp=td[i];                          td[i]=td[j];                          td[j]=temp;                      }                 }             }          }     }     var cellCount=table.rows[0].cells.length;     var tempTR=new Array();//临时行     for(var i=0;i<tr.length;i++)     {         var tempTD=new Array();//临时列集合         for(var j=k;j<cellCount-1;j++)         {            tempTD[j]=td[i].parentNode.cells[j].innerHTML;         }         tempTR[i]=tempTD;     }     for(var i=0;i<tr.length;i++)     {        for(var j=k;j<cellCount-1;j++)        {            tr[i].cells[j].innerHTML=tempTR[i][j];        }     } } /**  *汇总行  *@param id 表格id  *@param columns 汇总列数组  */ function sumRowForGrid(id) {    var columns=get(id,‘_sum_columns‘);    var _isHbar=get(id,‘_isHbar‘);    var flag=get(id,‘flag‘);    if(columns==undefined||columns.length==0)    {         return;    }    var sumTR=new Array();//汇总行临时数据    var table=document.getElementById(id);    var sum_table=document.getElementById("sum_"+id);    if((_isHbar&&flag==false&&table.rows.length==3)||(_isHbar&&flag&&table.rows.length==4)||(!_isHbar&&flag&&table.rows.length==3)||(!_isHbar&&!flag&&table.rows.length==2))    {     for(var i=0;i<columns.length;i++)     {      sum_table.rows[0].cells[columns[i]].innerHTML=‘&nbsp;‘;     }     return;    }    var index=1;    if(flag)    {     index=2;    }    var end=table.rows.length-1;    if(_isHbar)    {      end=table.rows.length-2;    }    for(var i=index;i<end;i++)    {        for(var j=0;j<columns.length;j++)        {           var value=http://www.mamicode.com/table.rows[i].cells[columns[j]].innerText;"0";           }           if(sumTR[j]==undefined)           {               sumTR[j]=value;           }           else if(sumTR[j]!="")           {               sumTR[j]=parseFloat(sumTR[j])+parseFloat(value);           }        }    }    //填充汇总行    for(var i=0;i<columns.length;i++)    {     sum_table.rows[0].cells[columns[i]].innerHTML=sumTR[i];    } } /**  *检查value是否为数字,返回true是数字,返回false为字符串  *@param value要检查的值  */ function checkValueForGrid(value) {   if(value && value.length>0)   {     var newValue=http://www.mamicode.com/value.replace(/s+/g,"");     value=http://www.mamicode.com/newValue;>

/**  * 构建表格以及滚动条  * @param id 表格id  * @param parentId 父节点,将建构建好的表格节点添加到父节点中  * @param width 表格宽度  * @param height 表格高度  * @param ondblclick 表格双击事件  * @param html (构建好的表格=序列号表格+表头表格+数据表格+汇总表格)  * @return  */ function _execute(id,parentId,width,height,html,isMultiple) {  /**   * 定义构建表格需要的变量   */  var _first_object=null;//第一列,序数表格  var _header_object=null;//表头  var _data_object=null;//数据表格  var _sum_object=null;//汇总表格  var _hbar_object=null;//横向滚动条  var _vbar_object=null;//纵向滚动条  var _current_row=null;//当前选中行  var mainFrame=document.createElement("DIV");  mainFrame.id="DIV_"+id;  mainFrame.style.width=width;  mainFrame.style.height=height;  mainFrame.className="datagrid";  mainFrame.onmousedown=function (e){//鼠标按下事件   e=e||window.event;   _selectedRow(e,id,isMultiple);//选中行  }  mainFrame.innerHTML=html;  /*   * 添加滚动事件,根据IE的冒泡特性子节点事件触发自后如果父节点也有相同的事件   * 就会接着执行父节点的事件   */  _addScrollEvent(mainFrame,id);  //构建横向滚动条  var hbar=document.createElement("DIV");  hbar.id="hbar";  hbar.style.position="absolute";  hbar.style.width="100%";  hbar.style.height="17px";  hbar.style.overflowX="auto";  hbar.style.top=height-17;  hbar.style.zIndex="10";  hbar.onscroll=function(){   _h_scroll(id);//横向滚动  }  hbar.innerHTML="<div style=\"width:100%;height:1px;overflow-y:hidden;\">&nbsp;</div>";  //构建纵向滚动条  var vbar=document.createElement("DIV");  vbar.id="vbar";  vbar.style.position="absolute";  vbar.style.width="17px";  vbar.style.height="100%";  vbar.style.overflowY="auto";  vbar.style.left=width-17;  vbar.style.zIndex="10";  vbar.onscroll=function(){   _v_scroll(id);//纵向滚动  }  vbar.innerHTML="<div style=\"width:1px;height:100%;overflow-x:hidden;\">&nbsp;</div>";  //将表格和滚动条组合在一起  mainFrame.appendChild(hbar);  mainFrame.appendChild(vbar);  //将构建好的表格节点追加到父节点中  document.getElementById(parentId).appendChild(mainFrame);  _first_object=document.getElementById("first_"+id);//第一列,序数表格  _header_object=document.getElementById("header_"+id);//表头  _data_object=document.getElementById(id);//数据表格  _sum_object=document.getElementById("sum_"+id);//汇总表格  _hbar_object=hbar;//横向滚动条  _vbar_object=vbar;//纵向滚动条  /*   * 注册全局变量   */  put(id,‘_first_object‘,_first_object);  put(id,‘_header_object‘,_header_object);  put(id,‘_data_object‘,_data_object);  put(id,‘_sum_object‘,_sum_object);  put(id,‘_hbar_object‘,_hbar_object);  put(id,‘_vbar_object‘,_vbar_object);  var bt=_getCurrentStyle(mainFrame,"borderTopWidth");  var bb=_getCurrentStyle(mainFrame,"borderBottomWidth");  var bl=_getCurrentStyle(mainFrame,"borderLeftWidth");  var br=_getCurrentStyle(mainFrame,"borderRightWidth");  _hbar_object.style.top=parseInt(_hbar_object.style.top)-parseInt(bt)-parseInt(bb);  _vbar_object.style.left=parseInt(_vbar_object.style.left)-parseInt(bl)-parseInt(br);  _block_scroll(id);//设置滚动块 } /**  * 当鼠标按下时选中行  * @param e  * @return  */ function _selectedRow(e,id,isMultiple) {  if(isMultiple)   return;  var td_object=e.srcElement?e.srcElement:e.target;  var _data_object=get(id,‘_data_object‘);  var table=document.getElementById(id);  if(td_object.parentNode.tagName=="TR")  {   var tr_object=td_object.parentNode;   var rowIndex=tr_object.rowIndex;//行索引   var _current_row=get(id,‘_current_row‘);   var flag=get(id,‘flag‘);   var _isHbar=get(id,‘_isHbar‘);   if(flag)   {    if(rowIndex==0||rowIndex==1)    {     return;    }   }   else   {    if(rowIndex==0)    {     return;    }   }   if(_isHbar)   {    if(rowIndex==table.rows.length-1||rowIndex==table.rows.length-2)    {     return;    }   }   else   {    if(rowIndex==table.rows.length-1)    {     return;    }   }   if(_current_row!=null)   {//取消之前的选中行状态    _data_object.rows[_current_row].className="";   }   //重新设置选中行状态   _data_object.rows[rowIndex].className="selectedrow";   _current_row=rowIndex;   put(id,‘_current_row‘,_current_row);  } } /**  * 添加滚动事件监听器  * @param element要添加事件的父节点  * @return  */ function _addScrollEvent(element,id) {  var handler=function(e)  {   _mouseScrollEvent.call(this, e,id);  }  if(document.attachEvent)  {//微软自定义的添加事件监听器   element.attachEvent("onmousewheel",handler);  }  else  {//W3C规范定义的添加事件监听器   element.addEventListener("DOMMouseScroll",handler,false);  } } /**  * 鼠标轮滚动事件和列表事件  * @param e  * @return  */ function _mouseScrollEvent(e,id) {  e=e||window.event;  var _vbar_object=get(id,‘_vbar_object‘);  if(e.wheelDelta<=0 || e.detail>0)  {   _vbar_object.scrollTop+=18;//设置滚动步长为一行的高度  }  else  {   _vbar_object.scrollTop-=18;  } } /**  * 横向滚动  * @return  */ function _h_scroll(id) {  var _hbar_object=get(id,‘_hbar_object‘);  var _header_object=get(id,‘_header_object‘);  var _data_object=get(id,‘_data_object‘);  var _sum_object=get(id,‘_sum_object‘);  _header_object.style.left=-(_hbar_object.scrollLeft);  _data_object.style.left=-(_hbar_object.scrollLeft);  _sum_object.style.left=-(_hbar_object.scrollLeft); } /**  *纵向滚动  * @return  */ function _v_scroll(id) {  var _vbar_object=get(id,‘_vbar_object‘);  var _first_object=get(id,‘_first_object‘);  var _data_object=get(id,‘_data_object‘);  _first_object.style.top=-(_vbar_object.scrollTop);  _data_object.style.top=-(_vbar_object.scrollTop); } /**  * 取出当前元素非style定义的样式  * @param element  * @param property  * @return  */ function _getCurrentStyle(element,property) {  if(element.currentStyle)  {//元素中非style定义的样式,包括内嵌样式和外部样式表中定义的样式   return element.currentStyle[property];  }  else if(window.getComputedStyle)  {//firefox的方式   property=property.replace(/([A-Z])/g, "-$1").toLowerCase();   return window.getComputedStyle(element,null).getPropertyValue(property);  }  else  {   return null;  } } /**  * 设置滚动块  * @return  */ function _block_scroll(id) {  var _hbar_object=get(id,‘_hbar_object‘);  var _vbar_object=get(id,‘_vbar_object‘);  var _data_object=get(id,‘_data_object‘);  _hbar_object.style.display="block";  _vbar_object.style.display="block";  _hbar_object.childNodes[0].style.width=_data_object.offsetWidth;  _vbar_object.childNodes[0].style.height=_data_object.offsetHeight;  if(_hbar_object.childNodes[0].offsetWidth<=_hbar_object.offsetWidth)  {   _hbar_object.style.display="none";  }  if(_vbar_object.childNodes[0].offsetHeight<=_vbar_object.offsetHeight)  {   _vbar_object.style.display="none";  } }

/////////////////////////////////////////////////////////////////////////////////////
/**
 * js通用对象,主要包括List和Map集合对象的定义
 * @author 陈双
 * @date 2012-10-01
 * @mail chenshuang_com@sina.com
 */
////////////////////////////////////////////////////////////////////////////////////
/**
 * List对象
 * @return
 */
function List()
{
 this.container=new Array(1000);//容器
 this.index=-1;//索引
 this.add=function(element){//添加元素
  this.index++;
  this.container[this.index]=element;
 }
 this.get=function(i){//获取元素
  if(this.index==-1||i<0)
  {
   return null;
  }
  return this.container[i];
 }
 this.size=function(){//List 对象的大小
  return this.index+1;
 }
 this.clear=function(){//清空List对象
  if(this.index!=-1)
  {
   for(var i=0;i<=this.index;i++)
   {
    this.container[i]=null;
   }
  }
  this.index=-1;
 }
 this.contain=function(element){//是否包含某元素
  if(this.index==-1||(!element))
  {
   return false;
  }
  for(var i=0;i<=this.index;i++)
  {
   if(this.container[i]==element)
   {
    return true;
   }
  }
 }
 this.isEmpty=function(){//是否为空
  return this.index==-1?true:false;
 }
 this.remove=function(element){//删除一个元素
  if((!element)||(!this.index))
  {
   return;
  }
  var po=-1;
  var flag=false;//是否移除了
  for(var i=0;i<=this.index;i++)
  {
   if(this.container[i]==element)
   {
    po=i;
    if(po==this.index)
    {
     po=-1;
    }
    flag=true;
   }
   if(po!=-1)
   {
    this.container[po]=this.container[po+1];
    po++;
   }
  }
  if(flag)
  {
   this.index=this.index-1;
  }
 }
 this.removeIn=function(i){//删除指定位置的元素
  if(i<0||this.index<0)
  {
   return;
  }
  var po=-1;
  var flag=false;//是否移除了
  for(var j=0;j<=this.index;j++)
  {
   if(j==i)
   {
    po=j;
    if(po==this.index)
    {
     po=-1;
    }
    flag=true;
   }
   if(po!=-1)
   {
    this.container[po]=this.container[po+1];
    po++;
   }
  }
  if(flag)
  {
   this.index=this.index-1;
  }
 }
}
/**
 * Map对象
 * @return
 */
function Map()
{
 this.index=-1;
 this.entrys=new Array(1000);
 this.get=function(key){//通过key映射value
  if(this.index==-1)
  {
   return null;
  }
  for(var i=0;i<=this.index;i++)
  {
   var entry=this.entrys[i];
   if(entry.key==key)
   {
    return entry.value;
   }
  }
  return null;
 }
 this.size=function(){//返回元素个数
  return this.index+1;
 }
 this.containsKey=function(key){//是否包含key值
  if(this.index==-1)
  {
   return false;
  }
  for(var i=0;i<=this.index;i++)
  {
   var entry=this.entrys[i];
   if(entry.key==key)
   {
    return true;
   }
  }
  return false;
 }
 this.containsValue=http://www.mamicode.com/function(value){//是否包含值
  if(this.index==-1)
  {
   return false;
  }
  for(var i=0;i<=this.index;i++)
  {
   var entry=this.entrys[i];
   if(entry.value=http://www.mamicode.com/=value)
   {
    return true;
   }
  }
  return false;
 }
 this.put=function(key,value){//添加元素
  if(this.containsKey(key))
  {
   this.remove(key);
  }
  this.index++;
  this.entrys[this.index]=new Entry(key,value);
 }
 this.keySet=function(){//返回key集合
  if(this.index==-1)
  {
   return null;
  }
  var keys=new List();
  for(var i=0;i<=this.index;i++)
  {
   keys.add(this.entrys[i].key);
  }
  return keys;
 }
 this.values=function(){//返回值集合
  if(this.index==-1)
  {
   return null;
  }
  var value=http://www.mamicode.com/new List();
  for(var i=0;i<=this.index;i++)
  {
   value.add(this.entrys[i].value);
  }
  return value;
 }
 this.clear=function(){//清空
  if(this.index!=-1)
  {
   for(var i=0;i<=this.index;i++)
   {
    this.entrys[i]=null;
   }
   this.index=-1;
  }
 }
 this.remove=function(key){//移除某个元素
  if(this.index==-1)
  {
   return;
  }
  var po=-1;
  var flag=false;
  for(var i=0;i<=this.index;i++)
  {
   var entry=this.entrys[i];
   if(entry.key==key)
   {
    po=i;
    if(i==this.index)
    {
     po=-1;
    }
    flag=true;
   }
   if(po!=-1)
   {
    this.entrys[po]=this.entrys[po+1];
    po++;
   }
  }
  if(flag)
  {
   this.index=this.index-1;
  }
 }
 this.isEmpty=function(){//是否为空
  if(this.index==-1)
  {
   return true;
  }
  return false;
 }
 this.entrySet=function(){//返回Entry
  if(this.index==-1)
  {
   return null;
  }
  var entry=new List();
  for(var i=0;i<=this.index;i++)
  {
   entry.add(this.entrys[i]);
  }
  return entry;
 }
}
/**
 * Map中的节点对象
 * @param key
 * @param value
 * @return
 */
function Entry(key,value)
{
 this.key=key;
 this.value=http://www.mamicode.com/value;
}
css代码:

/*datagrid 大块样式*/
.datagrid {position:relative;background:white;margin:0px;padding:0px;overflow:hidden;border:1px inset;-moz-user-select:none;}
/*datagrid 表格全局样式*/
.datagrid table {table-layout:fixed;margin:0px;}
.datagrid table td {height:18px;cursor:default;font-size:12px;font-family:verdana;text-indent:2px;border-right:1px solid #cccccc;border-bottom:1px solid #cccccc;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;word-break:keep-all;}
.datagrid table td .arrow {font-size:8px;color:#808080;}
.datagrid table .lastdata {border-right:none;}
.datagrid table .column {cursor:default;background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040;border-bottom:1px solid #404040;border-left:1px solid #fff;}
.datagrid table .over {cursor:default;background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040;border-bottom:1px solid #404040;border-left:1px solid #fff;}
.datagrid table .sortdown {cursor:default;background:buttonface;border-right:1px solid #ffffff;border-bottom:1px solid #ffffff;border-left:1px solid #404040;border-top:1px solid #404040;position:relative;left:1px;}
.datagrid table .dataover {background:#FAFAFA;}
.datagrid table .firstcolumn {width:30px;text-indent:0px;text-align:center;background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040;border-bottom:1px solid #404040;border-left:1px solid #fff;}
.datagrid table .lastcolumn {width:17px;background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040;border-bottom:1px solid #404040;border-left:1px solid #fff;}
/*datagrid 选定行样式*/
.datagrid table .selectedrow {background:highlight;color:white;}
/*datagrid 表头样式*/
.titlecolumn {width:100%;position:absolute;top:0px;left:0px;z-index:3;}
/*datagrid 左边栏样式*/
.slidecolumn {width:30px;position:absolute;top:0px;left:0px;z-index:2;}
.slidecolumn td {width:30px;text-indent:0px;text-align:center;background:buttonface;border-top:1px solid #fff;border-right:1px solid #404040;border-bottom:1px solid #404040;border-left:1px solid #fff;}
/*datagrid 内容表体样式*/
.datacolumn {width:100%;position:absolute;top:0px;left:0px;}
.datacolumn td {top:0px;left:0px;margin:0px;padding:0px}
.datacolumn td input {margin:0px;border:0px #cccccc solid;}

多级动态暂未实现

jsp 自定义标签实现表格转载http://blog.csdn.net/chenshuang_com