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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4035966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 05:00:01  来源:igfitidea点击:

Create a HTML table where each TR is a FORM

htmlwebformshtml-tableweb-standards

提问by vtortola

I'm trying to create a table where each row is a form. I want that each input is in a different table division, but I still need that for example, all first inputs belong to the same table head and so on.

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

What I'm trying to do is an editable grid, more or less this:

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

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

But apparently I cannot arrange the tags in that way (or so is what the w3c validator said).

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

Any good way to do this?

有什么好方法可以做到这一点吗?

回答by Matthew

If you want a "editable grid" i.e. a table like structure that allows you to make any of the rows a form, use CSS that mimics the TABLE tag's layout: display:table, display:table-row, and display:table-cell.

如果你想要一个“编辑网格”,即像结构的表格,可以让你做任何行的形式,使用CSS,模仿表标签的布局:display:tabledisplay:table-row,和display:table-cell

There is no need to wrap your whole table in a form and no need to create a separate form and table for each apparent row of your table.

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

Try this instead:

试试这个:

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

The problem with wrapping the whole TABLE in a FORM is that any and all form elements will be sent on submit (maybe that is desired but probably not). This method allows you to define a form for each "row" and send only that row of data on submit.

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

The problem with wrapping a FORM tag around a TR tag (or TR around a FORM) is that it's invalid HTML. The FORM will still allow submit as usual but at this point the DOM is broken. Note: Try getting the child elements of your FORM or TR with JavaScript, it can lead to unexpected results.

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

Note that IE7 doesn't support these CSS table styles and IE8 will need a doctype declaration to get it into "standards" mode: (try this one or something equivalent)

请注意,IE7 不支持这些 CSS 表格样式,并且 IE8 将需要一个 doctype 声明才能使其进入“标准”模式:(试试这个或类似的东西)

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

Any other browser that supports display:table, display:table-row and display:table-cell should display your css data table the same as it would if you were using the TABLE, TR and TD tags. Most of them do.

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

Note that you can also mimic THEAD, TBODY, TFOOT by wrapping your row groups in another DIV with display: table-header-group, table-row-groupand table-footer-grouprespectively.

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

NOTE:The only thing you cannot do with this method is colspan.

注意:您不能使用此方法做的唯一事情是 colspan。

Check out this illustration: http://jsfiddle.net/ZRQPP/

看看这个插图:http: //jsfiddle.net/ZRQPP/

回答by Sean Vieira

If all of these rows are related and you need to alter the tabular data ... why not just wrap the entire table in a form, and change GETto POST(unless you know that you're not going to be sending more than the max amount of data a GETrequest can send).

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

(That's assuming, of course, that all of the data is going to the same place.)

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

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

回答by Eli

You may have issues with column width, but you can set those explicitly.

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

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

You may want to also consider making it a single form, and then using jQuery to select the form elements from the row you want, serialize them, and submit them as the form.

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

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

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

Also, there are a number of very nice grid plugins: 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

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

回答by b_laoshi

If using JavaScript is an option and you want to avoid nesting tables, include jQuery and try the following method.

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

First, you'll have to give each row a unique id like so:

首先,您必须为每一行提供一个唯一的 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>

Then, include the following function in your JavaScript for your page.

然后,在页面的 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>

So what have we done here? We've given each row a unique id and included an element in the row that can trigger the submission of that row's unique identifier. When the submission element is activated, a new form is dynamically created and set up. Then using jQuery, we clone all of the elements contained in <td>'s of the row that we were passed and append the clones to our dynamically created form. Finally, we submit said form.

那么我们在这里做了什么?我们给每一行一个唯一的 id,并在行中包含一个元素,可以触发该行的唯一标识符的提交。当提交元素被激活时,一个新的表单被动态地创建和设置。然后使用 jQuery,我们克隆包含在<td>我们传递的行的 's 中的所有元素,并将克隆附加到我们动态创建的表单中。最后,我们提交上述表格。

回答by Dmitriy Sintsov

If all of these rows are related and you need to alter the tabular data ... why not just wrap the entire table in a form, and change GET to POST (unless you know that you're not going to be sending more than the max amount of data a GET request can send).

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

I cannot wrap the entire table in a form, because some input fields of each row are input type="file" and files may be large. When the user submits the form, I want to POST only fields of current row, not all fields of the all rows which may have unneeded huge files, causing form to submit very slowly.

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

So, I tried incorrect nesting: tr/form and form/tr. However, it works only when one does not try to add new inputs dynamically into the form. Dynamically added inputs will not belong to incorrectly nested form, thus won't get submitted. (valid form/table dynamically inputs are submitted just fine).

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

Nesting div[display:table]/form/div[display:table-row]/div[display:table-cell] produced non-uniform widths of grid columns. I managed to get uniform layout when I replaced div[display:table-row] to form[display:table-row] :

嵌套 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;
}

For the layout to be displayed correctly in IE8:

为了在 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" />

Sample of output:

输出示例:

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

It would be much harder to make this code work in IE6/7, however.

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

回答by Racky

If you can use javascript and strictly require it on your web, you can put textboxes, checkboxes and whatever on each row of your table and at the end of each row place button (or link of class rowSubmit) "save". Without any FORM tag. Form than will be simulated by JS and Ajax like this:

如果您可以使用 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>

What do you think?

你怎么认为?

PS: If you write in jQuery this:

PS:如果你用jQuery写这个:

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

It will be turned into jQuery object and you can work with it as you are used to in jQuery.

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

回答by NotQuiteAPro

I had a problem similar to the one posed in the original question. I was intrigued by the divs styled as table elements (didn't know you could do that!) and gave it a run. However, my solution was to keep my tables wrapped in tags, but rename each input and select option to become the keys of array, which I'm now parsing to get each element in the selected row.

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

Here's a single row from the table. Note that key [4] is the rendered ID of the row in the database from which this table row was retrieved:

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

Then, in PHP, I'm using the following method to store in an array ($SelectedElem) each of the elements in the row corresponding to the submit button. I'm using print_r()just to illustrate:

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

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

Perhaps this sounds convoluted, but it turned out to be quite simple, and it preserved the organizational structure of the table.

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

回答by Дмитро Зозуля

If you need forminside trand inputs in every td, you can add formin tdtag, and add attribute 'form' that contains id of formtag to outside inputs. Something like this:

如果你需要form内部trinputS IN每次td,你可以添加formtd标签,并添加属性“形式”,它包含的IDform标签之外input秒。像这样的东西:

<tr>
  <td>
    <form id='f1'>
      <input type="text">
    </form>
  </td>
  <td>
    <input form='f1' type="text">
  </td>
</tr>

回答by Martlark

You can use the formattribute idto span a form over multiple elements each using the formattribute with the name of the form as follows:

您可以使用该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>

回答by Harmen

Tables are not meant for this, why don't you use <div>'s and CSS?

表格不是为了这个,你为什么不使用<div>'s 和 CSS?