package com.ts.taglib.html;
import java.lang.reflect.Field;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
* 事件處理
* @author 陳雙
* @date 2012-09-22
* @mail [email protected]
*/
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.DataGrid;
/**
* 表格控件
* @author 陳雙
* @date 2012-09-22
* @mail [email protected]
*
*/
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=null;
multiple=false;
}
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 boolean isMultiple() {
return multiple;
}
public void setMultiple(boolean multiple) {
this.multiple = multiple;
}
public int doEndTag() throws JspException {
try {
pageContext.getOut().print(createTable());
} catch (IOException e) {
throw new JspException(e.getMessage());
}
return 6;
}
public int doStartTag() throws JspException {
pageContext.setAttribute("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=\"javascript:lastPage();\">上頁</a> <a href=\"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=null;
multiple=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 [email protected] */ 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; } }
package com.ts.taglib.data;
import java.io.Serializable; /** * 列數據 * @author 陳雙 * @date 2012-09-23 * @mail [email protected] */ 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.io.Serializable; import java.util.List; import java.util.Map; /** * 用於構建多級表頭動態列表格對象 * @author 陳雙 * @date 2012-09-22 * @mail [email protected] * */ 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 = data; } public String getDblclick() { return dblclick; } public void setDblclick(String dblclick) { this.dblclick = dblclick; } }
js代碼:
//=========================================================================== /** *表格操作 *@author 陳雙 *@date 2012-09-26 *@mail [email protected] */ //=========================================================================== 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'> </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'> </td></tr>"; } else { title+="</tr>"; } } } else {//正常情況 title="<tr><td class='firstcolumn'> </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'> </td></tr>"; } if(columns&&columns.length>0) {//彙總表格 sum="<tr><td class='firstcolumn'>彙總</td>"; if(isMultiple) { sum+="<td class='column' width='30'> </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+="> </td>"; } sum+="<td class='lastcolumn'> </td></tr>"; } if(rows&&rows.size()>0) {//構建第一列和數據表格 if(flag) { first="<tr><td> </td></tr>"; first+="<tr><td> </td></tr>"; } else { first="<tr><td> </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?" ":map.get(columns[j].name); data+="</td>"; } data+="<td class='lastdata'>"; data+="<input name='rowid' type='hidden' value='"+(rowId)+"'/>"; data+=" </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;\"> </td>"; for(var j=0;j<columns.length;j++) { data+="<td style=\"border:0;\"> </td>"; } data+="<td style=\"border:0;\"> </td>"; first+="<tr><td style=\"border:0;background-color:white;\"> </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=data; this.hidden=hidden; this.disabled=disabled; this.sum=sum; this.size=size; this.colspan=colspan; this.ondblclick=ondblclick; this.drillEvent=drillEvent; } /** *@param 排序 *@param id爲表格id *@param index:列索引 *@param sort:asc是升序,dsc是降序 *@param isMultiple是否多行 */ function sortTableForGrid(id,index,isMultiple) { var flag=get(id, 'flag'); var _isHbar=get(id, '_isHbar'); var tr=new Array();//行集合 var td=new Array();//列集合 var temp;//臨時單元格 var table=document.getElementById(id); var header=document.getElementById("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=' '; } 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=table.rows[i].cells[columns[j]].innerText; if(!checkValueForGrid(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 checkValueForGrid(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 checked是否選中true爲選中,false沒選中 *@param name 名稱 */ function checkAllForGrid(checked,name) { var checkList=document.getElementsByName(name); if(checkList && checkList.length>0) { for(var i=0;i<checkList.length;i++) { checkList[i].checked=checked; } } }
/** * 構建表格以及滾動條 * @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;\"> </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;\"> </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 [email protected]
*/
////////////////////////////////////////////////////////////////////////////////////
/**
* 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;
}
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;}
多級動態暫未實現