一个网站的诞生- MagicDict未来予想図4 [表格的动态增加行和删除行,完整版]

    首先,感谢 路过秋天 开源了他的系统,让园子里的童鞋有了新的研究方向,带动了园子的繁荣,拉动了园子的GDP。

    昨天又花了一整天来做在线单词编辑器,动态表格的增加行和删除行的一些问题,基本算是搞明白了,大致想法还是和昨天一模一样的。这里只是说一些技巧和锦上添花的东西,算不上什么奇技淫巧。DOM这个玩意,真的很有趣,掌握以后可以做很多HTML的工具。

    首先来说说我这个编辑器想要实现的功能:

    1.可以动态在表格后面添加指定格式的行。可以是一行,也可以是多行。

    2.当然也可以在指定行之前插入一行或者多行。

    3.如果插入/添加的多行的话,这些行在删除的时候也必须一并删除。

    4.单行的后面拥有 插入行 和 删除行的按钮。插入什么样的行,也在这里指定。多行的话,这些功能按钮在首行表示。

    5.某些行有特殊意义,必须给予特别的样式。

    6 可以读出所有行的所有输入信息。

功能不算太难,不过,第一次做的朋友可能不是很容易就能完成的。

    首先,插入和追加,都要动态生成控件,不同的是,一个要指定在哪行之前插入,一个则不需要。那么我们将这两个功能写在一个函数里面,参数就是在“某行”之前插入的“某行”。我们将这个函数命名为AddNewRow,参数“某行”RowObj。这里声明一下,RowObj 其实并不是 表格行 对象,而是表格行里面的按钮对象。通过表格行里面的按钮对象,可以获得表格行。追加的时候RowObj为Null。

    其次,我们还要控制动态生成行的类型,我们称这个类型为RowType。如果是追加的时候,我们通过一个ID为ItemType的下拉列表框来选择行的类型。追加的时候,我么则通过每个行的下拉列表框来选择行的类型,这个列表框无需ID。

 

