Você pode aninhar formulários html?

451

É possível aninhar formulários html como este

<form name="mainForm">
  <form name="subForm">
  </form>
</form>

para que ambas as formas funcionem? Meu amigo está tendo problemas com isso, uma parte dos subFormtrabalhos, enquanto outra parte não.

Levi
fonte
Ele está configurando um carrinho, em que a quantidade de atualização está dentro do formulário que controla os totais. Eu pessoalmente não faria isso, mas ele está tendo problemas para fazer com que isso funcione.
Levi
1
Parece que seria melhor usar o Javascript para copiar valores de um formulário para outro, em vez de tentar aninha-los. Eu não acho que o aninhamento funcione.
219 Ben
15
Pergunta antiga, mas para responder ao comentário, pode ser necessário aninhar formulários para evitar JavaScript. Estou vendo isso porque gostaria de aninhar formulários para os botões de redefinição do subformulário, que não exigem que o JavaScript esteja ativado.
vol7ron
1
Possível duplicado de: stackoverflow.com/questions/597596/…
yankee 16/06

Respostas:

459

Em uma palavra, não. Você pode ter vários formulários em uma página, mas eles não devem ser aninhados.

No rascunho de trabalho do html5 :

4.10.3 O formelemento

Modelo de conteúdo:

Conteúdo de fluxo, mas sem descendentes de elementos de formulário.

Craig
fonte
126
Eu concordo com a resposta, mas, para perguntar a outra, por que não? Por que o HTML não permite aninhar formulários? Para mim, parece ser uma limitação sem a qual estaríamos melhor. Existem muitos exemplos em que o uso de formulários aninhados seria mais fácil de programar (por exemplo, o uso de um formulário de upload de fotos com um formulário de edição de perfil).
Ryan
20
@ Nilzor, ele não está perguntando se isso não pode ser feito, ele está perguntando POR QUE não. Concordo; aninhar formulários é realmente muito útil. Portanto, se você tiver um aplicativo de uma página com guias, cada guia terá seu próprio formulário (para que você possa enviá-lo para salvar o progresso) e todos serão agrupados em um formulário, que poderá ser enviado para salvar tudo. Faz sentido para mim.
Rob Grant
5
Eu concordo com o que os outros disseram. Essa limitação parece arbitrária e prejudicial.
Aroth
12
Então, precisamos do HTML 5.1 com formulários aninhados.
Hector
3
O problema com formulários aninhados é a arquitetura do formulário no HTML, onde a ação nesse formulário leva a um evento de envio. A pergunta esclarece o que precisa ser enviado. Você pode ter vários campos em um formulário ou vários formulários em uma div, mas não faz sentido ter formulários em um formulário. Se o conteúdo for unido, é tudo uma forma; se o conteúdo é enviado separadamente, são realmente formulários separados que não precisam de um formulário externo.
Kyle Baker
96

Encontrei um problema semelhante e sei que não é uma resposta para a pergunta, mas pode ser
útil para alguém com esse tipo de problema: se houver necessidade de colocar os elementos de duas ou mais formas em uma determinada sequência , o atributo HTML5 <input> form pode ser a solução.

Em http://www.w3schools.com/tags/att_input_form.asp :

  1. O atributo do formulário é novo no HTML5.
  2. Especifica a qual <form>elemento um <input>elemento pertence. O valor desse atributo deve ser o atributo id de um <form>elemento no mesmo documento.

Cenário :

  • input_Form1_n1
  • input_Form2_n1
  • input_Form1_n2
  • input_Form2_n2

Implementação :

<form id="Form1" action="Action1.php" method="post"></form>
<form id="Form2" action="Action2.php" method="post"></form>

<input type="text" name="input_Form1_n1" form="Form1" />
<input type="text" name="input_Form2_n1" form="Form2" />
<input type="text" name="input_Form1_n2" form="Form1" />
<input type="text" name="input_Form2_n2" form="Form2" />

<input type="submit" name="button1" value="buttonVal1" form="Form1" />
<input type="submit" name="button2" value="buttonVal2" form="Form2" />

Aqui você encontrará a compatibilidade do navegador.

