web-dev-qa-db-ja.com

各TRがFORMであるHTMLテーブルを作成します

各行がフォームであるテーブルを作成しようとしています。各入力が異なるテーブル分割にあるようにしたいのですが、たとえば、すべての最初の入力が同じテーブルヘッドに属している必要があります。

私がやろうとしているのは編集可能なグリッドです、多かれ少なかれこれ:

<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バリデーターが言ったこともそうです)。

これを行う良い方法はありますか?

53
vtortola

「編集可能なグリッド」、つまり任意の行をフォームにできる構造のようなテーブルが必要な場合は、TABLEタグのレイアウトを模倣するCSSを使用します:display:tabledisplay: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>

FORMでTABLE全体をラップする場合の問題は、すべてのフォーム要素が送信時に送信されることです(おそらくそれは望ましいですが、おそらくそうではありません)。このメソッドを使用すると、「行」ごとにフォームを定義し、送信時にそのデータ行のみを送信できます。

TRタグ(またはFORMの周りのTR)を囲むFORMタグの問題は、それが無効なHTMLであるということです。 FORMは通常どおり送信を許可しますが、この時点でDOMは壊れています。注:JavaScriptを使用してFORMまたはTRの子要素を取得してみてください。予期しない結果が生じる可能性があります。

IE7はこれらのCSSテーブルスタイルをサポートしていないことに注意してください。IE8では、「標準」モードにするにはdoctype宣言が必要になります:(この1つまたは同等のものを試してください)

<!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データテーブルを表示する必要がありますタグ。それらのほとんどはそうです。

行グループをdisplay: table-header-grouptable-row-groupおよびtable-footer-groupでそれぞれ別のDIVにラップすることにより、THEAD、TBODY、TFOOTを模倣することもできます。

注:このメソッドでできないことは、colspanだけです。

この図を確認してください: http://jsfiddle.net/ZRQPP/

85
Matthew

これらのすべての行が関連していて、表形式のデータを変更する必要がある場合...単にテーブル全体をフォームにラップして、GETPOSTに変更しないでください(あなたが'GETリクエストが送信できる最大データ量を超えて送信することはありません)。

(もちろん、すべてのデータが同じ場所に送られると仮定しています。)

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

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を指定し、その行の一意の識別子の送信をトリガーできる要素を行に含めました。 submission要素がアクティブになると、新しいフォームが動的に作成および設定されます。次に、jQueryを使用して、渡された行の<td>に含まれるすべての要素のクローンを作成し、そのクローンを動的に作成されたフォームに追加します。最後に、上記のフォームを送信します。

9
b_laoshi

列幅に問​​題があるかもしれませんが、それらを明示的に設定できます。

<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

9
Eli

これらすべての行が関連していて、表形式のデータを変更する必要がある場合...単にテーブル全体をフォームにラップして、GETをPOSTに変更しない限りGETリクエストで送信できるデータの最大量を超えて送信することはできません)。

テーブル全体をフォームにラップすることはできません。各行の一部の入力フィールドがinput type = "file"であり、ファイルが大きくなる可能性があるためです。ユーザーがフォームを送信すると、POST現在の行のフィールドのみが必要です。すべての行のすべてのフィールドが不要で、巨大なファイルが不要なため、フォームの送信が非常に遅くなります。

そこで、誤ったネストを試みました:tr/formとform/tr。ただし、新しい入力をフォームに動的に追加しようとしない場合にのみ機能します。動的に追加された入力は、誤ってネストされたフォームに属さないため、送信されません。 (有効なフォーム/テーブルの動的入力は問題なく送信されます)。

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で機能させるのははるかに困難です。

4
Dmitriy Sintsov

Javascriptを使用してWeb上で厳密に要求できる場合は、テキストボックス、チェックボックスなどをテーブルの各行に配置し、各行配置ボタン(またはクラス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で慣れているように作業できます。

3
Racky

元の質問で提起された問題と同様の問題がありました。テーブル要素としてスタイル設定されたdivに興味があり(それができるとは知らなかった!)、試してみました。ただし、私の解決策は、テーブルをタグでラップしたまま、各入力の名前を変更し、オプションを選択して配列のキーになることでした。

これがテーブルの1行です。キー[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]);
_

これは複雑に聞こえるかもしれませんが、非常に単純であることが判明し、テーブルの組織構造を維持しました。

1
NotQuiteAPro

テーブルはこのためのものではありません。なぜ<div>とCSS?

1
Harmen

ハーメンのdivの提案を2回目にします。または、テーブルをフォームにラップし、javascriptを使用して行フォーカスをキャプチャし、送信前にjavascriptを介してフォームアクションを調整することもできます。

1
Prescott

harmenが述べたように、マークアップにテーブルを使用しないのと同じくらい簡単です。結局のところ、データを表示するのではなく、データを収集しています。

たとえば、ここで質問23を取り上げます。 http://accessible.netscouts-ggmbh.eu/en/developer.html#fb1_22_5

紙の上では、そのままで良い。結果を表示する必要がある場合は、おそらく大丈夫でしょう。
。 1行に1段落、これははるかに簡単です。

0
FelipeAls