É válido ter um formulário html dentro de outro formulário html?

331

É html válido ter o seguinte:

<form action="a">
    <input.../>
    <form action="b">
        <input.../>
        <input.../>
        <input.../>
    </form>
    <input.../>
</form>

Portanto, quando você envia "b", você obtém apenas os campos no formulário interno. Quando você envia "a", obtém todos os campos menos aqueles dentro de "b".

Se não for possível, quais soluções alternativas estão disponíveis?

allyourcode
fonte
28
Parece-me que essa é realmente uma necessidade muito comum das interfaces db - se um formulário atualiza a tabela A e essa tabela possui um campo vinculado à tabela B, geralmente queremos uma maneira de atualizar ou criar entradas para essa interface. campo vinculado sem precisar sair do formulário atual. Sub-formulários aninhados seriam uma maneira muito intuitiva de fazer isso (e é a interface do usuário implementada por vários bancos de dados da área de trabalho).
214122 monotaker
3
Isso não é válido. Existem soluções alternativas, mas você deve usar outro método para obter esses dados. Considere um formulário enviando todos os dados para um script de correio PHP, que envia parte (a parte de a) como um email e parte (a parte de b) como outro email. Ou em um banco de dados, ou o que você estiver fazendo com esses dados. Formulários de aninhamento podem ser feitos, mas NÃO é a resposta!
2
possível duplicado de Você pode aninhar formulários html?
User
A pergunta é boa, mas uma rápida pesquisa no Google (sem clicar nos links fornecidos) revela se os formulários nos formulários são válidos ou não. Eu, pessoalmente, gostei da resposta do @Andreas.
Jarett Lloyd

Respostas:

380

A. Não é HTML válido nem XHTML

Na especificação oficial W3C XHTML, a Seção B. "Proibições de elementos" afirma que:

"form must not contain other form elements."

http://www.w3.org/TR/xhtml1/#prohibitions

Quanto à especificação mais antiga do HTML 3.2 , a seção no elemento FORMS declara que:

"Todos os formulários devem ser colocados dentro de um elemento FORM. Pode haver vários formulários em um único documento, mas o elemento FORM não pode ser aninhado."

B. A solução alternativa

Existem soluções alternativas usando JavaScript sem a necessidade de aninhar tags de formulário.

"Como criar um formulário aninhado." (apesar do título, não são tags de formulário aninhadas, mas uma solução alternativa para JavaScript).

Respostas a esta pergunta do StackOverflow

Nota: Embora se possa enganar os Validadores do W3C para passar uma página manipulando o DOM via script, ainda não é HTML legal. O problema com o uso dessas abordagens é que o comportamento do seu código agora não é garantido nos navegadores. (já que não é padrão)

GeneQ
fonte
4
Veja meu comentário acima ... Esta é uma resposta maravilhosa, ótima solução alternativa, mas uma prática terrível. Você pode fazer exatamente a mesma coisa com menos problemas, enviando todos os dados para um script PHP e dividindo e enviando para seus próprios destinos a partir daí. Embora você tenha respondido à pergunta que é ótima, é apenas uma prática ruim e sem sentido, porque você pode fazê-lo da maneira certa em menos tempo.
53

Caso alguém encontre este post aqui, é uma ótima solução sem a necessidade de JS. Use dois botões de envio com atributos de nome diferentes, verifique no idioma do servidor qual botão de envio foi pressionado, pois apenas um deles será enviado ao servidor.

<form method="post" action="ServerFileToExecute.php">
    <input type="submit" name="save" value="Click here to save" />
    <input type="submit" name="delete" value="Click here to delete" />
</form>

O lado do servidor pode ser algo assim se você usar php:

<?php
    if(isset($_POST['save']))
        echo "Stored!";
    else if(isset($_POST['delete']))
        echo "Deleted!";
    else
        echo "Action is missing!";
?>
Andreas
fonte
Não é o mesmo, neste caso, você deseja ir para a mesma página e executar ações diferentes. Com 2 formulários, você pode ir para páginas diferentes E / OU ter informações diferentes enviadas em cada caso.
Luis Tellez
Você pode usar um arquivo php como wrapper e incluir qualquer arquivo que desejar, se desejar o código em arquivos diferentes. Então, ao invés de (echo "! Armazenadas";) você pode escrever (incluem "a.php";)
Andreas
Eu tenho vários botões de exclusão no meu formulário (o motivo pelo qual eu vim aqui considerando um formulário aninhado) 1 para cada registro e uma caixa de seleção de lista em cada um para fazer uma exclusão em massa. Sua resposta me levou a repensar meu plano; estou pensando agora que devo nomear os botões da exclusão individual com um ID numérico e a exclusão em massa como essa. Vou fazer o php fazer a classificação.
Chris
@ Andreas está no dinheiro. Essa é a solução natural para variar como a entrada do formulário é interpretada. Se você usar Post / Redirect / Get, o destino também poderá variar. No entanto, se você não tiver flexibilidade no lado do servidor para combinar suas ações em um único ponto de extremidade 'aORb', acho que você está preso a um hack.
27

O HTML 4.x e o HTML5 não permitem formulários aninhados, mas o HTML5 permitirá uma solução alternativa com o atributo "formulário" ("proprietário do formulário").

