Java实现的自定义可编辑表格控件(支持汇总、滚动、增行、删行、小数、日期、下拉列表、参照等)

来源:互联网 发布:ubuntu phpstorm 2017 编辑:程序博客网 时间:2024/04/30 08:36

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 onmouseover;    private String onmouseout;    private String onmousedown;    private String onmouseup;    private String onmousemove;    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 onmouseover; } public void setOnmouseover(String onmouseover) {  this.onmouseover = onmouseover; } public String getOnmouseout() {  return onmouseout; } public void setOnmouseout(String onmouseout) {  this.onmouseout = onmouseout; } public String getOnmousedown() {  return onmousedown; } public void setOnmousedown(String onmousedown) {  this.onmousedown = onmousedown; } public String getOnmouseup() {  return onmouseup; } public void setOnmouseup(String onmouseup) {  this.onmouseup = onmouseup; } public String getOnmousemove() {  return onmousemove; } public void setOnmousemove(String onmousemove) {  this.onmousemove = onmousemove; } 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.EditTable;import com.ts.taglib.data.Option;/** * 可编辑的表格控件 * @author 陈双 * @date 2012-09-23 * @mail chenshuang_com@sina.com */public class EditTableTag extends BaseHandlerTag {private static final long serialVersionUID = -5843535522230149125L;    private String name;//名称    private String width;//宽度    private String height;//高度    private String data;//取数    private String columnWidth="125";//默认宽度public EditTableTag()    {    super();    name=null;    width=null;    height=null;    data=null;    }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 String getData() {return data;}public void setData(String data) {this.data = data;}public int doEndTag() throws JspException {try {//pageContext.getOut().print(renderElement());//启用第一种方案pageContext.getOut().print(createScript());} catch (IOException e) {throw new JspException(e.getMessage());}return 6;}/** * 第一种实现方式全部由js实现表格的构建 * @return * @throws JspException */public String createScript()throws JspException{List list=(List) pageContext.getAttribute("columnHeader", 2);EditTable grid=(EditTable) pageContext.getAttribute(data, 2);if(list==null||list.size()==0){throw new JspException("Table name is "+name+",列数必须大于0!");}StringBuffer handlers=new StringBuffer("<div id=\"main_");handlers.append(getName());handlers.append("\" style=\"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");//构建所有的列handlers.append(getColumns(list));//构建数据行handlers.append(getRows(grid==null?null:grid.getData()));//调用js生成表格控件handlers.append("\n CreateEditTable('");handlers.append(getName());handlers.append("','main_");handlers.append(getName());handlers.append("',");handlers.append(getWidth());handlers.append(",");handlers.append(getHeight());handlers.append(",getColumns_");handlers.append(getName());handlers.append("(),getRows_");handlers.append(getName());handlers.append("(),'");if(grid!=null&&grid.getStatus()!=null){handlers.append(grid.getStatus());}else{handlers.append(EditTable.INSERT);}handlers.append("');\n</script>\n</div>");return handlers.toString();}/** * 实现方式二由Java构建table标签再配置js特效 * @return * @throws JspException */public String renderElement() throws JspException{List list=(List) pageContext.getAttribute("columnHeader", 2);EditTable grid=(EditTable) pageContext.getAttribute(data, 2);if(list==null||list.size()==0){throw new JspException("Table name is "+name+",列数必须大于0!");}StringBuffer script=new StringBuffer("<script type=\"text/javascript\">\n");//构建获取所有列的js函数script.append(getColumns(list));        //构建获取汇总列的js函数script.append("\n function getColumns_sum_");script.append(name);script.append("()\n{\n");script.append(getSumColumns(list));script.append("\n return columns_sum;\n}\n</script>\n");                //开始构建表格script.append("\n <div id=\"table_");script.append(getName());script.append("\" width=\"");script.append(getWidth());script.append("\" height=\"");script.append(Integer.parseInt(getHeight())+25);script.append("\" style=\"border:solid 1 #cccccc;padding:0px;position:absolute;\">");script.append("<table border=\"0\" width=\"");script.append(getWidth());script.append("\" height=\"25px\" style=\"table_layout:fixed;margin:0;\">\n<tr>\n<td align=\"right\"><input type=\"button\" style=\"background-color:#cccccc;\" value=\"增行\" onClick=\"");script.append("addRowForTable('");script.append(getName());script.append("',getColumns_");script.append(name);script.append("());\"");if(grid!=null&&grid.getStatus()!=null&&grid.getStatus().equals(EditTable.READ)){script.append(" disabled=\"disabled\"");}script.append("/>");script.append("<input type=\"button\" style=\"background-color:#cccccc;\" value=\"删行\" onClick=\"");script.append("deleteRowForTable('");script.append(getName());script.append("',getColumns_sum_");script.append(name);script.append("());\"");if(grid!=null&&grid.getStatus()!=null&&grid.getStatus().equals(EditTable.READ)){script.append(" disabled=\"disabled\"");}script.append("/>");script.append("\n</td>\n</tr>\n</table>\n");//构建表头StringBuffer handlers=new StringBuffer();handlers.append("<table id=\\\"header_");handlers.append(getName());handlers.append("\\\" cellspacing=\\\"0\\\" cellpadding=\\\"0\\\" class=\\\"titlecolumn\\\"><tr>");handlers.append("<td class=\\\"firstcolumn\\\"> </td>");for(int i=0;i<list.size();i++){//创建表头Column column=(Column) list.get(i);handlers.append("<td  class=\\\"column\\\" align=\\\"center\\\"");if(column.getWidth()!=null){handlers.append(" width=\\\"");handlers.append(column.getWidth());handlers.append("\\\"");}else{handlers.append(" width=\\\"");handlers.append(columnWidth);handlers.append("\\\"");}if(column.isHidden()){handlers.append(" style=\\\"display:none;\\\"");}handlers.append(">");handlers.append(column.getLabel());handlers.append("</td>");}handlers.append("<td class=\\\"lastcolumn\\\" > </td>");handlers.append("</tr></table>");        //创建第一列表handlers.append("<table id=\\\"first_");handlers.append(getName());handlers.append("\\\" cellspacing=\\\"0\\\" cellpadding=\\\"0\\\" class=\\\"slidecolumn\\\">");handlers.append("<tr><td> </td></tr>");if(grid!=null&&grid.getData()!=null&&grid.getData().size()>0){for(int i=0;i<grid.getData().size();i++){handlers.append("<tr>");handlers.append("<td>");handlers.append(i+1);handlers.append("</td></tr>");}}else{handlers.append("<tr>");handlers.append("<td>");handlers.append("1");handlers.append("</td></tr>");}handlers.append("<tr>");handlers.append("<td>");handlers.append(" ");handlers.append("</td></tr>");handlers.append("<tr>");handlers.append("<td>");handlers.append(" ");handlers.append("</td></tr>");handlers.append("</table>");//构建表体handlers.append("<table");handlers.append(" id=\\\"");handlers.append(getName());handlers.append("\\\"");handlers.append(" cellpadding=\\\"");handlers.append("0\\\"");handlers.append(" cellspacing=\\\"");handlers.append("0\\\"");//添加汇总函数调用事件handlers.append(" onclick=\\\"sumRowForTable('");handlers.append(getName());handlers.append("',getColumns_sum_");handlers.append(name);handlers.append("());\\\"");handlers.append(" class=\\\"datacolumn\\\">");handlers.append("<td class=\\\"firstcolumn\\\"> </td>");for(int i=0;i<list.size();i++){//创建表头Column column=(Column) list.get(i);handlers.append("<td  class=\\\"column\\\" align=\\\"center\\\"");if(column.getWidth()!=null){handlers.append(" width=\\\"");handlers.append(column.getWidth());handlers.append("\\\"");}else{handlers.append(" width=\\\"");handlers.append(columnWidth);handlers.append("\\\"");}if(column.isHidden()){handlers.append(" style=\\\"display:none;\\\"");}handlers.append(">");handlers.append(column.getLabel());handlers.append("</td>");}handlers.append("<td class=\\\"lastcolumn\\\" > </td></tr>");if(grid!=null&&grid.getData()!=null&&grid.getData().size()>0){//加载数据到填充表格for(int i=0;i<grid.getData().size();i++){Map row=(Map) grid.getData().get(i);handlers.append("<tr>");handlers.append("<td class=\\\"firstcolumn\\\"> </td>");for(int j=0;j<list.size();j++){Column column=(Column) list.get(j);handlers.append("<td width=\\\"");if(column.getWidth()!=null){handlers.append(column.getWidth());handlers.append("\\\"");}else{handlers.append(columnWidth);handlers.append("\\\"");}if(column.isHidden()){handlers.append(" style=\\\"display:none;\\\"");}if(column.getType().equals("int")||column.getType().equals("number")){handlers.append(" align=\\\"right\\\"");}handlers.append(">");handlers.append(createEditCell(column,"rowid_"+(i+1),row.get(column.getName()),false,grid.getStatus()));handlers.append("</td>");}handlers.append("<td class=\\\"lastdata\\\"><input name=\\\"rowid\\\" type=\\\"hidden\\\"");handlers.append(" value=\\\"rowid_");handlers.append((i+1));handlers.append("\\\"/> </td>");handlers.append("</tr>");}}else{//创建空白行handlers.append("<tr>");handlers.append("<td class=\\\"firstcolumn\\\"> </td>");for(int j=0;j<list.size();j++){Column column=(Column) list.get(j);handlers.append("<td ");if(column.isHidden()){handlers.append(" style=\\\"display:none;\\\"");}if(column.getType().equals("int")||column.getType().equals("number")){handlers.append(" align=\\\"right\\\"");}handlers.append(">");handlers.append(createEditCell(column,"rowid_1",null,false,EditTable.INSERT));handlers.append("</td>");}handlers.append("<td class=\\\"lastdata\\\"><input name=\\\"rowid\\\" type=\\\"hidden\\\"");handlers.append(" value=\\\"rowid_1\\\"/></td>");handlers.append("</tr>");}for(int i=0;i<2;i++){handlers.append("<tr>");for(int j=0;j<list.size();j++){handlers.append("<td> </td>");}handlers.append("</tr>");}handlers.append(prepareStyles());handlers.append(prepareEvents());handlers.append("</table>");//创建汇总行表格handlers.append("<table id=\\\"sum_");handlers.append(getName());handlers.append("\\\"");handlers.append(" cellpadding=\\\"");handlers.append("0\\\"");handlers.append(" cellspacing=\\\"");handlers.append("0\\\"");handlers.append(" style=\\\"width:100%;position:absolute;top:");handlers.append(Integer.parseInt(getHeight())-18-17);handlers.append(";left:0;z-index:4;\\\">");handlers.append(createSumRow(list));handlers.append("</table>");script.append("<script>");script.append(createScript(handlers));script.append("\n execute('");script.append(getName());script.append("','table_");script.append(getName());script.append("',");script.append(getWidth());script.append(",");script.append(getHeight());script.append(",");script.append("html);\n");script.append("sumRowForTable('");script.append(getName());script.append("',getColumns_sum_");script.append(name);script.append("());</script>\n</div>");return script.toString();}/** * 构建所有的列 * @param list * @return * @throws JspException */private String getColumns(List list) throws JspException{StringBuffer columns=new StringBuffer();columns.append(getOptions(list));if(list!=null&&list.size()>0){columns.append("function getColumns_");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 column");columns.append(i);columns.append("=new Column('");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(",");if(column.getType().equals("combox")){//构建optionscolumns.append("options");columns.append(i);}else{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());if(column.getOndblclick()!=null){columns.append(",\"");columns.append(column.getOndblclick());columns.append("\");\n");}else{columns.append(",");columns.append("null);\n");}columns.append("columns[");columns.append(i);columns.append("]=column");columns.append(i);columns.append(";\n");}columns.append("return columns;\n}");}return columns.toString();}/** * 构建combox的options * @param list * @return * @throws JspException */private String getOptions(List list)throws JspException{StringBuffer handlers=new StringBuffer();for(int i=0;i<list.size();i++){Column column=(Column) list.get(i);if(column.getType().equals("combox")){List options=(List) pageContext.getAttribute(column.getData(), 2);if(options==null){throw new JspException("Column: "+column.getName()+" data: "+column.getData()+" not found in requestScope!");}handlers.append("var options");handlers.append(i);handlers.append("=new Array();\n");for(int j=0;j<options.size();j++){Option option=(Option) options.get(j);handlers.append("options");handlers.append(i);handlers.append("[");handlers.append(j);handlers.append("]=new OptionData('");handlers.append(option.getValue());handlers.append("','");handlers.append(getString(option.getLabel(),column.getSize()));handlers.append("');\n");}}}return handlers.toString();}/** * 构建汇总行 * @param list * @retur * n */private String createSumRow(List list){StringBuffer row=new StringBuffer("");if(list!=null&&list.size()>0){row.append("<tr>");row.append("<td class=\\\"firstcolumn\\\">汇总</td>");for(int i=0;i<list.size();i++){Column column=(Column) list.get(i);row.append("<td class=\\\"column\\\" width=\\\"");if(column.getWidth()!=null){row.append(column.getWidth());}else{row.append(columnWidth);}if(column.isHidden()){row.append(" style=\\\"display:none;\\\"");}row.append("\\\"> </td>");}row.append("<td class=\\\"lastcolumn\\\"> </td>");row.append("</tr>");}return row.toString();}//构建汇总列数组private String getSumColumns(List list){StringBuffer cells=new StringBuffer("\n var columns_sum=new Array();\n ");if(list!=null&&list.size()>0){int index=0;for(int i=0;i<list.size();i++){Column col=(Column) list.get(i);if(col.isSum()&&(col.getType().equals("int")||col.getType().equals("number"))){cells.append("columns_sum[");cells.append(index);cells.append("]=");cells.append((i+1));cells.append(";\n ");index++;}}}return cells.toString();}/** * 构建编辑单元格 * @param column 列 * @param rowid 行id * @param value 值 * @return 可编辑控件 */public String createEditCell(Column column,String rowid,Object value,boolean script,String status)throws JspException{StringBuffer cell=new StringBuffer();if("text".equals(column.getType())){//构建文本cell.append("<input name=\\\"");cell.append(column.getName());cell.append(rowid);cell.append("\\\" type=\\\"text\\\"");if(value!=null){cell.append(" value=\\\"");cell.append(value);cell.append("\\\"");}else{cell.append(" value=\\\"\\\"");}if(column.isDisabled()||status.equals(EditTable.READ)){cell.append(" disabled=\\\"disabled\\\"");}cell.append(" style=\\\"margin:0px;border:0px #cccccc solid;\\\"/>");}else if("int".equals(column.getType())){//intcell.append("<input name=\\\"");cell.append(column.getName());cell.append(rowid);cell.append("\\\" type=\\\"text\\\"");if(value!=null){cell.append(" value=\\\"");cell.append(value);cell.append("\\\"");}else{cell.append(" value=\\\"\\\"");}if(column.isDisabled()||status.equals(EditTable.READ)){cell.append(" disabled=\\\"disabled\\\"");}if(script){cell.append(" onkeyup=\\\"var express=/^\\d+$/;if(!express.test(this.value))this.value='';\\\"");}else{cell.append(" onkeyup=\\\"var express=/^\\d+$/;if(!express.test(this.value))this.value='';\\\"");}cell.append(" style=\\\"margin:0px;border:0px #cccccc solid;\\\"/>");}else if("number".equals(column.getType())){//numbercell.append("<input name=\\\"");cell.append(column.getName());cell.append(rowid);cell.append("\\\" type=\\\"text\\\"");if(value!=null){cell.append(" value=\\\"");cell.append(value);cell.append("\\\"");}else{cell.append(" value=\\\"\\\"");}if(column.isDisabled()||status.equals(EditTable.READ)){cell.append(" disabled=\\\"disabled\\\"");}if(script){cell.append(" onkeyup=\\\"if(isNaN(this.value))this.value='';\\\"");}else{cell.append(" onkeyup=\\\"if(isNaN(this.value))this.value='';\\\"");}cell.append(" style=\\\"margin:0px;border:0px #cccccc solid;\\\"/>");}else if("date".equals(column.getType())){//构建日期cell.append("<input name=\\\"");cell.append(column.getName());cell.append(rowid);cell.append("\\\" type=\\\"text\\\"");if(value!=null){cell.append(" value=\\\"");cell.append(value);cell.append("\\\"");}else{cell.append(" value=\\\"\\\"");}if(column.isDisabled()||status.equals(EditTable.READ)){cell.append(" disabled=\\\"disabled\\\"");}cell.append(" onclick=\\\"");cell.append("calendar();\\\"");cell.append(" size=");if(column.getSize()!=null){cell.append(column.getSize());}else{cell.append("14");}cell.append(" style=\\\"margin:0px;border:0px #cccccc solid;\\\"/>");cell.append("<img src=\\\"images/datePicker/datePicker.gif\\\" align=\\\"center\\\"/>");}else if("refer".equals(column.getType())){//构建参照cell.append("<input name=\\\"");cell.append(column.getName());cell.append(rowid);cell.append("\\\" type=\\\"text\\\"");if(value!=null){cell.append(" value=\\\"");cell.append(value);cell.append("\\\"");}else{cell.append(" value=\\\"\\\"");}if(column.isDisabled()||status.equals(EditTable.READ)){cell.append(" disabled=\\\"disabled\\\"");}cell.append(" readonly=\\\"true\\\"");cell.append(" ondblclick=\\\"");cell.append(column.getOndblclick());cell.append("\\\"");cell.append(" size=");if(column.getSize()!=null){cell.append(column.getSize());}else{cell.append("14");}cell.append(" style=\\\"margin:0px;border:0px #cccccc solid;\\\"/>");cell.append("<img src=\\\"images/refer/refer.jpg\\\"");cell.append(" onclick=\\\"");cell.append(column.getOndblclick());cell.append("\\\"");cell.append("/>");}else if("combox".equals(column.getType())){//构建下啦列表cell.append("<select name=\\\"");cell.append(column.getName());cell.append(rowid);cell.append("\\\"");if(value!=null){cell.append(" value=\\\"");cell.append(value);cell.append("\\\"");}else{cell.append(" value=\\\"\\\"");}if(column.isDisabled()||status.equals(EditTable.READ)){cell.append(" disabled=\\\"disabled\\\"");}cell.append(" style=\\\"margin:0px;border:0px #cccccc solid;\\\">");List options=(List) pageContext.getAttribute(column.getData(), 2);if(options==null){throw new JspException("editTable "+name+" Column: "+column.getName()+" data: "+column.getData()+" not found in requestScope!");}if(options!=null&&options.size()>0){for(int i=0;i<options.size();i++){Option option=(Option) options.get(i);cell.append("<option value=\\\"");cell.append(option.getValue());cell.append("\\\">");cell.append(getString(option.getLabel(),column.getSize()));cell.append("</option>");}}cell.append("</select>");}return cell.toString();}/** * 计算label的长度,并补充长度 * @param label * @return */public String getString(String label,String size){int total=13;//总长度if(size!=null){total=Integer.parseInt(size);}int length=label.getBytes().length;//实际长度if(length<13){int i=0;int count=total-length;//需要补充的长度StringBuffer handlers=new StringBuffer(label);while(i<count){handlers.append(" ");i++;}return handlers.toString();}return label;}public StringBuffer createScript(StringBuffer handlers){StringBuffer script=new StringBuffer("var html=\"");//格式化for(int i=0;i<handlers.length();i++){if(handlers.charAt(i)=='<'){script.append("\"\n+\"");script.append(handlers.charAt(i));}else if(handlers.charAt(i)=='>'){script.append(handlers.charAt(i));script.append("\"\n+\"");}else if(handlers.charAt(i)==' '&&handlers.charAt(i+1)=='s'&&handlers.charAt(i+2)=='t'&&handlers.charAt(i+3)=='y'&&handlers.charAt(i+4)=='l'&&handlers.charAt(i+5)=='e'){script.append(handlers.charAt(i));script.append("\"\n+\"");}else{script.append(handlers.charAt(i));}}script.append("\";");return script;}/** * 构建rows数据集将Java中的List<map>转成javascript中List<Map>形式 * @param list列表 * @return */public String getRows(List list){StringBuffer handlers=new StringBuffer("\n function getRows_");handlers.append(getName());SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");handlers.append("()\n{\n");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 int doStartTag() throws JspException {pageContext.setAttribute("columnHeader", new ArrayList(),2);return 1;}public void release() {super.release();name=null;    width=null;    height=null;    data=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 = data; } public String getColspan() {  return colspan; } public void setColspan(String colspan) {  this.colspan = colspan; } public String getRowspan() {  return rowspan; } public void setRowspan(String rowspan) {  this.rowspan = rowspan; } 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; }}

package com.ts.taglib.data;

import java.util.List;import java.util.Map;/** * EditTable辅助类 * @author 陈双 * @date 2012-09-29 * @mail chenshuang_com@sina.com */public class EditTable { public static final String UPDATE="update"; public static final String READ="read"; public static final String INSERT="insert"; private String name; private String width; private String height; private String status=INSERT; private List<Map<String,Object>> data; 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 String getStatus() {  return status; } public void setStatus(String status) {  this.status = status; } public List<Map<String,Object>> getData() {  return data; } public void setData(List<Map<String,Object>> data) {  this.data = data; }

}

package com.ts.taglib.data;

import java.io.Serializable;/** * 选择项 * @author 陈双 * @date 2012-09-22 * @mail chenshuang_com@sina.com * */public class Option implements Serializable {

 private static final long serialVersionUID = -6526710058511724174L;    private String value;    private String label;    public Option()    {         }    public Option(String value,String label)    {     this.value=value;     this.label=label;    } public String getValue() {  return value; } public void setValue(String value) {  this.value = value; } public String getLabel() {  return label; } public void setLabel(String label) {  this.label = label; } public boolean equals(Object obj) {  // TODO Auto-generated method stub  if(!(obj instanceof Option))   return false;  else if(this.getValue().equals(((Option)obj).getValue())&&this.getLabel().equals(((Option)obj).getLabel()))   return true;  else   return false; } }

 

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=null;    colspan=null;    ondblclick=null;    drillEvent=null;    hidden=false;    disabled=false;    sum=false;    }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 = data;}public String getColspan() {return colspan;}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=null;    colspan=null;    size=null;    ondblclick=null;    drillEvent=null;    hidden=false;    disabled=false;    sum=false;}}js代码:
//////////////////////////////////////////////////////////////////////////////////////** * 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=function(value){//是否包含值  if(this.index==-1)  {   return false;  }  for(var i=0;i<=this.index;i++)  {   var entry=this.entrys[i];   if(entry.value==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=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=value;}
//==========================================================================/**                                                                         * EditTable操作                                                            * @author 陈双                                                             * @date 2012-09-27                                                         * @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 表格名称 * @param parentId 父节点id * @param width 表格宽度 * @param height 表格高度 * @param columns 表格所有的列,一数组的形式保存Column对象 * @param rows 数据列表,它是以集合List的形式保存Map,其中key是name,value是值 * @param status 表格状态值: read只读,update可修改,insert新增 */function CreateEditTable(id,parentId,width,height,columns,rows,status){ if((!id)|(!parentId)||(!width)||(!height)||(!columns)||(!rows)) {  return; } //声明全局变量 var all_columns;//所有的列 var sum_columns;//汇总列 var isHbar;//是否有横向滚动条 var first="";//声明第一列表 var title="";//标题表 var data="";//数据表 var sum="";//汇总表 var columnWidth=125;//默认列宽 all_columns=columns;//所有的列 put(id, "all_columns", all_columns);//注册全局变量 if(columns&&columns.length>0) {//标题和汇总表格  title="<tr><td class='firstcolumn'>&nbsp;</td>";  sum="<tr><td class='firstcolumn'>汇总</td>";  for(var i=0;i<columns.length;i++)  {   title+="<td class='column' align='center'";   sum+="<td class='column' align='center'";   if(columns[i].hidden)   {    columns[i].width=1;    title+=" style=\"border:none;\"";    sum+=" style=\"border:none;\"";   }   if(columns[i].width)   {    title+=" width='"+columns[i].width+"'";    sum+=" width='"+columns[i].width+"'";   }   else   {    title+=" width='"+columnWidth+"'";    sum+=" width='"+columnWidth+"'";   }   title+=">"+columns[i].label+"</td>";   sum+=">&nbsp;</td>";  }  title+="<td class='lastcolumn'>&nbsp;</td></tr>";  sum+="<td class='lastcolumn'>&nbsp;</td></tr>"; } if(rows&&rows.size()>0) {//构建第一列和数据表格  first="<tr><td>&nbsp;</td></tr>";  data="";  for(var i=0;i<rows.size();i++)  {   first+="<tr><td>"+(i+1)+"</td></tr>";   data+="<tr><td class='firstcolumn'>"+(i+1)+"</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+=">";    if(columns[j].type=="text")    {     data+=createText(columns[j],rowId,map.get(columns[j].name),status);    }    else if(columns[j].type=="int")    {     data+=createInt(columns[j],rowId,map.get(columns[j].name),status);    }    else if(columns[j].type=="number")    {     data+=createNumber(columns[j],rowId,map.get(columns[j].name),status);    }    else if(columns[j].type=="date")    {     data+=createDate(columns[j],rowId,map.get(columns[j].name),status);    }    else if(columns[j].type=="combox")    {     data+=createCombox(columns[j],rowId,map.get(columns[j].name),status);    }    else if(columns[j].type=="refer")    {     data+=createRefer(columns[j],rowId,map.get(columns[j].name),status);    }    data+="</td>";   }   data+="<td class='lastdata'>";   data+="<input name='rowid' type='hidden' value='"+(rowId)+"'/>";   data+="&nbsp;</td></tr>";  } } else {//构建空行  first="<tr><td>&nbsp;</td></tr>";  first+="<tr><td>1</td></tr>";  data+="<tr><td class='firstcolumn'>1</td>";  var rowId="rowid_1";  for(var j=0;j<columns.length;j++)  {   data+="<td";   if(columns[j].hidden)   {    columns[j].width=1;    data+=" style=\"border:none;\"";   }   if(columns[j].width)   {    data+=" width='"+columns[j].width+"'";   }   else   {    data+=" width='"+columnWidth+"'";   }   data+=">";   if(columns[j].type=="text")   {    data+=createText(columns[j],rowId,null,status);   }   else if(columns[j].type=="int")   {    data+=createInt(columns[j],rowId,null,status);   }   else if(columns[j].type=="number")   {    data+=createNumber(columns[j],rowId,null,status);   }   else if(columns[j].type=="date")   {    data+=createDate(columns[j],rowId,null,status);   }   else if(columns[j].type=="combox")   {    data+=createCombox(columns[j],rowId,null,status);   }   else if(columns[j].type=="refer")   {    data+=createRefer(columns[j],rowId,null,status);   }   data+="</td>";  }  data+="<td class='lastdata'>";  data+="<input name='rowid' type='hidden' value='rowid_1'/>";  data+="&nbsp;</td></tr>"; } //构建汇总列    sum_columns=new Array();//初始化 var k=0; for(var i=0;i<columns.length;i++) {  if(columns[i].sum)  {   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);  } } 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' onclick=\"sumRowForTable('"+id+"');\">"; 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+"</html>"; //构建表格操作按钮层 var html="<table border='0' width='"+width+"' height='25px' style='table_layout:fixed;'><tr><td align='right'><input type='button' style='background-color:#cccccc;' value='增行' onClick=\""; html+="addRowForTable('"+id+"');\""; if(status=="read") {  html+=" disabled='disabled'"; } html+="/><input type='button' style='background-color:#cccccc;' value='删行' onClick=\""; html+="deleteRowForTable('"+id+"');\""; if(status=="read") {  html+=" disabled='disabled'"; } html+="/></td></tr></table>"; //构建主体框架 var frame=document.createElement("DIV"); frame.id="table_"+id; frame.style.width=width; frame.style.height=parseInt(height)+25; frame.style.border="solid 1 #cccccc"; frame.style.padding="0px"; frame.style.position="absolute"; frame.innerHTML=html; document.getElementById(parentId).appendChild(frame); execute(id, null, width, height, first_html+title_html+data_html+sum_html,frame); sumRowForTable(id);}/** * 列结构 * @param name名称 * @param label 标签 * @param type 类型 * @param width 宽度 * @param height 高度 * @param data 列数据来源是一个数组 * @param hidden 是否隐藏 * @param disabled 是否可用 * @param sum 是否汇总 * @param size 字符个数 * @param ondblclick 鼠标双击事件 */function Column(name,label,type,width,height,data,hidden,disabled,sum,size,ondblclick){ this.name=name; this.label=label; this.type=type; this.width=width; this.height=height; this.data=data; this.hidden=hidden; this.disabled=disabled; this.sum=sum; this.size=size; this.ondblclick=ondblclick; }/** * 选项 * @param value 值 * @param label 标签 * @return */function OptionData(value,label){ this.value=value; this.label=label;}/** *添加一行 *@param id 表格id *@param columns 列集合 */function addRowForTable(id){ var columns=get(id, 'all_columns'); var isHbar=get(id,'isHbar'); if(columns==undefined || columns.length==0) {  return; } var first_table=document.getElementById("first_"+id); var table=document.getElementById(id); var newRow, rowId; if(isHbar) {  var firstRow=first_table.insertRow(first_table.rows.length-2);  newRow=table.insertRow(table.rows.length-2);  //添加第一列  var firstcell0=firstRow.insertCell(0);  firstcell0.setAttribute("align","center");  firstcell0.innerHTML=first_table.rows.length-3;    var cell0=newRow.insertCell(0);  cell0.setAttribute("className","firstcolumn");  cell0.setAttribute("align","center");  cell0.innerHTML=first_table.rows.length-3;  rowId="rowid_"+(table.rows.length-3); } else {  var firstRow=first_table.insertRow(first_table.rows.length-1);  newRow=table.insertRow(table.rows.length-1);  //添加第一列  var firstcell0=firstRow.insertCell(0);  firstcell0.setAttribute("align","center");  firstcell0.innerHTML=first_table.rows.length-2;    var cell0=newRow.insertCell(0);  cell0.setAttribute("className","firstcolumn");  cell0.setAttribute("align","center");  cell0.innerHTML=first_table.rows.length-2;  rowId="rowid_"+(table.rows.length-2); } for(var i=0;i<columns.length;i++) {  var cell=newRow.insertCell((i+1));  //cell.setAttribute("className","datacolumn");  if(columns[i].type=="text")  {   cell.innerHTML=createText(columns[i],rowId);  }  else if(columns[i].type=="int")  {   cell.innerHTML=createInt(columns[i],rowId);  }  else if(columns[i].type=="number")  {   cell.innerHTML=createNumber(columns[i],rowId);  }  else if(columns[i].type=="date")  {   cell.innerHTML=createDate(columns[i],rowId);  }  else if(columns[i].type=="combox")  {   cell.innerHTML=createCombox(columns[i],rowId);  }  else if(columns[i].type=="refer")  {   cell.innerHTML=createRefer(columns[i],rowId);  } } var lastCell=newRow.insertCell(columns.length+1); lastCell.setAttribute("className","lastdata") lastCell.innerHTML="<input name='rowid' type='hidden' value='"+rowId+"'/>&nbsp;"; block_scroll(id);}/** * 构建文本控件 * @param column 列 * @param rowId 行id * @param value 值 * @param status 单元格的状态 * @return */function createText(column,rowId,value,status){ var cell="<input name='"+column.name+rowId+"'";  if(value) {  cell+=" type='text' value='"+value+"'"; } else if(column.value) {  cell+=" type='text' value='"+column.value+"'"; } else {  cell+=" type='text' value=''"; } if(column.disabled||status=="read") {  cell+=" disabled='disabled'"; } if(column.hidden) {  cell+=" style=\"display:none;\""; } cell+="/>"; return cell;}/** * 构建整数控件 * @param column 列 * @param rowId 行id * @param value 值 * @param status 单元格的状态 * @return */function createInt(column,rowId,value,status){ var cell="<input name='"+column.name+rowId+"'"; if(value) {  cell+=" type='text' value='"+value+"'"; } else if(column.value) {  cell+=" type='text' value='"+column.value+"'"; } else {  cell+=" type='text' value=''"; } if(column.disabled||status=="read") {  cell+=" disabled='disabled'"; } cell+=" onkeyup='var express=/^\\d+$/;if(!express.test(this.value))this.value=\"\";'"; if(column.hidden) {  cell+=" style=\"display:none;\""; } cell+="/>"; return cell;}/** * 构建小数控件 * @param column 列 * @param rowId 行id * @param value 值 * @param status 单元格的状态 * @return */function createNumber(column,rowId,value,status){ var cell="<input name='"+column.name+rowId+"'"; if(value) {  cell+=" type='text' value='"+value+"'"; } else if(column.value) {  cell+=" type='text' value='"+column.value+"'"; } else {  cell+=" type='text' value=''"; } if(column.disabled||status=="read") {  cell+=" disabled='disabled'"; } cell+=" onkeyup='if(isNaN(this.value))this.value=\"\";'"; if(column.hidden) {  cell+=" style=\"display:none;\""; } cell+="/>"; return cell;}/** * 构建日期控件 * @param column 列 * @param rowId 行id * @param value 值 * @param status 单元格的状态 * @return */function createDate(column,rowId,value,status){ var cell="<input name='"+column.name+rowId+"'"; if(value) {  cell+=" type='text' value='"+value+"'"; } else if(column.value) {  cell+=" type='text' value='"+column.value+"'"; } else {  cell+=" type='text' value=''"; } if(column.disabled||status=="read") {  cell+=" disabled='disabled'"; } if(column.size) {  cell+=" size="+column.size; } else {  cell+=" size=14"; } cell+=" onclick='calendar();'"; if(column.hidden) {  cell+=" style=\"display:none;\""; } cell+="/>"; cell+="<img src='images/datePicker/datePicker.gif' align='center'"; if(column.hidden) {  cell+=" style=\"display:none;\""; } cell+="/>"; return cell;}/** * 构建下拉列表控件 * @param column 列 * @param rowId 行id * @param value 值 * @param status 单元格的状态 * @return */function createCombox(column,rowId,value,status){ var cell="<select name='"+column.name+rowId+"'"; if(value) {  cell+=" value='"+value+"'"; } else if(column.value) {  cell+=" value='"+column.value+"'"; } else {  cell+=" value=''"; } if(column.disabled||status=="read") {  cell+=" disabled='disabled'"; } if(column.hidden) {  cell+=" style=\"display:none;\""; } cell+="/>"; if(column.data && column.data.length>0) {  for(var i=0;i<column.data.length;i++)  {   cell+="<option value='"+column.data[i].value;   cell+="'>";   cell+=column.data[i].label;   cell+="</option>";  } }  cell+="</select>"; return cell;}/** * 构建参照控件 * @param column 列 * @param rowId 行id * @param value 值 * @param status 单元格的状态 * @return */function createRefer(column,rowId,value,status){ var cell="<input name='"+column.name+rowId+"'"; if(value) {  cell+=" type='text' value='"+value+"'"; } else if(column.value) {  cell+=" type='text' value='"+column.value+"'"; } else {  cell+=" type='text' value=''"; } if(column.disabled||status=="read") {  cell+=" disabled='disabled'"; } if(column.size) {  cell+=" size="+column.size; } else {  cell+=" size=14"; }// cell+=" readonly='true'"; if(column.hidden) {  cell+=" style=\"display:none;\""; } cell+=" ondblclick=\""+column.ondblclick+"\"/>"; cell+="<img src='images/refer/refer.jpg'"; if(column.hidden) {  cell+=" style=\"display:none;\""; } cell+="/>"; return cell;}/** * 删除行 *@param id 表格id *@param columns 汇总列数组名称 */function deleteRowForTable(id){   var isHbar=get(id,'isHbar');//取出全局变量   var table=document.getElementById(id);   var first_table=document.getElementById("first_"+id);   if(isHbar)   {   if(table.rows.length==3)   {   return;   }   table.deleteRow(table.rows.length-3);   first_table.deleteRow(first_table.rows.length-3);   }   else   {   if(table.rows.length==2)   {   return;   }   table.deleteRow(table.rows.length-2);   first_table.deleteRow(first_table.rows.length-2);   }   sumRowForTable(id);   block_scroll(id);}
/** *汇总行 *@param id 表格id *@param columns 汇总列数组 */function sumRowForTable(id){   var columns=get(id,'sum_columns');   var isHbar=get(id,'isHbar');   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&&table.rows.length==3)||(!isHbar&&table.rows.length==2))   {    for(var i=0;i<columns.length;i++)    {     sum_table.rows[0].cells[columns[i]].innerHTML='&nbsp;';    }    return;   }   var length=table.rows.length-1;   if(isHbar)   {    length=table.rows.length-2;   }   for(var i=1;i<length;i++)   {       for(var j=0;j<columns.length;j++)       {          var value=table.rows[i].cells[columns[j]].childNodes[0].value;          if(!checkValueForTable(value))          {             value="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 checkValueForTable(value){  if(value && value.length>0)  {    var newValue=value.replace(/\s+/g,"");    value=newValue;  }  else  {   return false;  }  if(value.length>0 && value.indexOf('.')!=-1)  {//判断是否是小数   var express=/^\d+.\d+$/;//匹配小数   if(express.test(value)){     return true;   }   else   {    return false;   }  }  else  {   var express=/^\d+$/;   if(express.test(value))   {    return true;   }   else   {    return false;   }  }  return false; }/** * 构建表格以及滚动条 * @param id 表格id * @param parentId 父节点,将建构建好的表格节点添加到父节点中 * @param width 表格宽度 * @param height 表格高度 * @param ondblclick 表格双击事件 * @param html (构建好的表格=序列号表格+表头表格+数据表格+汇总表格) * @param parentNode和parentId类似都用于追加构建好的动态表格对象 * @return */function execute(id,parentId,width,height,html,parentNode){ 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);//选中行 } 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); //将构建好的表格节点追加到父节点中 if(parentNode) {  parentNode.appendChild(mainFrame); } else {  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){ var td_object=e.srcElement?e.srcElement:e.target; 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 data_object=get(id,"data_object");  if(current_row!=null)  {//取消之前的选中行状态   data_object.rows[rowIndex].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)//由this调用mouseScrollEvent便于参数传递 } 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"; }}
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;}
这是我封装的控件中的一小部分,贴出来希望对大家有帮助!