分享

可编辑表格如何添加这个功能

 WindySky 2007-01-20
我想要实现这样的表格编辑输入功能,点击单元格实现可编辑输入内容,点击回车,可以新建一个行,且内容为点击的单元格那一行的全部内容,新建的行同样具有这样的可编辑功能,不知道大家有没有办法实现啊?
我只有可以编辑单元格的方法,点击回车实现换行新建的功能我不会,还望大家都来讨论...
[code]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www./TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5">
<title>Untitled Document</title>
<style type="text/css">
<!--
input {
        font-family: Geneva, Arial, Helvetica, sans-serif;
        font-size: 12px;
        color: #999999;
        background-color: #FFFFE1;
        border: 1px solid #999999;
}
-->
</style>
</head>

<body>
<div id="aa"></div>
<table width="80%"  border="1" bordercolorlight="#CCCCCC" bordercolordark="#FFFFFF" onclick="setEdit(event.srcElement)">
  <tr>
    <td width="20%">a</td>
    <td width="20%">bb</td>
    <td width="20%">asdf</td>
    <td width="20%">eee</td>
    <td width="20%">adsf</td>
  </tr>
  <tr>
    <td>1</td>
    <td>3</td>
    <td>4</td>
    <td>5</td>
    <td>9</td>
  </tr>
  <tr>
    <td>as</td>
    <td>asdfsdfa</td>
    <td>sadfsdaf</td>
    <td>sadfsdfa</td>
    <td>sdafsadf</td>
  </tr>
  <tr>
    <td>sadfsdfa</td>
    <td>asdf</td>
    <td> </td>
    <td>asdfasdf</td>
    <td>asdfasf</td>
  </tr>
  <tr>
    <td>asdfsadf</td>
    <td>asdfsadf</td>
    <td>asdfasdfasd</td>
    <td>ea</td>
    <td>asdfasfd</td>
  </tr>
</table>
</body>
</html>
<script>
oldObj="";
var newNode=document.createElement("input");
newNode.type="text";

function setEdit(click_td){
        var obj;
       
        if(click_td.tagName=="TD"){
                if(oldObj!=""){
                        oldObj.removeChild(eval("tmpText"));
                        if(newNode.vlaue=="") oldObj.innerText=" ";
                        else oldObj.innerText=newNode.value;
                }
               
                obj=click_td;
                oldObj=obj;
                //newNode.width=obj.clientWidth;
                //newNode.height=obj.clientHeight;
                newNode.width=obj.offsetWidth;
                newNode.height=obj.offsetHeight;

                newNode.id="tmpText";
                newNode.value=obj.innerText;
                obj.innerText="";
                obj.appendChild(newNode);
                newNode.focus();

        }
}
</script>


[/code]

[ 本帖由 快乐点心 最后编辑于 2005-12-5 15:06 ]

回车新建的功能有什么办法实现呢?

关注中.................

这个有用,俺们不知道,不过先收藏了,敬请楼主加油.

楼主,要是加一个添加按钮,不就可以了吗????也不一定要响应回车啊

一步一步来,加按钮能实现复制当前行内容新建吗?

[code]
<html>
<head>
<style>
  TR {background-color: white; color: black; font-family: verdana; font-size: 20; font-weight: bold;}
</style>
<body style="font-family: verdana">
<h2>Table Editor</h2>
<br>
<h3>Single click to select a cell, alt-click to select a row</h3>
<br>
<div id=TableContainer>
<table id=TheTable border=1 style="border-collapse: collapse; ">
  <tbody>
     <tr><td>Cell 1,1</td><td>Cell 1,2</td><td>Cell 1,3</td></tr>
     <tr><td>Cell 2,1</td><td>Cell 2,2</td><td>Cell 2,3</td></tr>
     <tr><td>Cell 3,1</td><td>Cell 3,2</td><td>Cell 3,3</td></tr>
  </tbody>
</table>
</div>

<br><br><br>