1           function  AddNewRow(RowObj) {
2               var  RowType;
3 
4 
5               if  (RowObj  ==   null ) {
6                  RowType  =  document.getElementById( " ItemType " ).value;
7              }  else  {
8                  RowType  =  RowObj.parentNode.childNodes[ 1 ].value;
9              }  

 

RowObj.parentNode表示按钮的父控件,这里指包含按钮的单元格。RowObj.parentNode.childNodes[1]表示单元格里面的子控件数组。由于按钮和每个行的插入类型下拉框是兄弟,所以可以这样来获得下拉框。

接下来我们生成一个行对象:

 

             var  WordTable  =  document.getElementById( " WordTable " );
            
var  bodies  =  WordTable.tBodies;
            
var  aBody  =  bodies[ 0 ];
            
var  row  =  document.createElement( " tr " );

 

有了行对象后,我们生成行的第一个单元格。我的编辑器,第一个单元格标识了行的名字。同时我们希望将种类为1的行,添加一个样式,就是指定一个类名。

 

 1               var  cellExplain  =  document.createElement( " td " );
 2               switch  (RowType){
 3                   case   " 1 " :
 4                      cellExplain.innerHTML  =   " 解释 " ;
 5                      row.setAttribute( " class " " Word_Start_td " );
 6                       break ;
 7                   case   " 2 " :    
 8                      cellExplain.innerHTML  =   " 例句[日语] " ;
 9                       break ;
10                   case   " 3 " :
11                      cellExplain.innerHTML  =   " 反义词 " ;
12                       break ;
13                   case   " 4 " :
14                      cellExplain.innerHTML  =   " 主题 " ;
15                       break ;
16              }
17              row.appendChild(cellExplain);

 

设定一个单元格里面的内容有关innerHTML(FF中),设定样式也使用setAttribute。最后将这个单元格追加入行中。

使用同样的方法,我们加入第二个单元格,这里将展示合并单元格的代码:

colspan也可以设定

 1               var  str;
 2               var  cellExplainInput;
 3              cellExplainInput  =  document.createElement( " td " );
 4              cellExplainInput.setAttribute( " colspan " " 3 " );
 5               switch  (RowType) {
 6                   case   " 1 " :
 7                      str  =   " <input type='text' style='width: 400px' /> "
 8                       break ;
 9                   case   " 2 " :
10                      str  =   " <input type='text' style='width: 400px' /> "
11                       break ;
12                   case   " 3 " :
13                      str  =   " 假名:<input type='text' style='width: 150px' />&nbsp; "
14                      str  +=   " 汉字:<input type='text' style='width: 145px' /> "
15                       break ;
16                   case   " 4 " :
17                      str  =   " <input type='text' style='width: 400px' /> "
18                       break ;
19              }
20              cellExplainInput.innerHTML  =  str;
21              row.appendChild(cellExplainInput);

 

接下来,我们希望在每行里面,或者是多行的首行里面追加1个插入行按钮,一个下拉列表框内容,一个删除行按钮。

 

 cellExplainInput  =  document.createElement( " td " );
            cellExplainInput.setAttribute(
" colspan " " 2 " );
            cellExplainInput.setAttribute(
" align " " right " );
            str 
=   " <input  class='buttonNormal' type='button' value='插入行' οnclick='AddNewRow(this)'/> "
            str 
+=   " <select id='ItemType'> " ;
            str 
+=   " <option value='1'>解释</option> " ;
            str 
+=   " <option value='2'>例句</option> " ;
            str 
+=   " <option value='3'>反义词</option> " ;
            str 
+=   " <option value='4'>主题</option> " ;
            str 
+=   " </select> " ;
            str 
+=   " <input class='buttonNormal' type='button' value='删除行' οnclick='RemoveRow(this)'/> "
            cellExplainInput.innerHTML 
=  str;
            row.appendChild(cellExplainInput);

请注意,这里的下拉列表框和按钮,是兄弟关系,都在同一个单元格里面。

好了,有了行以后我们可以追加行或者插入行了。

insertBefore没有第二参数,则是追加到最后,有的话则是插入到指定位置之前。

1                   if  (RowObj  ==   null ) {
2                      aBody.insertBefore(row,  null );
3                  }  else  {
4                      aBody.insertBefore(row, RowObj.parentNode.parentNode);
5                  }
6                  RowCount  =  RowCount  +   1 ;

 

最后,我们希望如果是类型为2的行,应该是同时拥有2行 一组的多行类型。

这个也很简单,如果是追加的话,追加了首行后,追加第二行。如果是插入的话,在指定行之前顺序插入第一行后,在插入第二行。

 

                if  (RowObj  ==   null ) {
                    aBody.insertBefore(row, 
null );
                } 
else  {
                    aBody.insertBefore(row, RowObj.parentNode.parentNode);
                }

                
var  row  =  document.createElement( " tr " );
                cellExplain 
=  document.createElement( " td " );
                cellExplain.innerHTML 
=   " 例句[中文] " ;
                row.appendChild(cellExplain);

                cellExplainInput 
=  document.createElement( " td " );
                cellExplainInput.setAttribute(
" colspan " " 3 " );
                str 
=   " <input type='text' style='width: 400px' /> "
                cellExplainInput.innerHTML 
=  str;
                row.appendChild(cellExplainInput);


                cellExplainInput 
=  document.createElement( " td " );
                cellExplainInput.setAttribute(
" colspan " " 2 " );
                str 
=   " &nbsp; "
                cellExplainInput.innerHTML 
=  str;
                row.appendChild(cellExplainInput);

                
if  (RowObj  ==   null ) {
                    aBody.insertBefore(row, 
null );
                } 
else  {
                    aBody.insertBefore(row, RowObj.parentNode.parentNode);
                }

                RowCount 
=  RowCount  +   2 ;

 

 

删除行的代码很简单,先贴出来,再解释。

如果是单行的话,直接删除掉。。。

如果是2行一组的多行,必须同时删除两个行。这个行的认定,我们通过行的第一个单元格内容来判断。

删除的时候先删除第二行,再删除首行。[首行删除了,第二行定位有些麻烦]。

row.nextSibling表示首行的下一行。

         function  RemoveRow(obj) {
            
var  WordTable  =  document.getElementById( " WordTable " );
            
var  bodies  =  WordTable.tBodies;
            
var  aBody  =  bodies[ 0 ];
            
var  row  =  obj.parentNode.parentNode;
            
if  (row.cells[ 0 ].innerHTML  ==   " 例句[日语] " ) {
                aBody.removeChild(row.nextSibling);
                aBody.removeChild(row);
                RowCount 
=  RowCount  -   2 ;
            } 
else  {
                aBody.removeChild(row);
                RowCount 
=  RowCount  -   1 ;
            }
        }

 

获取单元格的数据,就是遍历整个表格,看了代码一下子就理解了。注意,我的表格的前3行是固定的,从第四行开始遍历即可。逐行逐单元的获取每个控件的值,就可以了。。。。

         function  GenerateData() {
            
var  strJSON  =   "" ;
            
var  WordTable  =  document.getElementById( " WordTable " );
            
var  bodies  =  WordTable.tBodies;
            
var  aBody  =  bodies[ 0 ];
                        
            
for  (i  =   3 ; i  <  aBody.rows.length; i ++ ) {
                
switch  (aBody.rows[i].cells[ 0 ].innerHTML) {
                    
case   " 解释 " :
                        strJSON 
+=   " {Type: Explain,Data:  "   +  aBody.rows[i].cells[ 1 ].childNodes[ 0 ].value  +   " } " ;
                        
break ;
                    
case   " 例句[日语] " :
                        strJSON 
+=   " {Type: SentenceJp,Data:  "   +  aBody.rows[i].cells[ 1 ].childNodes[ 0 ].value  +   " } " ;
                        
break ;
                    
case   " 例句[中文] " :
                        strJSON 
+=   " {Type: SentenceCN,Data:  "   +  aBody.rows[i].cells[ 1 ].childNodes[ 0 ].value  +   " } "
                        
break ;
                    
case   " 反义词 " :
                        strJSON 
+=   " {Type: Anti,Kana:  "   +  aBody.rows[i].cells[ 1 ].childNodes[ 1 ].value;
                        strJSON 
+=   " ,Kanji:  "   +  aBody.rows[i].cells[ 1 ].childNodes[ 3 ].value  +   " } " ;
                        
break ;
                    
case   " 主题 " :
                        strJSON 
+=   " {Type: Topic,Data:  "   +  aBody.rows[i].cells[ 1 ].childNodes[ 0 ].value  +   " } "
                        
break ;
                }
                
if  (i  !=  aBody.rows.length  -   1 ) {
                    strJSON 
+=   " , " ;
                }
            }
            document.getElementById(
" strJSON " ).value  =  strJSON;
            alert(strJSON);
        }

 

问题点:动态加载的控件,控件间距无法控制。

这个例子的演示页面:http://www.magicdict.com/Account/WordEditor.aspx

 

 

初始状态的表格 

   各种行插入后的表格

转载于:https://www.cnblogs.com/TextEditor/archive/2011/06/11/2077978.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值