通过JavaScript实现在线编辑表格的步骤
======JavaScript在线表格演示======
注:第一列单击弹出下拉框选择;在表格最后一行,按下“下箭头”可以增加一个新的空行;使用回车键可以向下遍历整个表格 *****=====下列按钮根据需要选定使用======***** =====另一个实例===== *****=====下列按钮根据需要选定使用======*****
|
=====以下为代码清单=====
======OnlineEditTable.html======
<html> <head> <!-- * Title:Table to edit online * Description:Use to table to input data to a form * Copyright:Copyright (c) 2003 * Company:weide * @authorweidegong(weidegong@yahoo.com.cn) * @version3.2 * Function动态可编辑表格构成的表单,其中输入域及其输入形式可根据实际需要自行设置(参考本例Select),IE6测试通过 将script和style定义放在页面head区;将如<table></table>区域拷贝至需要使用该表格的位置即可;最下方为参考按钮 为了能在同一Form中使用多个表格,故将<table>放在form中,而不是将<TBODY>放在form中,这样导致提交的输入域的第一个值无效,如在JSP中:String strxs[]=request.getParameterValues("x");//则strxs[0]即为无效数据thead.tr.th:定义表头,可以设置相应的列宽;th的数目需要同下面的td数目相同,以一一对应;其中"X"是固定列 thead.tr.td.<input ... name=x>设置相应数据列对应的输入域的名字;其中第一列用于显示一个选择框 tableData,默认<TR>的样式单名称;tableDataHit,高亮度显示时<TR>采用的样式单 inputTableData,显示数据时表格中input输入域使用的样式单;inputTableDataHit,TR高亮度显示时,input使用的样式单 * @History1.0 从网上下载了例子,并略作修改 2.0 使用CSS表单美化界面;增加一个模拟可编辑Select下拉框 3.0 将addRow,deleteRow修改为带有对象类型参数的函数,使得在同一界面可使用可编辑表格的多个实例 3.1 将addRow,deleteRow函数的参数修改为表格对象,更加方便;整理出onlineEditTable.css、onlineEditTable.js 3.2 (2003-03-27)增加键盘导航功能,使用方向键或回车键均可 --><meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <LINK href="onlineEditTable.css" type=text/css rel=stylesheet> <script language="javascript" src="onlineEditTable.js"></script> </head> <body><select id=qswh size=6 style="position:absolute;display:none" onblur="this.style.display='none'" onchange="setInputFromSelect(inputFocus,this)"> <option value="1">中国</option> <option value="2">美国</option> <option value="3">英国</option> </select><form name=frmTableOnlineEdit action="showPara.htm"> <TABLE bgColor=silver border=2 borderColorDark=gray borderColorLight=silver cellPadding=2 cellSpacing=1 cols=1 id=tableOnlineEdit rules=rows width="100%" onKeyDown="navigateKeys()" onKeyUp="setKeyDown(false)"> <thead><tr bgColor=#0a6846> <th class=thData width=1%><input type=checkbox id=checkLineAll onclick=setOnlineEditCheckBox(getUpperObj(this,"TABLE"),this.checked)></th><!--Fixed--> <th class=thData width=30%>标题一</th> <th class=thData width=30%>标题二</th> <th class=thData width=39%>标题三</th> <!--<th....................标题N...可定义多个--> </tr><TR style="display:none" bgColor=#e0e0e0 class=tableData onclick=lightonRow(this)> <TD class=scheduleButtonVisible ><input type=checkbox id=checkLine></td><!--Fixed--> <TD><input class=inputTableData name=x onclick=showInputSelect(this,qswh) onblur=hideInput(qswh)></TD> <TD><input class=inputTableData name=y></TD> <TD><input class=inputTableData name=z></TD> <!--<TD><input...........name=...></TD>....可定义多个,与上面的<th>数目保持一致...--> </TR></thead> <tbody> </tbody></TABLE> </form> <p align=center><font size="1">注:第一列单击弹出下拉框选择;在表格最后一行,按下“下箭头”可以增加一个新的空行;使用回车键可以向下遍历整个表格</p> <p align=center><font size="2">*****=====下列按钮根据需要选定使用======*****</font></p><p align=center> <input type=button onclick="addRow(tableOnlineEdit)" value="添加空数据行"> <input type=button onclick="addInstanceRow(tableOnlineEdit,['x','y','z'],['1','100','这是一个测试的例子'])" value="添加实例数据行"> <input type=button onclick="deleteRow(tableOnlineEdit)" value="删除"> <input type=button onclick="clearRow(tableOnlineEdit)" value="删除全部"> <input type=button onclick="frmTableOnlineEdit.submit()" value="submit Form"> <input type=button onclick="frmTableOnlineEdit.reset()" value="Reset"> </p>
============================另一个实例================================= <form action="showPara.htm"> <TABLE bgColor=silver border=2 borderColorDark=gray borderColorLight=silver cellPadding=2 cellSpacing=1 cols=1 id=tableResource rules=rows width="100%" onKeyDown="navigateKeys()" onKeyUp="setKeyDown(false)"> <thead><tr bgColor=#0a6846> <th class=thData width=1%><input type=checkbox id=checkLineAll onclick=setOnlineEditCheckBox(getUpperObj(this,"TABLE"),this.checked)></th><!--Fixed--> <th class=thData width=30%>标题一</th> <th class=thData width=30%>标题二</th> <th class=thData width=39%>标题三</th> <!--<th....................标题N...可定义多个--> </tr><TR style="display:none" bgColor=#e0e0e0 class=tableData onclick=lightonRow(this)> <TD class=scheduleButtonVisible ><input type=checkbox id=checkLine></td><!--Fixed--> <TD><input class=inputTableData name=x onclick=showInputSelect(this,qswh) onblur=hideInput(qswh)></TD> <TD><input class=inputTableData name=y></TD> <TD><input class=inputTableData name=z></TD> <!--<TD><input...........name=...></TD>....可定义多个,与上面的<th>数目保持一致...--> </TR></thead> <tbody> </tbody></TABLE> </form> <p align=center><font size="2">*****=====下列按钮根据需要选定使用======*****</font></p><p align=center> <input type=button onclick="addRow(tableResource)" value="添加空数据行"> <input type=button onclick="addInstanceRow(tableResource,['x','y','z'],['1','100','这是一个测试的例子'])" value="添加实例数据行"> <input type=button onclick="deleteRow(tableResource)" value="删除"> <input type=button onclick="clearRow(tableResource)" value="删除全部"> <input type=button onclick="setOnlineEditCheckBox(tableResource,true)" value="选中全部"> </p></body> </html> |
======onlineEditTable.js======
//全局变量 var inputFocus;//该变量记录当前焦点的input var bKeyDown=false;//记录键盘被按下的状态,当有键盘按下时其值为truefunction setRowClass(obj,className){ obj.className=className; var oldClass,toClass; if(className=="tableData"){oldClass="inputTableDataHit";toClass="inputTableData";} if(className=="tableDataHit"){oldClass="inputTableData";toClass="inputTableDataHit";} var objsInput=obj.all; for(var i=0;i<objsInput.length;i++) if(objsInput[i].tagName=="INPUT")if(objsInput[i].className==oldClass)objsInput[i].className=toClass; }function lightonRow(obj){ if(obj.tagName!="TR")return;//将所有未被选中的行取消高亮度现实 var tableOnlineEdit=obj.parentElement; while(tableOnlineEdit.tagName!="TABLE")tableOnlineEdit=tableOnlineEdit.parentElement; var objsCheckBox=tableOnlineEdit.all("checkLine"); for(var iCheckBox=1;iCheckBox<objsCheckBox.length;iCheckBox++) if(objsCheckBox[iCheckBox].checked==false) setRowClass(tableOnlineEdit.rows[iCheckBox+1],"tableData");//当前点击行高亮度显示 setRowClass(obj,"tableDataHit"); }//得到obj的上级元素TagName function getUpperObj(obj,TagName){ var strTagName=TagName.toUpperCase(); var objUpper=obj.parentElement; while(objUpper){ if(objUpper.tagName==strTagName) break; objUpper=objUpper.parentElement; } return objUpper; } function getPosition(obj,pos){ var t=eval("obj."+pos); while(obj=obj.offsetParent){ t+=eval("obj."+pos); } return t; } function showInputSelect(obj,objShow){ inputFocus=obj;//记录当前焦点input至全局变量 objShow.style.top =getPosition(obj,"offsetTop")+obj.offsetHeight+2; objShow.style.left=getPosition(obj,"offsetLeft"); objShow.style.width=obj.offsetWidth; objShow.value=obj.value; objShow.style.display="block"; }function setInputFromSelect(objTo,objShow){ objTo.value=objShow.options[objShow.selectedIndex].value; //objShow.style.display="none"; }function hideInput(obj){ obj.style.display="none"; }function clearRow(objTable){ var tbodyOnlineEdit=objTable.getElementsByTagName("TBODY")[0]; for (var i=tbodyOnlineEdit.children.length-1;i>=0;i--) tbodyOnlineEdit.deleteRow(i); }function deleteRow(objTable){ var tbodyOnlineEdit=objTable.getElementsByTagName("TBODY")[0]; for (var i=tbodyOnlineEdit.children.length-1; i>=0 ; i-- ) if (tbodyOnlineEdit.children[i].firstChild.firstChild.checked) tbodyOnlineEdit.deleteRow(i); }function addRow(objTable){ var tbodyOnlineEdit=objTable.getElementsByTagName("TBODY")[0]; vartheadOnlineEdit=objTable.getElementsByTagName("THEAD")[0]; var elm = theadOnlineEdit.lastChild.cloneNode(true); elm.style.display=""; tbodyOnlineEdit.insertBefore(elm); }//将指定数据行的objRow的输入域strName设置为strValue function setInputValue(objRow,strName,strValue){ var objs=objRow.all; for(var i=0;i<objs.length;i++){ if(objs[i].name==strName)objs[i].value=strValue; } }//添加一个实例数据行 function addInstanceRow(objTable,Names,Values){ var tbodyOnlineEdit=objTable.getElementsByTagName("TBODY")[0]; var theadOnlineEdit=objTable.getElementsByTagName("THEAD")[0]; var elm = theadOnlineEdit.lastChild.cloneNode(true) elm.style.display=""; for(var i=0;i<Names.length;i++) setInputValue(elm,Names[i],Values[i]); tbodyOnlineEdit.insertBefore(elm); }//将全部复选框设为指定值 function setOnlineEditCheckBox(obj,value){ var tbodyOnlineEdit=obj.getElementsByTagName("TBODY")[0]; for (var i=tbodyOnlineEdit.children.length-1; i>=0 ; i-- ) tbodyOnlineEdit.children[i].firstChild.firstChild.checked=value; }//为动态表格增加键盘导航功能,要使用该功能请在表格定义中增加事件处理onKeyDown="navigateKeys()" onKeyUp="setKeyDown(false)" //有一点点问题,当按下"->"跳转到下一输入域时,光标显示在第一个字符之后 //建议仍然使用Tab键跳转 function navigateKeys(){ if(bKeyDown) return; bKeyDown=true; var elm=event.srcElement; if(elm.tagName!="INPUT") return;//默认只对INPUT进行导航,可自行设定var objTD=elm.parentElement; var objTR=objTD.parentElement; var objTBODY=objTR.parentElement.parentElement; var objTable=objTBODY.parentElement;var nRow=objTR.rowIndex; var nCell=objTD.cellIndex;var nKeyCode=event.keyCode; switch(nKeyCode){ case 37://<- if(getCursorPosition(elm)>0)return; nCell--; if(nCell==0){ nRow--;//跳转到上一行 nCell=objTR.cells.length-1;//最后一列 } break; case 38://^ nRow--; break; case 39://-> if(getCursorPosition(elm)<elm.value.length)return; nCell++; if(nCell==objTR.cells.length){ nRow++;//跳转到下一行首位置 nCell=1;//第一列 } break; case 40:///|/ nRow++; if(nRow==objTBODY.rows.length){ addRow(objTable);//增加一个空行 nCell=1;//跳转到第一列 } break; case 13://Enter nCell++; if(nCell==objTR.cells.length){ nRow++;//跳转到下一行首位置 nCell=1;//第一列 } if(nRow==objTBODY.rows.length){ addRow(objTable);//增加一个空行 nCell=1;//跳转到第一列 }break; default://do nothing return; } if(nRow<2 || nRow>=objTBODY.rows.length || nCell<1 ||nCell>=objTR.cells.length) return;objTR=objTBODY.rows[nRow]; objTD=objTR.cells[nCell]; var objs=objTD.all; for(var i=0;i<objs.length;i++){ //此处使用ojbs[0],实际使用时可能需要加以修改,或加入其他条件 try{ lightonRow(objTR); objs[i].focus();//setCursorPosition(objs[i],-1); return; }catch(e){ continue; //if error occur,continue to next element } }//end for objs.length }//设置键盘状态,即bKeyDown的值 function setKeyDown(status){ bKeyDown=status; } //得到光标的位置 function getCursorPosition(obj){ var qswh="@#%#^&#*$" obj.focus(); rng=document.selection.createRange(); rng.text=qswh; var nPosition=obj.value.indexOf(qswh) rng.moveStart("character", -qswh.length) rng.text=""; return nPosition; } //设置光标位置 function setCursorPosition(obj,position){ range=obj.createTextRange(); range.collapse(true); range.moveStart('character',position); range.select(); } |
======onlineEditTable.css======
.thData{ BACKGROUND:0a6846; } .tableData { BACKGROUND: white; BORDER-BOTTOM: white 1px dashed; BORDER-LEFT: white 1px dashed; BORDER-RIGHT: white 1px dashed; BORDER-TOP: white 1px dashed; COLOR: black; CURSOR: hand; FONT-FAMILY: verdana,arial,helvetica; FONT-SIZE: 12px } .inputTableData { BACKGROUND: white; BORDER-BOTTOM: white 1px dashed; BORDER-LEFT: white 1px dashed; BORDER-RIGHT: white 1px dashed; BORDER-TOP: white 1px dashed; COLOR: black; CURSOR: hand; FONT-FAMILY: verdana,arial,helvetica; FONT-SIZE: 12px;width:100%; } .tableDataSel { BACKGROUND: #6090d0; BORDER-BOTTOM: #6090d0 1px dashed; BORDER-LEFT: #6090d0 1px dashed; BORDER-RIGHT: #6090d0 1px dashed; BORDER-TOP: #6090d0 1px dashed; COLOR: white; CURSOR: hand; FONT-FAMILY: verdana,arial,helvetica; FONT-SIZE: 12px } .tableDataHit { BACKGROUND: #d0e0ff; BORDER-BOTTOM: #d0e0ff 1px dashed; BORDER-LEFT: #d0e0ff 1px dashed; BORDER-RIGHT: #d0e0ff 1px dashed; BORDER-TOP: #d0e0ff 1px dashed; COLOR: black; CURSOR: hand; FONT-FAMILY: verdana,arial,helvetica; FONT-SIZE: 12px } .inputTableDataHit { BACKGROUND: #d0e0ff; BORDER-BOTTOM: #d0e0ff 1px dashed; BORDER-LEFT: #d0e0ff 1px dashed; BORDER-RIGHT: #d0e0ff 1px dashed; BORDER-TOP: #d0e0ff 1px dashed; COLOR: black; CURSOR: hand; FONT-FAMILY: verdana,arial,helvetica; FONT-SIZE: 12px;width:100% } .tableDataOver { BACKGROUND: #d0e0ff; BORDER-BOTTOM: #d0e0ff 1px dashed; BORDER-LEFT: #d0e0ff 1px dashed; BORDER-RIGHT: #d0e0ff 1px dashed; BORDER-TOP: #d0e0ff 1px dashed; COLOR: black; CURSOR: hand; FONT-FAMILY: verdana,arial,helvetica; FONT-SIZE: 12px } .scheduleButtonVisible { BACKGROUND: silver; BORDER-BOTTOM: gray 1px dashed; BORDER-LEFT: white 1px dashed; BORDER-RIGHT: gray 1px dashed; BORDER-TOP: white 1px dashed; COLOR: black; CURSOR: hand; FONT-FAMILY: webdings; FONT-SIZE: 12px } |