<input id=ButtonAddRow style="width: 200px;" type=button value="Add Row" onclick="addRow()"><br>
<input id=ButtonRemoveRow style="width: 200px;" type=button value="Remove Row" onclick="removeRow()"><br>
<input id=ButtonAddCell style="width: 200px;" type=button value="Add Cell" onclick="addCell()"><br>
<input id=ButtonRemoveCell style="width: 200px;" type=button value="Remove Cell" onclick="removeCell()"><br>
<input id=ButtonMoveUp style="width: 200px;" type=button value="Move Up" onclick="moveUp()"><br>
<input id=ButtonMoveDown style="width: 200px;" type=button value="Move Down" onclick="moveDown()"><br>
<input id=ButtonMoveLeft style="width: 200px;" type=button value="Move Left" onclick="moveLeft()"><br>
<input id=ButtonMoveRight style="width: 200px;" type=button value="Move Right" onclick="moveRight()"><br>
<input id=ButtonEditContents style="width: 200px;" type=button value="Edit Contents" onclick="editContents();">
<input type=text style="display: none; width: 400px;" id=EditCell><br>
<input id=ButtonEditStyle style="width: 200px;" type=button value="Edit Table Style" onclick="editStyle();">
<input type=text style="display: none; width: 400px;" id=EditStyle><br>
<script>
var lastSelection = null;

ButtonAddRow.setExpression("disabled", "nothingSelected(lastSelection)");
ButtonRemoveRow.setExpression("disabled", "! rowSelected(lastSelection)");
ButtonAddCell.setExpression("disabled", "nothingSelected(lastSelection)");
ButtonRemoveCell.setExpression("disabled", "! cellSelected(lastSelection)");
ButtonMoveUp.setExpression("disabled", "! rowSelected(lastSelection)");
ButtonMoveDown.setExpression("disabled", "! rowSelected(lastSelection)");
ButtonMoveLeft.setExpression("disabled", "! cellSelected(lastSelection)");
ButtonMoveRight.setExpression("disabled", "! cellSelected(lastSelection)");
ButtonEditContents.setExpression("disabled", "(! cellSelected(lastSelection)) || (EditCell.style.display == ‘‘)");
ButtonEditStyle.setExpression("disabled", "(EditStyle.style.display == ‘‘)");
ButtonEditStyle.setExpression("value", "‘Edit ‘ + whatIsSelected(lastSelection) + ‘ Style‘");

function select(element) {
  var e, r, c;
  if (element == null) {
    e = window.event.srcElement;
  } else {
    e = element;
  }
  if ((window.event.altKey) || (e.tagName == "TR")) {
    r = findRow(e);
    if (r != null) {
      if (lastSelection != null) {
        deselectRowOrCell(lastSelection);
      }
      selectRowOrCell(r);
      lastSelection = r;
    }
  } else {
    c = findCell(e);
    if (c != null) {
      if (lastSelection != null) {
        deselectRowOrCell(lastSelection);
      }
      selectRowOrCell(c);
      lastSelection = c;
    }
  }

  window.event.cancelBubble = true;
}

TableContainer.onclick = select;

function cancelSelect() {

  if (window.event.srcElement.tagName != "BODY")
    return;

  if (lastSelection != null) {
    deselectRowOrCell(lastSelection);
    lastSelection = null;
  }
}

document.onclick = cancelSelect;

function findRow(e) {
  if (e.tagName == "TR") {
    return e;
  } else if (e.tagName == "BODY") {
    return null;
  } else {
    return findRow(e.parentElement);
  }
}

function findCell(e) {
  if (e.tagName == "TD") {
    return e;
  } else if (e.tagName == "BODY") {
    return null;
  } else {
    return findCell(e.parentElement);
  }
}

function deselectRowOrCell(r) {
  r.runtimeStyle.backgroundColor = "";
  r.runtimeStyle.color = "";
  //r.runtimeStyle.fontFamily = "Verdana";
}