Cliff Burton
fonte
1
funciona muito bem! deve ser incluído na resposta aceita
Nahouto 31/01
1
Apenas para apontar a tabela de suporte ao navegador: caniuse.com/#feat=form-attribute Resuming - funciona em qualquer lugar (Chrome, Firefox, Opera, Egde, Safari, navegador Android ...), exceto o IE (incluindo o mais recente agora v11) .
dmikam
@ Cliff-Burton, qual é a diferença aqui? Eu apenas consigo ver entradas fora do formulário. Ainda seria necessário que o JS enviasse os dois formulários ao mesmo tempo. Não seria?
sdlins 29/04
Já faz muito tempo desde a última vez que o usei, mas acho que o JS não é necessário para o envio do formulário. Desde que o <input type="submit"link esteja vinculado ao <form>que especifica um action, o <input />(s) link (s) vinculado (s) ao mesmo <form>serão usados ​​nessa solicitação
Cliff Burton
90

O segundo formulário será ignorado. Veja o trecho do WebKit, por exemplo:

bool HTMLParser::formCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
    // Only create a new form if we're not already inside one.
    // This is consistent with other browsers' behavior.
    if (!m_currentFormElement) {
        m_currentFormElement = new HTMLFormElement(formTag, m_document);
        result = m_currentFormElement;
        pCloserCreateErrorCheck(t, result);
    }
    return false;
}
Vitalii Fedorenko
fonte
43

HTML simples não pode permitir que você faça isso. Mas com javascript você pode fazer isso. Se você estiver usando javascript / jquery, poderá classificar seus elementos de formulário com uma classe e, em seguida, usar serialize () para serializar apenas esses elementos de formulário para o subconjunto dos itens que deseja enviar.

<form id="formid">
    <input type="text" class="class1" />
    <input type="text" class="class2">
</form>

Em seu javascript, você pode fazer isso para serializar elementos class1

$(".class1").serialize();

Para class2 você poderia fazer

$(".class2").serialize();

Para toda a forma

$("#formid").serialize();

ou simplesmente

$("#formid").submit();
user2420019
fonte
31

Se você estiver usando o AngularJS, quaisquer <form>tags dentro do seu ng-appserão substituídas no tempo de execução por ngFormdiretivas projetadas para serem aninhadas.

Nas formas angulares pode ser aninhado. Isso significa que o formulário externo é válido quando todos os formulários filhos também são válidos. No entanto, os navegadores não permitem o aninhamento de <form>elementos; portanto, o Angular fornece a ngFormdiretiva que se comporta de maneira idêntica, <form>mas que pode ser aninhada. Isso permite que você tenha formulários aninhados, o que é muito útil ao usar diretivas de validação angular em formulários gerados dinamicamente usando a ngRepeatdiretiva. ( fonte )

roufamatic
fonte
Esta foi a resposta que eu estava procurando :) E sim, faz sentido aninhar o formulário, porque se você tiver várias guias, mas desejar executar a validação em apenas uma guia, com o formulário aninhado, poderá fazer isso.
NeverGiveUp161
É o mesmo para componentes da web?
Gangadhar Jannu
31

Como é 2019, gostaria de dar uma resposta atualizada para esta pergunta. É possível obter o mesmo resultado que os formulários aninhados, mas sem aninhar. O HTML5 introduziu o atributo form. Você pode adicionar o atributo form para formar controles fora de um formulário para vinculá-los a um elemento específico do formulário (por ID).

https://www.impressivewebs.com/html5-form-attribute/

Dessa forma, você pode estruturar seu html assim:

<form id="main-form" action="/main-action" method="post"></form>
<form id="sub-form"  action="/sub-action"  method="post"></form>

<div class="main-component">
    <input type="text" name="main-property1" form="main-form" />
    <input type="text" name="main-property2" form="main-form" />

    <div class="sub-component">
        <input type="text" name="sub-property1" form="sub-form" />
        <input type="text" name="sub-property2" form="sub-form" />
        <input type="submit" name="sub-save" value="Save" form="sub-form" />
    </div>

    <input type="submit" name="main-save" value="Save" form="main-form" />
</div>

