Создайте таблицу 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 (опция будет заголовками первой строки). Один абзац на строку, это намного проще.