function selectRowOrCell(r) {
  r.runtimeStyle.backgroundColor = "darkblue";
  r.runtimeStyle.color = "white";
  //r.runtimeStyle.fontFamily = "Verdana";
}

function addRow() {
  var r, p, nr;
  if (lastSelection == null) {
    r = null;
    p = TheTable.children[0];
  } else {
    r = lastSelection;

    if (r.tagName == "TD") {
      r = r.parentElement;
    }

    p = r.parentElement;
  }

  nr = document.createElement("TR");

  p.insertBefore(nr, r);

  select(nr);

  addCell();

  return nr;   
}

function removeRow() {
  var r, p, nr;
  if (lastSelection == null)
    return false;

  r = lastSelection;

  if (r.tagName == "TD") {
    r = r.parentElement;
  }

  p = r.parentElement;

  p.removeChild(r);

  lastSelection = null;

  return r;
}

function addCell() {
  var r, p, c, nc, text;
  if (lastSelection == null)
    return false;

  r = lastSelection;

  if (r.tagName == "TD") {
    r = r.parentElement;
    c = lastSelection;
  } else {
    c = null;
  }

  nc = document.createElement("TD");
  text = document.createTextNode("New Cell");

  nc.insertBefore(text, null);
  r.insertBefore(nc, c);

  select(nc);

  return nc;
}

function removeCell() {
  var c, p, nr;
  if (lastSelection == null)
    return false;

  c = lastSelection;

  if (c.tagName != "TD") {
    return null;
  }

  p = c.parentElement;

  p.removeChild(c);

  lastSelection = null;

  return c;
}

function editContents() {
  var c, p, nr;
  if (lastSelection == null)
    return false;

  c = lastSelection;

  if (c.tagName != "TD") {
    return null;
  }

  EditCell.style.display = "";

  EditCell.value = c.innerHTML;

  c.setExpression("innerHTML", "EditCell.value");

  EditCell.focus();

  EditCell.onblur = unhookContentsExpression;
}

function unhookContentsExpression() {
  lastSelection.removeExpression("innerHTML");
  EditCell.value = ‘‘;
  EditCell.style.display = "none";
}

function editStyle() {
  var c;

  if (lastSelection == null) {
    c = TheTable;
  } else {
    c = lastSelection;
  }
  
  EditStyle.style.display = "";

  EditStyle.value = c.style.cssText;

  c.style.setExpression("cssText", "EditStyle.value");

  EditStyle.focus();

  EditStyle.onblur = unhookStyleExpression;
}

function unhookStyleExpression() {
  var c;

  if (lastSelection == null) {
    c = TheTable;
  } else {
    c = lastSelection;
  }
  c.style.removeExpression("cssText");

  EditStyle.value = ‘‘;
  EditStyle.style.display = "none";
}

function moveUp() {
  var r, p, ls;
  if (lastSelection == null)
    return false;

  r = lastSelection;

  if (r.tagName != "TR") {
    return null;
  }

  if (r.rowIndex == 0)
    return;

  ls = r.previousSibling;

  p = ls.parentElement;

  p.insertBefore(r, ls);

  return r;
}

function moveDown() {
  var r, p, ls;
  if (lastSelection == null)
    return false;

  r = lastSelection;

  if (r.tagName != "TR") {
    return null;
  }

  ls = r.nextSibling;

  if (ls == null)
    return null;

  p = ls.parentElement;

  ls = ls.nextSibling;

  p.insertBefore(r, ls);

  return r;
}

function moveLeft() {
  var c, p, ls;
  if (lastSelection == null)
    return false;

  c = lastSelection;

  if (c.tagName != "TD") {
    return null;
  }

  ls = c.previousSibling;

  if (ls == null)
    return null;

  p = ls.parentElement;

  p.insertBefore(c, ls);

  return c;
}

function moveRight() {
  var c, p, ls;
  if (lastSelection == null)
    return false;

  c = lastSelection;

  if (c.tagName != "TD") {
    return null;
  }

  ls = c.nextSibling;

  if (ls == null)
    return null;

  p = ls.parentElement;

  ls = ls.nextSibling;

  p.insertBefore(c, ls);

  return c;
}