O atributo form é suportado por todos os navegadores modernos. O IE não suporta isso, mas o IE não é mais um navegador, mas uma ferramenta de compatibilidade, conforme confirmado pela própria Microsoft: https://www.zdnet.com/article/microsoft-security-chief-ie-is-not-a -browser-para-parar-de-usar-como-seu-padrão / . Já é hora de pararmos de nos preocupar em fazer as coisas funcionarem no IE.

https://caniuse.com/#feat=form-attribute
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form

A partir da especificação html:

Esse recurso permite que os autores resolvam a falta de suporte para elementos de formulário aninhados.

Criativo
fonte
Qual é a diferença aqui? Eu apenas consigo ver entradas fora do formulário. Ainda seria necessário que o JS enviasse os dois formulários ao mesmo tempo. Não seria?
sdlins 29/04
@sdlins Não, a idéia é estilizar o componente principal e o subcomponente da maneira que você deseja, aninhados. As duas tags de formulário reais serão invisíveis. Cada botão de envio acionará seu respectivo envio de formulário. Não é necessário javascript.
Creative
se você quiser acionar apenas um ou outro formulário, ok. Mas como isso resolveria quando você precisa acionar o "pai"? forma com suas formas filho como era um e sem js?
sdlins
@sdlins não é sobre isso que se trata. A questão é sobre duas formas diferentes, mas aninhe-as. Eu estou querendo saber por que você quer ter 2 formulários, mas ainda 1 função de envio? Você não pode apenas ter um formulário, então? Você realmente precisará recorrer ao javascript para algo tão estranho como esse: P
Creative
Sim, você está certo, essa não é a questão do OP. Vou postar o meu. Obrigado!
sdlins
12

Outra maneira de contornar esse problema, se você estiver usando alguma linguagem de script do lado do servidor que permita manipular os dados publicados, é declarar seu formulário html assim:

<form>
<input name="a_name"/>
<input name="a_second_name"/>
<input name="subform[another_name]"/>
<input name="subform[another_second_name]"/>
</form>

Se você imprimir os dados publicados (usarei o PHP aqui), você obterá uma matriz como esta:

//print_r($_POST) will output :
    array(
    'a_name' => 'a_name_value',
    'a_second_name' => 'a_second_name_value',
    'subform' => array(
      'another_name' => 'a_name_value',
      'another_second_name' => 'another_second_name_value',
      ),
    );

Então você pode simplesmente fazer algo como:

$my_sub_form_data = $_POST['subform'];
unset($_POST['subform']);

Seu $ _POST agora possui apenas os dados do "formulário principal" e os dados do subformulário são armazenados em outra variável que você pode manipular à vontade.

Espero que isto ajude!

Pierre
fonte
11

Como Craig disse, não.

Mas, com relação ao seu comentário sobre o porquê :

Pode ser mais fácil usar 1 <form>com as entradas e o botão "Atualizar" e usar as entradas ocultas de cópia com o botão "Enviar pedido" em outra <form>.

Jonathan Lonowski
fonte
Fiz a página do meu carrinho assim, ele apenas seguiu um caminho diferente e não quis mudar. Eu não era positivo se o método dele também fosse válido.
Levi
9

Observe que você não tem permissão para aninhar elementos FORM!

http://www.w3.org/MarkUp/html3/forms.html

https://www.w3.org/TR/html4/appendix/changes.html#hA.3.9 (a especificação html4 não observa alterações nos formulários de aninhamento de 3.2 a 4)

https://www.w3.org/TR/html4/appendix/changes.html#hA.1.1.12 (a especificação html4 não observa alterações nos formulários de aninhamento de 4.0 para 4.1)

https://www.w3.org/TR/html5-diff/ (a especificação html5 não observa alterações nos formulários de aninhamento de 4 a 5)

https://www.w3.org/TR/html5/forms.html#association-of-controls-and-forms comenta "Este recurso permite que os autores resolvam a falta de suporte para elementos de formulário aninhados". não cite onde isso é especificado, acho que eles estão assumindo que devemos assumir que é especificado na especificação html3 :)

