zoukankan      html  css  js  c++  java
  • 一个网站的诞生 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=' 400px' />"
     8                     break;
     9                 case "2":
    10                     str = "<input type='text' style=' 400px' />"
    11                     break;
    12                 case "3":
    13                     str = "假名:<input type='text' style=' 150px' />&nbsp;"
    14                     str += "汉字:<input type='text' style=' 145px' />"
    15                     break;
    16                 case "4":
    17                     str = "<input type='text' style=' 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='插入行' onclick='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='删除行' onclick='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=' 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

    初始状态的表格 

       各种行插入后的表格

  • 相关阅读:
    成都磨子桥技工学校 / 数据结构 Challenge 4
    圆桌问题(网络流24题)
    试题库问题(网络流24题)
    [AHOI2005]航线规划
    [AMPPZ2014]The Prices
    方格取数(网络流24题)
    太空飞行计划问题(网络流24题)
    Linux 学习3
    Linux 学习2
    Linux 学习1
  • 原文地址:https://www.cnblogs.com/TextEditor/p/2077978.html
Copyright © 2011-2022 走看看