function nothingSelected() {
  return (lastSelection == null);
}

function rowSelected() {
  var c;
  if (lastSelection == null)
    return false;

  c = lastSelection;

  return (c.tagName == "TR")
}

function cellSelected() {
  var c;
  if (lastSelection == null)
    return false;

  c = lastSelection;

  return (c.tagName == "TD")
}

function whatIsSelected() {
  if (lastSelection == null)
    return "Table";
  if (lastSelection.tagName == "TD")
    return "Cell";
  if (lastSelection.tagName == "TR")
    return "Row";
}

</script>
[/code]

楼主的界面好看...但是如何把修改后的表格打印出来呢....数据怎么保存进去呢......
好像如果是这样,你即使改了,查看源代码,表格的数据还是没有改变的,怎么办呢???

打印可以解决的,我通常都是用ie的打印组件去处理的,应该没有问题~
现在就是如何新增一行就是当前编辑单元格的那一行呢?且单元格内容还为当前单元格行内容~

cloneNode
再修改相关属性

能给出个例子吗?呵呵~~

请问7楼的例子可以有保存数据的功能么?

[code]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www./TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5">
<title>Untitled Document</title>
<style type="text/css">
<!--
input {
        font-family: Geneva, Arial, Helvetica, sans-serif;
        font-size: 12px;
        color: #999999;
        background-color: #FFFFE1;
        border: 1px solid #999999;
}
-->
</style>
</head>

<body>
<div id="aa"></div>
<table width="80%"  border="1" bordercolorlight="#CCCCCC" bordercolordark="#FFFFFF"  onclick="setEdit(event)" onkeydown="checkAdd(event)">
<!--传入event对象,兼容firefox-->
  <tr>
    <td width="20%">a</td>
    <td width="20%">bb</td>
    <td width="20%">asdf</td>
    <td width="20%">eee</td>
    <td width="20%">adsf</td>
  </tr>
  <tr>
    <td>1</td>
    <td>3</td>
    <td>4</td>
    <td>5</td>
    <td>9</td>
  </tr>
  <tr>
    <td>as</td>
    <td>asdfsdfa</td>
    <td>sadfsdaf</td>
    <td>sadfsdfa</td>
    <td>sdafsadf</td>
  </tr>
  <tr>
    <td>sadfsdfa</td>
    <td>asdf</td>
    <td> </td>
    <td>asdfasdf</td>
    <td>asdfasf</td>
  </tr>
  <tr>
    <td>asdfsadf</td>
    <td>asdfsadf</td>
    <td>asdfasdfasd</td>
    <td>ea</td>
    <td>asdfasfd</td>
  </tr>
</table>
</body>
</html>
<script language="javascript">
oldObj="";
var newNode=document.createElement("input");
newNode.type="text";

function setEdit(e){
    var click_td = e.srcElement? e.srcElement : e.target;
    //IE 使用srcElement,而firefox之类的用 target
        var obj;
        if(click_td.tagName=="TD"){
                if(oldObj!=""){
            var tobj = document.getElementById(‘tmpText‘);
            //原eval方法在firefox下面失效
                        oldObj.removeChild(tobj);
                        if(newNode.vlaue=="")
              oldObj.innerHTML=" ";
                        else
              oldObj.innerHTML=newNode.value;
                }
               
                obj=click_td;
                oldObj=obj;
                //newNode.width=obj.clientWidth;
                //newNode.height=obj.clientHeight;
                newNode.width=obj.offsetWidth;
                newNode.height=obj.offsetHeight;

                newNode.id="tmpText";
                newNode.value=obj.innerHTML;
                obj.innerHTML="";
                obj.appendChild(newNode);
                newNode.focus();

        }
               click_td = obj = tobj = null;
}
function checkAdd(e){
    if(e && e.keyCode == 13){
    //键值判断
       var obj = e.srcElement? e.srcElement : e.target;
    //取活动元素,正常情况下为input
       var t = obj.parentNode.parentNode;
    //其父结点的父结点为TR标签
   //以下处理跟点击处理一样
                if(oldObj!=""){
            var tobj = document.getElementById(‘tmpText‘);
                        oldObj.removeChild(tobj);
                        if(newNode.vlaue=="")
              oldObj.innerHTML=" ";
                        else
              oldObj.innerHTML=newNode.value;
            oldObj = ‘‘;
                }
   //以下克隆结点,并在当前结点的前面插入
       if(t.tagName && t.tagName == ‘TR‘){
         t2 = t.cloneNode(true);
         t.parentNode.insertBefore(t2,t);
       }
    }
    obj = t = tobj = t2 = null;
   //清空,方便垃圾回收
}
</script>
</body>
</html>
[/code]
兼容IE6 & FF 1.07,Opera7.3下面好像有点问题

