Создайте таблицу HTML, где каждый TR является FORM

Я пытаюсь создать таблицу, где каждая строка является формой. Я хочу, чтобы каждый вход находился в другом делении таблицы, но мне все еще нужно, чтобы, например, все первые входы принадлежали одной и той же головке таблицы и т.д.

То, что я пытаюсь сделать, - это редактируемая сетка, более или менее:

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

Любой хороший способ сделать это?

Ответ 1

Если вам нужна "редактируемая сетка", т.е. такая таблица, как структура, которая позволяет вам сделать любую из строк формой, используйте CSS, который имитирует макет тега TABLE: 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>

Проблема с упаковкой всего TABLE в FORM заключается в том, что любые элементы формы будут отправляться на submit (возможно, это желательно, но, вероятно, нет). Этот метод позволяет вам определить форму для каждой "строки" и отправить только эту строку данных для отправки.

Проблема с упаковкой тега FORM вокруг тега TR (или TR вокруг FORM) заключается в том, что он недействителен HTML. FORM по-прежнему будет предоставлять как обычно, но в этот момент DOM нарушается. Примечание. Попробуйте получить дочерние элементы вашего FORM или TR с помощью JavaScript, это может привести к неожиданным результатам.

Обратите внимание, что IE7 не поддерживает эти стили таблиц CSS, а для IE8 требуется объявление doctype, чтобы перейти в режим "стандартов": (попробуйте это или что-то подобное)

<!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. Большинство из них делают.

Обратите внимание, что вы также можете имитировать THEAD, TBODY, TFOOT, обернув группы строк в другой DIV с помощью display: table-header-group, table-row-group и table-footer-group соответственно.

ПРИМЕЧАНИЕ. Единственное, что вы не можете сделать с этим методом, это colspan.

Посмотрите эту иллюстрацию: http://jsfiddle.net/ZRQPP/

Ответ 2

Если все эти строки связаны друг с другом, и вам нужно изменить табличные данные... почему бы просто не обернуть всю таблицу в форме и изменить 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>

Ответ 3

У вас могут быть проблемы с шириной столбца, но вы можете установить их явно.

<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

Если использование 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> 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 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>

Итак, что мы здесь сделали? Мы дали каждой строке уникальный идентификатор и включили элемент в строку, которая может инициировать отправку уникального идентификатора этой строки. Когда элемент отправки активирован, новая форма динамически создается и настраивается. Затем, используя jQuery, мы клонируем все элементы, содержащиеся в <td> строки, которую мы передали, и добавим клоны в нашу динамически созданную форму. Наконец, мы представляем указанную форму.

Ответ 5

Если все эти строки связаны между собой, и вам нужно изменить табличные данные... почему бы просто не обернуть всю таблицу в форму и не изменить 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] на форму [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

Если вы можете использовать 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.

Ответ 7

Таблицы не предназначены для этого, почему бы вам не использовать <div> и CSS?

Ответ 8

Второе предложение Harmen div. Кроме того, вы можете обернуть таблицу в форме и использовать javascript для захвата фокуса строки и настройки действия формы с помощью javascript перед отправкой.

Ответ 9

У меня была проблема, аналогичная проблеме, заданной в исходном вопросе. Я был заинтригован девами, стилизованными как элементы таблицы (не знал, что вы можете это сделать!) И дал ему бег. Тем не менее, мое решение состояло в том, чтобы мои таблицы были обернуты тегами, но переименовывали каждый вход и выбирали опцию, чтобы стать ключами массива, которые я теперь разбираю, чтобы получить каждый элемент в выбранной строке.

Вот одна строка из таблицы. Обратите внимание, что клавиша [4] - это визуализированный идентификатор строки в базе данных, из которой была получена эта таблица:

<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

это так же просто, как не использовать таблицу для разметки, как указано Harmen. В конце концов, вы не показываете данные, вы собираете данные.

Я возьму, например, вопрос 23 здесь: http://accessible.netscouts-ggmbh.eu/en/developer.html#fb1_22_5

На бумаге это хорошо, как есть. Если вам нужно было отобразить результаты, это, вероятно, будет ОК.
Но вы можете заменить его на... 4 абзаца с меткой и select (опция будет заголовками первой строки). Один абзац на строку, это намного проще.