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

时间:2010-10-27 17:33:07

标签: html webforms html-table web-standards

我正在尝试创建一个表格,其中每一行都是一个表格。我希望每个输入都在不同的表格中,但我仍然需要这样,例如,所有第一个输入都属于同一个表头,依此类推。

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

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

但显然我无法以这种方式排列标签(或者w3c验证器所说的那样)。

有什么好方法吗?

12 个答案:

答案 0 :(得分:82)

如果你想要一个可编辑的网格&#34;即一个类似于结构的表,允许您将任何行创建为表单,使用模仿TABLE标记布局的CSS:display:tabledisplay:table-rowdisplay:table-cell。< / p>

无需将整个表格包装在表格中,也无需为表格的每个明显行创建单独的表格和表格。

请改为尝试:

<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>

将整个TABLE包装在FORM中的问题是,任何和所有表单元素都将在提交时发送(可能是期望但可能不是)。此方法允许您为每个&#34;行&#34;定义一个表单。并且仅在提交时发送该行数据。

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

请注意,IE7不支持这些CSS表格样式,IE8需要一个doctype声明才能将其纳入&#34;标准&#34;模式:(尝试这个或类似的东西)

<!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应该显示你的css数据表,就像你使用TABLE,TR和TD标签一样。他们中的大多数都这样做。

请注意,您还可以通过将行组分别包含在display: table-header-grouptable-row-grouptable-footer-group的另一个DIV中来模仿THEAD,TBODY,TFOOT。

注意:这个方法唯一不能做的就是colspan。

查看此插图:http://jsfiddle.net/ZRQPP/

答案 1 :(得分:12)

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

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

<form method="POST" action="your_action">
<table>
<tr>
<td><input type="text" name="r1c1" value="" /></td>
<!-- ... snip ... -->
</tr>
<!-- ... repeat as needed ... -->
</table>
</form>

答案 2 :(得分:9)

您可能遇到列宽问题,但可以明确设置。

<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

答案 3 :(得分:9)

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

首先,您必须为每一行提供一个唯一的ID,如下所示:

<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,并在行中包含了一个元素,可以触发该行的唯一标识符的提交。激活提交元素后,将动态创建和设置新表单。然后使用jQuery,我们克隆我们传递的行的<td>中包含的所有元素,并将克隆附加到我们动态创建的表单中。最后,我们提交了表格。

答案 4 :(得分:4)

  

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

我无法将整个表包装在表单中,因为每行的某些输入字段是输入类型=“文件”,文件可能很大。当用户提交表单时,我想只发布当前行的字段,而不是所有行的所有字段,这些字段可能有不需要的大文件,导致表单提交速度非常慢。

所以,我尝试了不正确的嵌套:tr / form和form / tr。但是,只有在没有尝试动态地将新输入添加到表单中时,它才有效。动态添加的输入不属于错误嵌套的表单,因此不会被提交。 (有效的表格/表格动态输入提交得很好)。

嵌套div [display:table] / form / div [display:table-row] / div [display:table-cell]产生非均匀宽度的网格列。当我将div [display:table-row]替换为[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中使这段代码工作要困难得多。

答案 5 :(得分:3)

如果您可以在网络上使用javascript并严格要求它,您可以在表格的每一行和每个行位置按钮(或类rowSubmit的链接)“保存”的末尾放置文本框,复选框等。没有任何FORM标签。表格比JS和Ajax模拟的那样:

<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)

它将变成jQuery对象,您可以像在jQuery中一样使用它。

答案 6 :(得分:2)

您可以使用form属性id将表单跨越多个元素,每个元素都使用form属性,其表单名称如下:

<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>

答案 7 :(得分:1)

表格不适用于此,为什么不使用<div>和CSS?

答案 8 :(得分:1)

我是第二个Harmen的div建议。或者,您可以将表格包装在一个表单中,并使用javascript来捕获行焦点,并在提交之前通过javascript调整表单操作。

答案 9 :(得分:1)

我遇到的问题类似于原始问题中提出的问题。我对被称为表格元素的div感兴趣(不知道你能做到这一点!)并给它一个运行。但是,我的解决方案是将表格保存在标签中,但重命名每个输入并选择选项以成为数组的键,我现在正在解析它以获取所选行中的每个元素。

这是表格中的一行。请注意,key [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>

然后,在PHP中,我使用以下方法将数组($ SelectedElem)存储在与提交按钮对应的行中的每个元素中。我正在使用print_r()来说明:

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

也许这听起来很复杂,但结果很简单,它保留了表格的组织结构。

答案 10 :(得分:0)

就像没有使用表格进行标记一样简单,如Harmen所述。毕竟你没有显示数据,而是收集数据。

我将在此处提出问题23:http://accessible.netscouts-ggmbh.eu/en/developer.html#fb1_22_5

在纸面上,它很好。如果你必须显示结果,它可能没问题。
但你可以用...带有标签和选择的4段代替它(选项是第一行的标题)。每行一个段落,这要简单得多。

答案 11 :(得分:0)

如果您需要在form中的trinput和每个td中的form s,则可以在td标签中添加form,然后添加包含input标记的ID的属性“表单”到外部<tr> <td> <form id='f1'> <input type="text"> </form> </td> <td> <input form='f1' type="text"> </td> </tr> 。 像这样:

range()