代码之家  ›  专栏  ›  技术社区  ›  vtortola

创建一个HTML表,其中每个TR都是一个表单

  •  49
  • vtortola  · 技术社区  · 15 年前

    我试图创建一个表,其中每一行都是一个表单。我希望每个输入都在不同的表分区中,但我仍然需要例如,所有第一个输入都属于同一个表头等等。

    我要做的是一个可编辑的网格 ,或多或少是这样:

    <table>
        <tr>
            <form method="POST" action="whatever">
                <td><input type="text"/></td>
                <td><input type="text"/></td>
            </form>
        </tr>
        <tr>
            <form method="POST" action="whatever">
                <td><input type="text"/></td>
                <td><input type="text"/></td>
            </form>
        </tr>
    </table>
    

    但显然我不能这样安排标签(w3c验证器也这么说)。

    有什么好办法吗?

    10 回复  |  直到 6 年前
        1
  •  88
  •   Matthew    12 年前

    如果您想要一个“可编辑的网格”,即一个类似于表的结构,它允许您将任何一行变成一个表单,请使用模拟表标记布局的CSS: display:table , display:table-row display:table-cell .

    不需要将整个表包装成一个窗体,也不需要为表中的每一行创建单独的窗体和表。

    请改为:

    <style>
    DIV.table 
    {
        display:table;
    }
    FORM.tr, DIV.tr
    {
        display:table-row;
    }
    SPAN.td
    {
        display:table-cell;
    }
    </style>
    ...
    <div class="table">
        <form class="tr" method="post" action="blah.html">
            <span class="td"><input type="text"/></span>
            <span class="td"><input type="text"/></span>
        </form>
        <div class="tr">
            <span class="td">(cell data)</span>
            <span class="td">(cell data)</span>
        </div>
        ...
    </div>
    

    将表单标记包装在TR标记周围(或将TR包装在表单周围)的问题是它是无效的HTML。表单仍允许像往常一样提交,但此时DOM已损坏。注意:尝试使用JavaScript获取表单或TR的子元素,可能会导致意外的结果。

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    

    任何其他支持display:table、display:table row和display:table cell的浏览器都应该像使用table、TR和TD标记一样显示css数据表。他们中的大多数都是。

    注意,您还可以通过将行组包装到另一个DIV中来模拟THEAD、TBODY和TFOOT display: table-header-group , table-row-group table-footer-group

    注: 你唯一不能用这种方法做的就是colspan。

    http://jsfiddle.net/ZRQPP/

        2
  •  12
  •   Sean Vieira    15 年前

    如果所有这些行都是相关的,并且需要更改表格数据。。。为什么不把整个表包装成一个表单,然后更改 GET POST (除非你知道你发送的数据不会超过 请求可以发送)。

    (当然,这是假设所有数据都将指向同一个地方。)

    <form method="POST" action="your_action">
    <table>
    <tr>
    <td><input type="text" name="r1c1" value="" /></td>
    <!-- ... snip ... -->
    </tr>
    <!-- ... repeat as needed ... -->
    </table>
    </form>
    
        3
  •  10
  •   Eli    15 年前

    <table>
      <tr>
        <td>
           <form>
             <table>
               <tr>
                 <td></td> 
                 <td></td> 
                 <td></td> 
                 <td></td> 
                 <td></td> 
                 <td></td> 
               </tr>
             </table>
           </form>
         </td>
        </tr>
      <tr>
        <td>
           <form>
             <table>
               <tr>
                 <td></td> 
                 <td></td> 
                 <td></td> 
                 <td></td> 
                 <td></td> 
                 <td></td> 
               </tr>
             </table>
           </form>
         </td>
        </tr>
      </table>
    

    您可能还需要考虑将其设置为单个表单,然后使用jQuery从所需的行中选择表单元素,对它们进行序列化,并将它们作为表单提交。

    见: http://api.jquery.com/serialize/

    此外,还有许多非常不错的网格插件: http://www.google.com/search?q=jquery+grid&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a

        4
  •  10
  •   Nisse Engström sting_roc    9 年前

    如果使用JavaScript是一个选项,并且您希望避免嵌套表,请包含jQuery并尝试以下方法。

    <table>
      <tr id="idrow1"><td> ADD AS MANY COLUMNS AS YOU LIKE  </td><td><button onclick="submitRowAsForm('idrow1')">SUBMIT ROW1</button></td></tr>
      <tr id="idrow2"><td> PUT INPUT FIELDS IN THE COLUMNS  </td><td><button onclick="submitRowAsForm('idrow2')">SUBMIT ROW2</button></td></tr>
      <tr id="idrow3"><td>ADD MORE THAN ONE INPUT PER COLUMN</td><td><button onclick="submitRowAsForm('idrow3')">SUBMIT ROW3</button></td></tr>
    </table>
    

    然后,在页面的JavaScript中包含以下函数。

    <script>
    function submitRowAsForm(idRow) {
      form = document.createElement("form"); // CREATE A NEW FORM TO DUMP ELEMENTS INTO FOR SUBMISSION
      form.method = "post"; // CHOOSE FORM SUBMISSION METHOD, "GET" OR "POST"
      form.action = ""; // TELL THE FORM WHAT PAGE TO SUBMIT TO
      $("#"+idRow+" td").children().each(function() { // GRAB ALL CHILD ELEMENTS OF <TD>'S IN THE ROW IDENTIFIED BY idRow, CLONE THEM, AND DUMP THEM IN OUR FORM
            if(this.type.substring(0,6) == "select") { // JQUERY DOESN'T CLONE <SELECT> ELEMENTS PROPERLY, SO HANDLE THAT
                input = document.createElement("input"); // CREATE AN ELEMENT TO COPY VALUES TO
                input.type = "hidden";
                input.name = this.name; // GIVE ELEMENT SAME NAME AS THE <SELECT>
                input.value = this.value; // ASSIGN THE VALUE FROM THE <SELECT>
                form.appendChild(input);
            } else { // IF IT'S NOT A SELECT ELEMENT, JUST CLONE IT.
                $(this).clone().appendTo(form);
            }
    
        });
      form.submit(); // NOW SUBMIT THE FORM THAT WE'VE JUST CREATED AND POPULATED
    }
    </script>
    

    我们在这里做了什么?我们给每一行一个惟一的id,并在行中包含一个元素,该元素可以触发该行惟一标识符的提交。当submission元素被激活时,将动态创建和设置一个新表单。然后使用jQuery,我们克隆了 <td>

        5
  •  4
  •   Dmitriy Sintsov    13 年前

    如果所有这些行都是相关的,并且需要更改表格数据。。。为什么不将整个表包装成一个表单,并更改GET to POST(除非您知道发送的数据不会超过GET请求可以发送的最大数据量)。

    我不能将整个表包装成一个表单,因为每行的一些输入字段是input type=“file”,并且文件可能很大。当用户提交表单时,我只想发布当前行的字段,而不是所有行的字段,这些字段可能有不需要的大文件,导致表单提交非常慢。

    嵌套div[display:table]/form/div[display:table row]/div[display:table cell]生成的网格列宽度不一致。当我将div[display:table row]替换为form[display:table row]时,我设法获得了统一的布局:

    div.grid {
        display: table;
    }
    
    div.grid > form {
        display: table-row;
    
    
    div.grid > form > div {
        display: table-cell;
    }
    div.grid > form > div.head {
        text-align: center;
        font-weight: 800;
    }
    

    要使布局在IE8中正确显示:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    ...
    <meta http-equiv="X-UA-Compatible" content="IE=8, IE=9, IE=10" />
    

    输出样本:

    <div class="grid" id="htmlrow_grid_item">
    <form>
        <div class="head">Title</div>
        <div class="head">Price</div>
        <div class="head">Description</div>
        <div class="head">Images</div>
        <div class="head">Stock left</div>
        <div class="head">Action</div>
    </form>
    <form action="/index.php" enctype="multipart/form-data" method="post">
        <div title="Title"><input required="required" class="input_varchar" name="add_title" type="text" value="" /></div>
    

    然而,要让这段代码在IE6/7中工作要困难得多。

        6
  •  3
  •   Racky    13 年前

    <script type="text/javascript">
    $(document).ready(function(){
      $(".rowSubmit").click(function()
      {
         var form = '<form><table><tr>' + $(this).closest('tr').html() + '</tr></table></form>';
         var serialized = $(form).serialize(); 
         $.get('url2action', serialized, function(data){
           // ... can be empty
         }); 
       });
    });        
    </script>
    

    你怎么认为?

    PS:如果您在jQuery中写下:

    $("valid HTML string")
    $(variableWithValidHtmlString)
    

        7
  •  1
  •   Harmen    15 年前

    桌子不是用来做这个的,你为什么不用 <div> 和CSS?

        8
  •  1
  •   Prescott    15 年前

    我同意哈门的建议。或者,可以将表包装成表单,并在提交之前使用javascript捕获行焦点并通过javascript调整表单操作。

        9
  •  1
  •   NotQuiteAPro    12 年前

    我有一个问题和原来的问题类似。我很感兴趣的div样式为表元素(不知道你可以这样做!)然后跑了一圈。但是,我的解决方案是将表包装在标记中,但是重命名每个输入并选择option以成为数组的键,我现在正在对其进行解析以获取所选行中的每个元素。

    这是桌子上的一行。请注意,键[4]是从中检索此表行的数据库行的呈现ID:

    <table>
      <tr>
        <td>DisabilityCategory</td>
        <td><input type="text" name="FormElem[4][ElemLabel]" value="Disabilities"></td>
        <td><select name="FormElem[4][Category]">
            <option value="1">General</option>
            <option value="3">Disability</option>
            <option value="4">Injury</option>
            <option value="2"selected>School</option>
            <option value="5">Veteran</option>
            <option value="10">Medical</option>
            <option value="9">Supports</option>
            <option value="7">Residential</option>
            <option value="8">Guardian</option>
            <option value="6">Criminal</option>
            <option value="11">Contacts</option>
          </select></td>
        <td>4</td>
        <td style="text-align:center;"><input type="text" name="FormElem[4][ElemSeq]" value="0" style="width:2.5em; text-align:center;"></td>
        <td>'ccpPartic'</td>
        <td><input type="text" name="FormElem[4][ElemType]" value="checkbox"></td>
        <td><input type="checkbox" name="FormElem[4][ElemRequired]"></td>
        <td><input type="text" name="FormElem[4][ElemLabelPrefix]" value=""></td>
        <td><input type="text" name="FormElem[4][ElemLabelPostfix]" value=""></td>
        <td><input type="text" name="FormElem[4][ElemLabelPosition]" value="before"></td>
        <td><input type="submit" name="submit[4]" value="Commit Changes"></td>
      </tr>
    </table>
    

    print_r() 只是为了说明:

    $SelectedElem = implode(",", array_keys($_POST['submit']));
    print_r ($_POST['FormElem'][$SelectedElem]);
    

    也许这听起来很复杂,但事实证明它非常简单,并且保留了表的组织结构。

        10
  •  1
  •   Ray    6 年前

    如果你需要 form tr input 在每个 td ,您可以添加 形式 在里面 标记,并添加包含 形式 标记到外部 s。 像这样的:

    <tr>
      <td>
        <form id='f1'>
          <input type="text">
        </form>
      </td>
      <td>
        <input form='f1' type="text">
      </td>
    </tr>
    
        11
  •  1
  •   Martlark    6 年前

    form 属性 id 使用 形式 属性,表单名称如下:

    <table>
         <tr>
              <td>
                   <form method="POST" id="form-1" action="/submit/form-1"></form>
                   <input name="a" form="form-1">
              </td>
              <td><input name="b" form="form-1"></td>
              <td><input name="c" form="form-1"></td>
              <td><input type="submit" form="form-1"></td>
         </tr>
    </table>
    
        12
  •  0
  •   FelipeAls    15 年前

    我将以这里的问题23为例: http://accessible.netscouts-ggmbh.eu/en/developer.html#fb1_22_5


    但你可以用。。。带有标签和选择的4个段落(选项将是第一行的标题)。每行一段,这要简单得多。

    推荐文章