主从表-可编辑明细表格代码

来源:互联网 发布:2016茶叶大数据 编辑:程序博客网 时间:2024/05/17 03:52

 项目中因需要用到主从表可编辑表格,原来打算用EXT来实现,但发觉EXT文件实在太大及学习门槛有点高了,所以决定放弃EXT,另在网站转了许久,终于找以下可行代码(感谢作者),此代码可与"我佛山人"的Validator 1.05完美结合:

onlineEditTable.js:

 

//全局变量
var inputFocus;//该变量记录当前焦点的input
var bKeyDown=false;//记录键盘被按下的状态,当有键盘按下时其值为true

function 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];
 
var theadOnlineEdit=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
}

 

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
 * @author  weidegong(weidegong@yahoo.com.cn)
 * @version  3.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使用的样式单
 * @History  1.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=utf8">
<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>
<TR style="display:''" bgColor=#e0e0e0 class=tableData onclick=lightonRow(this)>
 
<TD class=scheduleButtonVisible ><input type=checkbox id=checkLine value="12"></td><!--Fixed-->
 
<TD><input class=inputTableData name=x onclick=showInputSelect(this,qswh) onblur=hideInput(qswh) value="34"></TD>
 
<TD><input class=inputTableData name=y value="56"></TD>
 
<TD><input class=inputTableData name=z value="789"></TD>
 
<!--<TD><input...........name=...></TD>....可定义多个,与上面的<th>数目保持一致...-->
</TR>
<TR style="display:''" bgColor=#e0e0e0 class=tableData onclick=lightonRow(this)>
 
<TD class=scheduleButtonVisible ><input type=checkbox id=checkLine value="as"></td><!--Fixed-->
 
<TD><input class=inputTableData name=x onclick=showInputSelect(this,qswh) onblur=hideInput(qswh) value="df"></TD>
 
<TD><input class=inputTableData name=y value="er"></TD>
 
<TD><input class=inputTableData name=z value="htg"></TD>
 
<!--<TD><input...........name=...></TD>....可定义多个,与上面的<th>数目保持一致...-->
</TR>
<TR style="display:''" bgColor=#e0e0e0 class=tableData onclick=lightonRow(this)>
 
<TD class=scheduleButtonVisible ><input type=checkbox id=checkLine value="!@"></td><!--Fixed-->
 
<TD><input class=inputTableData name=x onclick=showInputSelect(this,qswh) onblur=hideInput(qswh) value="^$"></TD>
 
<TD><input class=inputTableData name=y value="@#"></TD>
 
<TD><input class=inputTableData name=z value="$#"></TD>
 
<!--<TD><input...........name=...></TD>....可定义多个,与上面的<th>数目保持一致...-->
</TR>
</tbody>

</TABLE>

</form>
<align=center><font size="1">注:第一列单击弹出下拉框选择;在表格最后一行,按下“下箭头”可以增加一个新的空行;使用回车键可以向下遍历整个表格</p>
<align=center><font size="2">*****=====下列按钮根据需要选定使用======*****</font></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>
<align=center><font size="2">*****=====下列按钮根据需要选定使用======*****</font></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>

 

 

原创粉丝点击