[ 本帖由 nameless 最后编辑于 2005-12-7 11:05 ]

引用内容由 快乐点心 发表于 2005-12-7 08:04
打印可以解决的,我通常都是用ie的打印组件去处理的,应该没有问题~
现在就是如何新增一行就是当前编辑单元格的那一行呢?且单元格内容还为当前单元格行内容~

我在页面上加了个打印预览,数据修改时,现在已经是新的数据了...但是修改的后,最后鼠标点的那个TD,预览时和别的不一样,会有边框,也就是那个TEXT的边边......怎么办?

nameless
能不能把你那个JS解释一下呢??
要是添加一行时,数据为空,没有传递原有数据,要改哪里呢?

引用内容由 820612 发表于 2005-12-7 10:37
nameless
能不能把你那个JS解释一下呢??
要是添加一行时,数据为空,没有传递原有数据,要改哪里呢?

加注释了,这个我试过,可以传递原有数据的,克隆的true参数指明了克隆子结点

谢谢大家,人多力量大啊~~
nameless老兄的代码不错~帮我解决了问题,呵呵
zulex老兄也给我们提供了很好的思路和范例
其实,在用web做grid表格的时候,一行一行录入,经常会用到这类方法的,现在没有很好的web控件,能用js做真的很棒!
大家还能不能再继续讨论下去,看还有没有更好的办法,或者把它做成htc封装好,更多的运用了,嘻嘻~~

nameless还能就这个代码提议点问题吗?
不知道能不能稍微改进一些
1.当点中一个单元格,处于可编辑状态,能不能在点这个表格以外的页面时,取消点中的单元格的编辑状态呢?因为打印或者预览的时候,编辑状态的单元格还是一个input。
2.编辑单元格回车新增一行的时候,能不能同时还能保持复制行的刚才的那个单元格的编辑状态呢?
一点小意见,因为主要是考虑一行一行录入的时候方便快捷一些~

[code]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www./TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=big5">
<title>Untitled Document</title>
<style type="text/css">
<!--
input {
        font-family: Geneva, Arial, Helvetica, sans-serif;
        font-size: 12px;
        color: #999999;
        background-color: #FFFFE1;
        border: 1px solid #999999;
}
-->
</style>
</head>

<body>
<div id="aa"></div>
<table width="80%"  border="1" bordercolorlight="#CCCCCC" bordercolordark="#FFFFFF" onclick="setEdit(event)" onkeydown="checkAdd(event)">
  <tr>
    <td width="20%">a</td>
    <td width="20%">bb</td>
    <td width="20%">asdf</td>
    <td width="20%">eee</td>
    <td width="20%">adsf</td>
  </tr>
  <tr>
    <td>1</td>
    <td>3</td>
    <td>4</td>
    <td>5</td>
    <td>9</td>
  </tr>
  <tr>
    <td>as</td>
    <td>asdfsdfa</td>
    <td>sadfsdaf</td>
    <td>sadfsdfa</td>
    <td>sdafsadf</td>
  </tr>
  <tr>
    <td>sadfsdfa</td>
    <td>asdf</td>
    <td> </td>
    <td>asdfasdf</td>
    <td>asdfasf</td>
  </tr>
  <tr>
    <td>asdfsadf</td>
    <td>asdfsadf</td>
    <td>asdfasdfasd</td>
    <td>ea</td>
    <td>asdfasfd</td>
  </tr>
