Formulário dentro de uma tabela

239

Estou incluindo alguns formulários dentro de uma tabela HTML para adicionar novas linhas e atualizar as linhas atuais. O problema que estou enfrentando é que, quando inspeciono os formulários nas minhas ferramentas de desenvolvimento, vejo que os elementos do formulário são fechados imediatamente após a abertura (entradas, etc, não são incluídas no formulário).

Dessa forma, o envio de um formulário falha ao incluir os campos.

A linha da tabela e as entradas são as seguintes:

<tr>
    <form method="post" action="">
        <td>
            <input type="text" name="job_num">
        </td>

        <td>
            <input type="text" name="desc">
        </td>
    </form>
</tr>

Qualquer ajuda seria ótimo, obrigado.

Alex
fonte
6
<form>não pode ser colocado dentro <tr>.
Derek朕會功夫
1
E você esqueceu de fechar o <tr>.
Derek朕會功夫
1
Use display: table-row para seu formulário e descarte a tag da tabela completamente. Veja minha resposta aqui: stackoverflow.com/a/15600151/1038812
Matthew
Não pode, mas funciona ...
Sandburg

Respostas:

371

Um formulário não pode ser um elemento filho de a table, tbodyou tr. Tentar colocá-lo lá tenderá a fazer com que o navegador mova o formulário para ele após a tabela (deixando seu conteúdo - linhas da tabela, células da tabela, entradas, etc - para trás).

Você pode ter uma tabela inteira dentro de um formulário. Você pode ter um formulário dentro de uma célula da tabela. Você não pode ter parte de uma tabela dentro de um formulário.

Use um formulário ao redor da tabela inteira. Em seguida, use o botão de envio clicado para determinar qual linha processar (para ser rápida) ou processar todas as linhas (permitindo atualizações em massa).

HTML 5 introduz o form atributo . Isso permite que você fornecer um formulário para cada linha fora da tabela e, em seguida, associar todo o controle de formulário em uma determinada linha com uma dessas formas usando seu id.

Quentin
fonte
2
Tome cuidado ao usar um formulário para toda a tabela; todos os campos serão enviados ao servidor, mesmo que estejam vazios. Poderia ser uma enorme quantidade de dados !!! Por favor, para uso em massa / público, prefira usar uma caixa de diálogo (formulário que não está na tabela) aberta a partir de um botão nessa linha.
Loenix 13/02/16
1
@ Phoenix: É muito improvável que você coloque dados suficientes na tabela para que isso seja um fardo significativo para a largura de banda das pessoas (pelo menos quando comparado ao tamanho de uma página da Web típica). Exigir que os usuários carreguem outra página entre optar por editar uma linha e poder fazer suas alterações, OTOH, seria uma interação extra irritante que eles teriam que executar.
Quentin
1
Você não precisa de um botão de edição para a solução proposta na pergunta original.
Quentin
1
Por que o proibido <form>dentro dos <table>padrões?
1234ru
4
@ Qentin justo o suficiente. É uma pena que isso ainda ocorra após duas décadas sem motivo óbvio.
1234ru
188

Use o atributo "formulário" , se desejar salvar sua marcação:

<form method="GET" id="my_form"></form>

<table>
    <tr>
        <td>
            <input type="text" name="company" form="my_form" />
            <button type="button" form="my_form">ok</button>
        </td>
    </tr>
</table>

(* Campos de formulário fora da tag <form>)

Veja também os 2 primeiros comentários

Vladimir
fonte
64
Observe que esta solução é válida apenas com HTML5.
Threenplusone
18
além disso, ele não funcionará no Internet Explorer mais informações aqui
Souhaieb Besbes
1
O status do atributo do formulário está 'em consideração', o que significa que você deve ser muito paciente developer.microsoft.com/en-us/microsoft-edge/platform/status/… enquanto isso, você pode tentar esse polyfill e verificar se ele funciona para você stackoverflow.com/a/26696165/648484
Souhaieb Besbes
1
Parece "em desenvolvimento" agora e ok para usar #
user1156544
1
@ user1156544 Ele é suportado no Edge agora, mas não no IE. Se você precisa oferecer suporte ao IE, está sem sorte com esta solução. Meu plano é usar duas tabelas para dois elementos de formulário (não acredito que preciso fazer isso). Obrigado Microsoft!
Plutão
41

Se você quer um "grid editável", isto é uma tabela como a estrutura que permite que você faça qualquer uma das linhas de um formulário, use CSS que imita o layout da marca TABLE: display:table, display:table-row, e display:table-cell.

Não é necessário agrupar toda a tabela em um formulário e criar um formulário e tabela separados para cada linha aparente da tabela.

Tente isso:

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

O problema de agrupar toda a tabela em um formulário é que todos e quaisquer elementos do formulário serão enviados no envio (talvez isso seja desejado, mas provavelmente não). Este método permite definir um formulário para cada "linha" e enviar apenas essa linha de dados no envio.

O problema de agrupar uma marca FORM em torno de uma marca TR (ou TR em torno de um FORM) é que ele é HTML inválido. O FORM ainda permitirá o envio como de costume, mas neste momento o DOM está quebrado. Nota: Tente obter os elementos filhos do seu FORM ou TR com JavaScript, pois isso pode levar a resultados inesperados.

Observe que o IE7 não suporta esses estilos de tabela CSS e o IE8 precisará de uma declaração de tipo de documento para colocá-la no modo "padrões": (tente este ou algo equivalente)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Qualquer outro navegador que suporte display: table, display: table-row e display: table-cell deve exibir sua tabela de dados css da mesma forma que faria se você estivesse usando as tags TABLE, TR e TD. A maioria deles faz.

Observe que você também pode imitar THEAD, TBODY, TFOOT envolvendo seus grupos de linhas em outro DIV com display: table-header-group, table-row-groupe table-footer-grouprespectivamente.

NOTA: A única coisa que você não pode fazer com esse método é colspan.

Confira esta ilustração: http://jsfiddle.net/ZRQPP/

Mateus
fonte
4
1 para mencionar este não permite colspan ... o que eu devo ter perdido a primeira leitura através ;-)
Johannes Rudolph
1
Esse deve ser o verde verificado resposta (mesmo que não use tag realmente tabela)
Alessio