Quanto ao HTML 4.x, você pode:

  1. Use um formulário extra com apenas campos ocultos e JavaScript para definir suas entradas e enviar o formulário.
  2. Use CSS para alinhar vários formulários HTML para se parecer com uma única entidade - mas acho que é muito difícil.
Nishi
fonte
1
Não sei por que isso foi rejeitado. Aqui está o link para a seção W3C de proprietários de formulários: w3.org/TR/html5/…
SooDesuNe
5
@SooDesuNe seu link está desatualizado, aqui está o novo w3.org/TR/html5/forms.html#form-owner
chiliNUT
13

Como outros já disseram, não é um HTML válido.

Parece que você está fazendo isso para posicionar os formulários visualmente um dentro do outro. Se for esse o caso, basta fazer dois formulários separados e usar CSS para posicioná-los.

user64075
fonte
1
Era isso que eu pensava que seria necessário para o meu site, mas adoraria um exemplo de como fazer isso.
Brian Peterson
8

Não, a especificação HTML afirma que nenhum FORMelemento deve conter outro FORMelemento.

David Grant
fonte
5

Você pode responder sua própria pergunta com muita facilidade inserindo o código HTML no W3 Validator . (Possui um campo de entrada de texto, você nem precisará colocar seu código em um servidor ...)

(E não, não será validado.)

Christian Studer
fonte
5

em vez disso, use um método javascript personalizado dentro do atributo action do formulário!

por exemplo

<html>
    <head>
        <script language="javascript" type="text/javascript">
        var input1 = null;
        var input2 = null;
        function InitInputs() {
            if (input1 == null) {
                input1 = document.getElementById("input1");
            }
            if (input2 == null) {
                input2 = document.getElementById("input2");
            }

            if (input1 == null) {
                alert("input1 missing");
            }
            if (input2 == null) {
                alert("input2 missing");
            }
        }
        function myMethod1() {
            InitInputs();
            alert(input1.value + " " + input2.value);
        }
        function myMethod2() {
            InitInputs();
            alert(input1.value);
        }
        </script>
    </head>
    <body>
        <form action="javascript:myMethod1();">
            <input id="input1" type="text" />
            <input id="input2" type="text" />
            <input type="button" onclick="myMethod2()" value="myMethod2"/>
            <input type="submit" value="myMethod1" />
        </form>
    </body>
</html>
Andreas Niedermair
fonte
5

Uma possibilidade é ter um iframe dentro da forma externa. O iframe contém a forma interna. Certifique-se de usar a <base target="_parent" />tag dentro da tag head do iframe para fazer com que o formulário se comporte como parte da página principal.

Robin Manoli
fonte
1

Não, não é válido. Mas uma "solução" pode estar criando uma janela modal fora do formulário "a" que contém o formulário "b".

<div id="myModalFormB" class="modal">
    <form action="b">
        <input.../>
        <input.../>
        <input.../>
        <button type="submit">Save</button>
    </form>
</div>

<form action="a">
    <input.../>
    <a href="#myModalFormB">Open modal b </a>
    <input.../>
</form>

Isso pode ser feito facilmente se você estiver usando o bootstrap ou materializar o css. Estou fazendo isso para evitar o uso de iframe.

Jonathas Hortense
fonte
0

Uma solução alternativa não JavaScript para aninhar tags de formulário:

Porque você permite

todos os campos menos aqueles dentro de "b".

ao enviar "a", o seguinte funcionaria, usando formulários da Web regulares sem truques sofisticados de JavaScript:

Etapa 1. Coloque cada formulário em sua própria página da web.

Etapa 2. Insira um iframe onde quiser que esse sub-formulário apareça.

Etapa 3. Lucro.

Tentei usar um site de playground de código para mostrar uma demonstração, mas muitos deles proíbem incorporar seus sites em iframes, mesmo dentro de seu próprio domínio.

ADJenks
fonte
-1

Se você precisar que seu formulário envie / confirme dados em um banco de dados relacional 1: M, eu recomendaria a criação de um acionador de banco de dados "após inserção" na tabela A que inserirá os dados necessários para a tabela B.

cbWrites
fonte
-2

Não, não é válido, mas você pode enganar sua posição interna no formulário HTMLcom a ajuda CSSe o jQueryuso. Primeiro, crie alguma div de contêiner dentro do formulário pai e, em qualquer outro lugar da página, a div com o formulário filho (interno):

<form action="a">
    <input.../>
    <div class="row" id="other_form_container"></div>
    <input.../>
</form>

....

<div class="row" id="other_form">
    <form action="b">
        <input.../>
        <input.../>
        <input.../>
    </form>
</div>

Dê ao seu container div um peso estável

<style>
  #other_form_container {
    height:90px;
    position:relative;
  }
</style> 

Obrigado enganar a posição "other_form" em relação ao container div.

<script>
  $(document).ready(function() {
    var pos = $("#other_form_container").position();
    $("#other_form").css({
      position: "absolute",
      top: pos.top - 40,
      left: pos.left + 7,
      width: 500,
    }).show();
  });
</script>

PS: Você terá que jogar com números para torná-lo bonito.

Yaroslav Varkhol
fonte