</table>
</body>
</html>
<script language="javascript">
oldObj="";
var newNode=document.createElement("input");
newNode.type="text";
function setEdit(e){
    var click_td = e.srcElement? e.srcElement : (e.target ? e.target : e);
        var obj;
        if(click_td.tagName && click_td.tagName=="TD"){
                if(oldObj!=""){
            var tobj = document.getElementById(‘tmpText‘);
                        oldObj.removeChild(tobj);
                        if(newNode.vlaue=="")
              oldObj.innerHTML=" ";
                        else
              oldObj.innerHTML=newNode.value;
                }
               
                obj=click_td;
                oldObj=obj;
                //newNode.width=obj.clientWidth;
                //newNode.height=obj.clientHeight;
                newNode.width=obj.offsetWidth;
                newNode.height=obj.offsetHeight;

                newNode.id="tmpText";
                newNode.value=obj.innerHTML;
                obj.innerHTML="";
                obj.appendChild(newNode);
                newNode.focus();
        }
    click_td = obj = tobj = null;
}
function checkAdd(e){
    if(e && e.keyCode == 13){
       var obj = e.srcElement? e.srcElement : e.target;
       var t = obj.parentNode.parentNode;
                if(oldObj!=""){
            var tobj = document.getElementById(‘tmpText‘);
                        oldObj.removeChild(tobj);
                        if(newNode.vlaue=="")
              oldObj.innerHTML=" ";
                        else
              oldObj.innerHTML=newNode.value;
            var oldObj2 = oldObj;
            oldObj = ‘‘;
                }
       if(t.tagName && t.tagName == ‘TR‘){
         t2 = t.cloneNode(true);
         t.parentNode.insertBefore(t2,t);
       }
       setEdit(oldObj2);
    }
    obj = t = tobj = t2 = oldObj2 = null;
}
</script>
</body>
</html>
[/code]
这个编辑状态保持好像可以用了,但取消不会,有个想法就是给input加onblur事件
但那样好像又不行,矛盾,期待高手

嗯,nameless老兄,编辑状态是保持了,可是鼠标并没有保持在input编辑框啊,每次还得用鼠标点击一下,才可以保持激活可以输入的,我的意思直接可以保持激活,就用键盘输入就可以了,呵呵,不知道能不能实现啊?
取消激活,我见你第一次发的那个,回车以后就没有编辑状态了,不知道有没有办法了,一起期待高手了~~

表格一演示入口:
[url]www.etaiping.com/download/grid1/examples/index.html[/url]

表格二演示入口:
[url]www.etaiping.com/download/grid2/OnlineEditTable.htm[/url]

表格(JSC)三演示入口:
[url]www.etaiping.com/download/jsc/index.html[/url]


所有代码下载:
[url]www.etaiping.com/download/grid.rar[/url]

本人主要做系统设计,技术非常有限,但对于一个表格控件应有的功能理解如下:

1、点击表头按列重新排序,可以按当前页排序(针对不分页的表格,这样不用交互),也可以全结果集排序,对于有分页的表格要有这个功能

2、带有翻页导航

3、如EXCEL一样前面有计数列

4、支持键操作,上下左右键,回车换行,回车新增一行

5、单元格中可以放控件,不要那种点击后才显原型的控件,直接显示为控件样式
6、直接可以在表格内编辑

7、带有统计行,可以分类统计

8、可动态调整列宽

9、可以显示图片,格式化数据


以上几点我收集的三个表格例子加起来基本可以完成以上所有功能,只是单个使用都不行,是否有高手可以将之改写一下,并共享给大家?

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多