Mark Peterson
fonte
23
Não sei por que você postaria uma pergunta que foi respondida há 3 anos e meio, mas o mais problemático é o link para o HTML3, que não é uma recomendação há muito tempo.
Aidiakapi
7
É uma referência a quanto tempo a pergunta subjacente foi respondida, que eu acreditava ser construtiva. Também achei o tato "Note que você não tem permissão para aninhar elementos FORM!" dentro da especificação para ser bem-humorado.
Mark Peterson
1
Isso é um problema porque tenho que inserir uma API que é um formulário e porque o aplicativo .net (que envolve uma tag <form> em tudo). Como você supera esse problema.
jelly46
4

Uma solução simples é usar um iframe para manter o formulário "aninhado". Visualmente, o formulário está aninhado, mas no lado do código está em um arquivo html separado.

Ezion
fonte
1
Tempo está a fim de iframe
Muhammad Tayyab
3

Você também pode usar formaction = "" dentro da tag button.

<button type="submit" formaction="/rmDog" method='post' id="rmDog">-</button>

Isso seria aninhado na forma original como um botão separado.

Chief Buddy
fonte
isso não responder à pergunta, mas isso só me ajudou a resolver um outro problema que eu estava tendo dando assim upvote
codeAndStuff
ignorar acima (não me deixe editar depois de 5 minutos ... hmm). uma grande ajuda aqui - exatamente mapeada para o que eu estava tentando fazer esta manhã. é por isso que todos nós amamos SO
codeAndStuff
2

Mesmo se você conseguir que ele funcione em um navegador, não há garantia de que funcionaria da mesma maneira em todos os navegadores. Então, enquanto você pode ser capaz de fazê-lo funcionar algum do tempo, você certamente não seria capaz de fazê-lo funcionar todo o tempo.

Mike Hofer
fonte
2

Você ainda teria problemas para fazê-lo funcionar em diferentes versões do mesmo navegador. Portanto, evite usar isso.

MP.
fonte
2

Embora não apresente uma solução para formulários aninhados (não funciona de maneira confiável), apresento uma solução alternativa que funciona para mim:

Cenário de uso: um superformulário que permite alterar N itens de uma só vez. Possui um botão "Enviar tudo" na parte inferior. Cada item deseja ter seu próprio formulário aninhado com o botão "Enviar item nº N". Mas não pode ...

Neste caso, pode-se realmente usar um único formulário, e depois ter o nome dos botões de ser submit_1.. submit_Ne submitAlle manipulá-lo servidores de lado, apenas olhando para params que terminam em _1se o nome do botão foi submit_1.

<form>
    <div id="item1">
        <input type="text" name="foo_1" value="23">
        <input type="submit" name="submit_1" value="Submit Item #1">
    </div>
    <div id="item2">
        <input type="text" name="foo_2" value="33">
        <input type="submit" name="submit_2" value="Submit Item #2">
    </div>
    <input type="submit" name="submitAll" value="Submit All Items">
</form>

Ok, não há muita invenção, mas faz o trabalho.

Peter V. Mørch
fonte
1

Sobre o aninhamento de formulários: Passei 10 anos uma tarde tentando depurar um script ajax.

minha resposta / exemplo anterior não foi responsável pela marcação html, desculpe.

<form id='form_1' et al>
  <input stuff>
  <submit onClick='ajaxFunction(That_Puts_form_2_In_The_ajaxContainer)' >
  <td id='ajaxContainer></td>
</form>

O formulário_2 falhava constantemente ao dizer o formulário inválido

Quando mudei o ajaxContainer que produzia o formulário_2 <i>outside</i>do formulário_1, eu estava de volta aos negócios. É a resposta à pergunta de por que alguém pode aninhar formulários. Quero dizer, realmente, qual é o ID para não definir qual formulário deve ser usado? Deve haver um trabalho melhor e mais eficiente.

Larry
fonte
1

Use a tag de formulário vazia antes do formulário aninhado

Testado e Trabalhado no Firefox, Chrome

Não testado no IE

<form name="mainForm" action="mainAction">
  <form></form>
  <form name="subForm"  action="subAction">
  </form>
