Создайте таблицу HTML, в которой каждый TR является формой - PullRequest
52 голосов
/ 27 октября 2010

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

Я пытаюсь сделать редактируемую сетку , более или менее так:

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

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

Ответы [ 10 ]

85 голосов
/ 24 марта 2013

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

Проблема с обертыванием тега FORM вокруг тега TR (или TR вокруг FORM) заключается в том, что это недопустимый HTML. ФОРМА будет по-прежнему разрешать отправку как обычно, но на этом этапе 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/

12 голосов
/ 27 октября 2010

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

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

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

9 голосов
/ 27 октября 2010

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

<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 голосов
/ 23 августа 2012

Если все эти строки связаны и вам нужно изменить табличные данные ... почему бы просто не обернуть всю таблицу в форму и изменить GET на POST (если вы не знаете, что не собираетесь отправлять больше максимального количества данных, которое может отправить запрос GET).

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

3 голосов
/ 06 марта 2013

Если вы можете использовать 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 это:Он будет превращен в объект jQuery, и вы сможете работать с ним так, как вы привыкли в jQuery.

1 голос
/ 29 октября 2013

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

Вотодин ряд из таблицы.Обратите внимание, что ключ [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]);

Возможно, это звучит запутанно, но оказалось, что это довольно просто, и это сохранило организационную структуру таблицы.

1 голос
/ 27 октября 2010

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

1 голос
/ 27 октября 2010

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

0 голосов
/ 27 октября 2010

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

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

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

...