Is the following valid HTML? What I am wondering about specifically is the location of the <form> tag.
<table>
<form>
<tr>
<td>
<input id="txt" type="text"></input>
</td>
<td>
<input id="txt" type="text"></input>
</td>
<td>
<input type="submit"></input>
</td>
</tr>
</form>
</table>
I recomment using the w3c validator http://validator.w3.org/. And no its not valid :-)
It's not valid. I'm guessing you want to remove the default padding of the form element. This is better done through CSS:
form {
padding:0;
margin:0;
}
or
<form style="padding:0;margin:0;">
Your approach used to be very common to remove the default form padding (before CSS became popular). Now you should put the form tags outside the table. Preferrably you shouldn't even use a table here, but that's not the question, so I'll let it slide. ;)
No this is not valid, TABLE can only contain TBODY, THEAD, TFOOT, CAPTION, COL, COLGROUP. If you are using XHTML then you can also put tr inside the table.
No. see: http://www.w3.org/TR/html4/struct/tables.html#edef-TABLE
<!ELEMENT TABLE - -
(CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)>
The <form> element can appear in all places where you can have block content. So <form> can go in <body>,<blockquote>,<noscript> (oddly enough also in <map>). Because block can also go in flow, it may also appear in <div>,<ins>,<del>,<dd>,<li>,<td>,<th>
It's not proper HTML, but it's sometimes done to lose the empty lines.
Related
Let's assume I have the following structure
<table>
<tr>
<td>
<input type="text" name="name" />
</td>
<td>
<input type="submit" name="submit" />
</td>
</tr>
...
</table>
I need to have forms in each row, but because my inputs are in other <td> elements, I don't know how to place the <form> element (of course I can use colspan="2" and put the form into it, but I need to have two other <td> elements).
How can I solve this?
UPDATE: I don't want to use Javascript to solve this problem :)
Just place the tags around the table:
<form action="...">
<table>
...
</table>
</form>
This form will "handle" all the input fields inside the table.
The best solution: Use divs instead of tables.
Other solution, create a separate table for each row. That way, you can put each table in a separate form and put the input fields in the td-s, so they will be inside the form too.
You can make a table, and in the table cells, create a form, and in the form, create another table:
<table>
<tr><td>
<form>
<table>
<tr><td>
....
</tr></td>
</table>
</form>
</tr></td>
</table>
I am pretty sure it is not possible to mix and match inputs in a form if the forms don't follow each other sequentially i.e. "assign" an input to a form.
Can I use the <caption> tag inside a form ? If not, why not?
Example:
<form>
<caption>description</caption>
<label>name:</label>
<input />
</form>
Have you actually tried it first?
Answer: no. (Well, you can, but it would break standards).
The <caption> element is used to caption a table, not a form.
Alternative solution:
If you really want to caption forms, simply add a valid element that can be styled with CSS to it, like so:
<form>
<div class="caption">This is my form caption</div>
<input .../>
</form>
Another approach, that would probably be more semantically correct, would be to use a <fieldset> to group your form:
<fieldset>
<legend>This is my form caption</legend>
<form>
<input .../>
</form>
</fieldset>
You are looking for the <legend> tag, perhaps?
No, the caption element pertains specifically to tables. One may argue it's a strange case of omission on part of whoever helped make HTML what it is today, but be it as it may, it cannot be used with forms. Furthermore, there are semantical implications of trying to use caption for a form, since it captions tables and not forms.
The idiomatic way to "caption" or "head" content in HTML, including announcing forms and form content, is to use the heading tags h1, h2 etc. These are generic with regard to what they help announce and you may therefore well precede or nest these within a form element.
In your case you would then have:
<form>
<h1>description</h1>
<label>name:</label>
<input />
</form>
or you could also put the heading element directly preceding the form element:
<h1>description</h1>
<form>
<label>name:</label>
<input />
</form>
I think the former is more semantically applicable, but sometimes certain factors like abilities of CSS, will necessitate use of the latter. Either should be valid, regardless.
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:
<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).
Any good way to do this?
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.
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.
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.
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)
<!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.
Note that you can also mimic THEAD, TBODY, TFOOT by wrapping your row groups in another DIV with display: table-header-group, table-row-group and table-footer-group respectively.
NOTE: The only thing you cannot do with this method is colspan.
Check out this illustration: http://jsfiddle.net/ZRQPP/
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).
(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>
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.
See: 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
If using JavaScript is an option and you want to avoid nesting tables, include jQuery and try the following method.
First, you'll have to give each row a unique id like so:
<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.
<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.
You can use the form attribute id to span a form over multiple elements each using the form attribute with the name of the form as follows:
<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>
If you need form inside tr and inputs in every td, you can add form in td tag, and add attribute 'form' that contains id of form tag to outside inputs.
Something like this:
<tr>
<td>
<form id='f1'>
<input type="text">
</form>
</td>
<td>
<input form='f1' type="text">
</td>
</tr>
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).
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.
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).
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.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:
<!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.
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:
<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:
$("valid HTML string")
$(variableWithValidHtmlString)
It will be turned into jQuery object and you can work with it as you are used to in jQuery.
I second Harmen's div suggestion. Alternatively, you can wrap the table in a form, and use javascript to capture the row focus and adjust the form action via javascript before submit.
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.
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:
<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:
$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.
Tables are not meant for this, why don't you use <div>'s and CSS?
it's as simple as not using a table for markup, as stated by Harmen. You're not displaying data after all, you're collecting data.
I'll take for example the question 23 here: http://accessible.netscouts-ggmbh.eu/en/developer.html#fb1_22_5
On paper, it's good as it is. If you had to display the results, it'd probably be OK.
But you can replace it with ... 4 paragraphs with a label and a select (option's would be the headers of the first line). One paragraph per line, this is far more simple.
Is it valid to have a form tag inside a table tag? Some documentation links would be appreciated.
<form> is valid inside a <td> element. You can check this sort of thing at http://validator.w3.org. Choose "Validate by direct input", then paste the following HTML:
<table>
<tbody>
<tr>
<td><form action="test"><div><input type="text"></div></form></td>
</tr>
</tbody>
</table>
Under "More options", select "Validate document fragment". This allows you to check a HTML snippet without writing an entire page for it. I use it for checking HTML fragments all the time.
References:
The TD element
The FORM element
Putting a form tag inside a table (but outside the rows) was sometimes used to keep the margins of the form to interfere with the layout. It kind of works, but it's invalid code according to the HTML standard.
Use CSS to remove the margin from the form tag instead. Example:
<form ... style="margin:0">
Or preferrably put it in your style sheet.
You can nest a form within a td, its usually fine for most purposes though to wrap a form around a table
<form action="#">
<table>
<thead>
<tr>
<th>list</th>
<th>button</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" required="required"></td>
<td><button type="submit" id="saveRow">Save me</button></td>
</tr>
</tbody>
</table>
</form>
It is valid to put a <form> tag inside a <table> tag.
<table>
<tr>
<td>
<form name="sample" action="test.php">
<div>
<input type="submit" value="submit" >
</div>
</form>
</td>
</tr>
</table>
Editing note: tags wrapped as code so that the content reads as intended, but the answer should specify that while the form is inside the table, it cannot be a direct descendant: it must be a child of a cell.
I've come across a few examples recently that do things like:
<dl>
<dt>Full Name:</dt>
<dd><input type="text" name="fullname"></dd>
<dt>Email Address:</dt>
<dd><input type="text" name="email"></dd>
</dl>
for doing HTML forms. Why is that? What is the advantage over using tables?
I guess it's up to you to determine the semantics, but in my opinion:
Rather than a definition list, form-related properties should be used.
<form>
<label for="fullname">Full Name:</label>
<input type="text" name="fullname" id="fullname">
<label for="email">Email Address:</label>
<input type="text" name="email" id="email">
</form>
The "for" attribute in the <label> tag should reference the "id" attribute of a <input> tag. Note that when labels are associated with fields, clicking the label will put the associated field in focus.
You can also use tags like <fieldset> to cluster sections of a form together and <legend> to caption a fieldset.
I've successfully used the technique outlined in this article several times.
I agree with sjstrutt that you should use form related tags like label and form in you forms, but the HTML outlined in his example, will often lack some code you can use as "hooks" for styling your form with CSS.
As a consequence of this I markup my forms like this:
<form name="LoginForm" action="thispage">
<fieldset>
<legend>Form header</legend>
<ul>
<li>
<label for="UserName">Username: </label>
<input id="UserName" name="UserName" type="text" />
</li>
<li>
<label for="Password">Password: </label>
<input id="Password" name="Password" type="text" />
</li>
</ul>
</fieldset>
<fieldset class="buttons">
<input class="submit" type="submit" value="Login" />
</fieldset>
</form>
This approach leaves me with a comprehensible set of tags, which contains enough hooks to style the forms in a lot of different ways.
This is a subset of the issue of semantics vs formatting. A definition list says what they are, a list of related key/value attributes, but does not say how to display it. A table says more about layout and how to display the data then what the data inside is. It limits how the list can be formatted both by overspecifying the format and by underspecifying what it is.
HTML, historically, has mixed up semantics with formatting. Font tags and tables being the worst examples. The move to CSS for the formatting and the stripping of a lot of the pure formatting tags out of XHTML restores, somewhat, the separation of meaning from formatting. By separating formatting into CSS you can display the same HTML in many different ways reformatting it for a wide browser, a small mobile browser, printing, plain text, etc...
For enlightenment, visit the CSS Zen Garden.
Using dl dt,dd for forms is just another way to structure your forms, along with ul li, div and table. You can always put a label into dt. This way you keep the form specific element label in place.
<form action="/login" method="post">
<dl>
<dt><label for="login">Login</label></dt>
<dd><input type="text" name="login" id="login"/></dd>
<dt><label for="password">Password</label></dt>
<dd><input type="password" name="password" id="password"/></dd>
<dd><input type="submit" value="Add"/></dd>
</dl>
</form>
In this case, labels and inputs are your semantic meaning and they stand on their own.
Imagine you had to read the web page, out load, to a blind person. You wouldn't say "Okay, I have a list of definitions here. The first term is 'name'." Instead, you'd probably say "Okay we have a form here and it looks like the there's a set of fields, the first input is labeled 'name'."
This is why the semantic web is important. It allows the content of the page to represent itself accurately to both humans and technology. For example, there are many browser plugins that help people quickly fill out web forms with their standard information (name, phone number, etc). These rarely work well if inputs don't have associated labels.
Hope that helps.
Definition lists have semantic meaning. They are for listing terms (<dt>) and their associated definitions (<dd>). Therefore in this case a <dl> portrays the semantic meaning of the content more accurately than a table.
Definition lists are almost never used because semantically speaking they rarely show up on the internet.
In your case the correct code has been posted:
<form>
<label for="fullname">Full Name:</label>
<input type="text" name="fullname" id="fullname">
<label for="email">Email Address:</label>
<input type="text" name="email" id="email">
</form>
You are creating a form with inputs and labels for said inputs, you are not setting forth a list of words and defining them.
If you are doing some kind of help section then definition lists would be appropriate, e.g.:
<dl>
<dt>HTML</dt>
<dd>Hypertext Markup Language</dd>
<dt>CSS</dt>
<dd>Cascade Stylesheets</dd>
<dt>PHP</dt>
<dd>Hypertext Preprocessor</dd>
</dl>
Part of the reason for using <dl> for marking up the form is that it is much easier to do fancy CSS layout tricks with a <dl> than a <table>. The other part is that it better reflects the semantics of the form (a list of label/field pairs) than a table would.
Ok, table hate is part of it too.
Sometimes, a definition list simply presents the information in the way that's desired, whilst a table does not. Personally, I would probably not use a definition list for a form, unless it suits the style of the site.
Virtually all forms are tabular. Do you ever see a form that's not tabular? The guidelines I've read suggested using the table tag for tabular presentation and that's exactly what forms, calendars, and spreadsheets are for. And now they're using DD and DT instead of tables? What is the Web coming to?! :)
Table List Data will be like this:
<table>
<tr>
<td class="title">Name: </td>
<td class="text">John Don</td>
</tr>
<tr>
<td class="title">Age: </td>
<td class="text">23</td>
</tr>
<tr>
<td class="title">Gender: </td>
<td class="text">Male</td>
</tr>
<tr>
<td class="title">Day of Birth:</td>
<td class="text">12th May 1986</td>
</tr>
</table>
And you can use DL, DT, DD Tags List Data like this:
<dl>
<dt>Name: </dt>
<dd>John Don</dd>
<dt>Age: </dt>
<dd>23</dd>
<dt>Gender: </dt>
<dd>Male</dd>
<dt>Day of Birth:</dt>
<dd>12th May 1986</dd>
</dl>