</form>
Fatih
fonte
quando eu tentei isso em cromo ele gera este <form name = "Mainform"> </ form> <form name = "subformulário"> </ form>
ianace
1
Você tentou com o botão enviar. Eu uso esse método muitas vezes e sempre funcionei.
Fatih
10
Isso é uma violação da especificação e seu uso está implorando por problemas futuros.
Oskar Berggren
As versões mais recentes do webkit apenas removem os elementos de formulário aninhados.
woens 03/08/19
0

Embora a pergunta seja bastante antiga e eu concorde com o @everyone que o aninhamento de formulário não é permitido em HTML

Mas isso é algo que todos podem querer ver isso

onde você pode invadir (estou chamando de invasão, pois tenho certeza de que isso não é legítimo) html para permitir que o navegador tenha um formulário aninhado

<form id="form_one" action="http://apple.com">
  <div>
    <div>
        <form id="form_two" action="/">
            <!-- DUMMY FORM TO ALLOW BROWSER TO ACCEPT NESTED FORM -->
      </form>
    </div>
      <br/>
    <div>
      <form id="form_three" action="http://www.linuxtopia.org/">
          <input type='submit' value='LINUX TOPIA'/>
      </form>
    </div>
      <br/>

    <div>
      <form id="form_four" action="http://bing.com">
          <input type='submit' value='BING'/>
      </form>
    </div>
      <br/>  
    <input type='submit' value='Apple'/>
  </div>  
</form>

JS LINK FIDDLE

http://jsfiddle.net/nzkEw/10/

Viren
fonte
0

Não, você não pode ter um formulário aninhado. Em vez disso, você pode abrir um Modal que contém o formulário e executar o envio do formulário Ajax.

Shree Sthapit
fonte
0

Realmente não é possível ... Não consegui aninhar tags de formulário ... No entanto, usei este código:

<form>
    OTHER FORM STUFF

    <div novalidate role="form" method="post" id="fake_form_id_0" data-url="YOUR_POST_URL">
        THIS FORM STUFF
    </div>
</form>

com {% csrf_token %}e outras coisas

e aplicou algum JS

var url = $(form_id).attr("data-url");

$.ajax({
  url: url,
  "type": "POST",
   "data": {
    'csrfmiddlewaretoken': '{{ csrf_token }}',
    'custom-param-attachment': 'value'
  },
  success: function (e, data) {
      if (e.is_valid) {
         DO STUFF
      }
  }
});
diogosimao
fonte
-1

Hoje, eu também fiquei preso no mesmo problema e resolvi o problema: adicionei um controle de usuário e,
nesse controle, uso esse código

<div class="divformTagEx">

</div>

<asp:Literal runat="server" ID="litFormTag" Visible="false">
'<div> <form  style="margin-bottom: 3;" action="http://login.php" method="post" name="testformtag"></form> </div>'</asp:Literal>

e no evento PreRenderComplete da página, chame este método

private void InitializeJavaScript()
{
        var script = new StringBuilder();
        script.Append("$(document).ready(function () {");
        script.Append("$('.divformTagEx').append( ");
        script.Append(litFormTag.Text);
        script.Append(" )");
        script.Append(" });");
        ScriptManager.RegisterStartupScript(this, GetType(), "nestedFormTagEx", script.ToString(), true);
    }

Eu acredito que isso vai ajudar.

Shivanshu
fonte
-1

Antes que eu soubesse que não deveria fazer isso, aninhei formulários com o objetivo de ter vários botões de envio. Funcionou dessa maneira por 18 meses, milhares de transações de inscrição, ninguém nos ligou sobre quaisquer dificuldades.

Os formulários aninhados me deram um ID para analisar a ação correta a ser tomada. Não quebrou até tentar anexar um campo a um dos botões e validar a reclamação. Não foi grande coisa para desembaraçar - usei uma string explícita no formulário externo para que não importasse o envio e o formulário não correspondessem. Sim, sim, deveria ter retirado os botões de um envio para um onclick.

O ponto é que existem circunstâncias em que não está totalmente quebrado. Mas "não totalmente quebrado" é talvez um padrão muito baixo para se atirar em :-)

Roger Krueger
fonte