¿Puedes anidar formularios html?

451

¿Es posible anidar formas html como esta?

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

para que ambas formas funcionen? Mi amigo está teniendo problemas con esto, una parte de las subFormobras, mientras que otra parte no.

Levi
fuente
Está configurando un carrito, donde la cantidad de actualización está dentro del formulario que realiza un seguimiento de los totales. Yo personalmente no haría eso, pero está teniendo problemas para que eso funcione.
Levi
1
Parece que sería mejor usar Javascript para copiar valores de un formulario a otro, en lugar de tratar de anidarlos. No creo que la anidación funcione.
Ben
15
Antigua pregunta, pero para responder al comentario, los formularios de anidación podrían ser necesarios para evitar JavaScript. Me encuentro con esto porque me gustaría anidar formularios para los botones de "restablecimiento" del subformulario, que no requieren que JavaScript esté habilitado.
vol7ron
1
Posible duplicado de: stackoverflow.com/questions/597596/…
yankee

Respuestas:

459

En una palabra, no. Puede tener varios formularios en una página, pero no deben estar anidados.

Del borrador de trabajo html5 :

4.10.3 El formelemento

Modelo de contenido:

Contenido de flujo, pero sin descendientes de elementos de forma.

Craig
fuente
126
Estoy de acuerdo con la respuesta, pero para preguntar otra, ¿por qué no? ¿Por qué el HTML no permite los formularios de anidación? Para mí, parece ser una limitación sin la cual estaríamos mejor. Hay muchos ejemplos en los que usar formularios anidados sería más fácil de programar (es decir, usar un formulario de carga de fotos con un formulario de edición de perfil).
Ryan
20
@Nilzor no pregunta si no se puede hacer o no, pregunta por qué no. Estoy de acuerdo; anidar formularios es realmente muy útil. Entonces, si tiene una aplicación de una página con pestañas, cada pestaña tiene su propio formulario (para que pueda enviarla para guardar el progreso), y todas están envueltas en un formulario, que puede enviar para guardar todo. Tiene sentido para mi.
Rob Grant
55
Estoy de acuerdo con lo que han dicho. Esta limitación parece arbitraria y perjudicial.
Aroth
12
Entonces necesitamos HTML 5.1 con formas anidadas.
Héctor
3
El problema con los formularios anidados es la arquitectura del formulario dentro de HTML, donde la acción dentro de ese formulario conduce a un evento de envío. La pregunta capta lo que debe presentarse. Puede tener varios campos dentro de un formulario, o varios formularios dentro de un div, pero realmente no tiene sentido tener formularios dentro de un formulario. Si el contenido va de la mano, es una sola forma; si el contenido se envía por separado, son realmente formularios separados que no necesitan un formulario externo.
Kyle Baker, el
96

Me encontré con un problema similar, y sé que no es una respuesta a la pregunta, pero puede ser de ayuda para alguien con este tipo de problema:
si es necesario poner los elementos de dos o más formas en una secuencia dada , el atributo HTML5 <input> form puede ser la solución.

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

  1. El atributo del formulario es nuevo en HTML5.
  2. Especifica a qué <form>elemento <input>pertenece un elemento. El valor de este atributo debe ser el atributo id de un <form>elemento en el mismo documento.

Escenario :

  • input_Form1_n1
  • input_Form2_n1
  • input_Form1_n2
  • input_Form2_n2

implementación :

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

Aquí encontrarás la compatibilidad del navegador.

Cliff Burton
fuente
1
funciona muy bien! debe incluirse en la respuesta aceptada
Nahouto
1
Solo para señalar la tabla de soporte del navegador: caniuse.com/#feat=form-attribute Resuming : funciona en todas partes (Chrome, Firefox, Opera, Egde, Safari, navegador Android ...) excepto IE (incluido el último hasta ahora v11) .
dmikam
@ Cliff-Burton, ¿cuál es la diferencia aquí? Solo puedo ver entradas fuera del formulario. Todavía necesitaría que JS envíe ambos formularios al mismo tiempo. ¿No es así?
sdlins
Uh, ha pasado mucho tiempo desde la última vez que usé esto, pero creo que JS no está obligado a enviar el formulario. Siempre que <input type="submit"se vincule a su <form>que especifique un action, la <input />(s) vinculación a ese mismo <form>se utilizará en esa solicitud
Cliff Burton
90

El segundo formulario será ignorado, vea el fragmento de WebKit, por ejemplo:

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

El HTML simple no puede permitirte hacer esto. Pero con javascript puedes hacer eso. Si está utilizando javascript / jquery, podría clasificar sus elementos de formulario con una clase y luego usar serialize () para serializar solo esos elementos de formulario para el subconjunto de los elementos que desea enviar.

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

Luego, en su javascript, podría hacer esto para serializar elementos de clase 1

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

Para la clase 2 podrías hacer

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

Para toda la forma

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

o simplemente

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

Si está usando AngularJS, cualquier <form>etiqueta dentro de usted ng-appse reemplaza en tiempo de ejecución con ngFormdirectivas que están diseñadas para anidarse.

En formas angulares se pueden anidar. Esto significa que el formulario externo es válido cuando todos los formularios secundarios también son válidos. Sin embargo, los navegadores no permiten anidar <form>elementos, por lo que Angular proporciona la ngFormdirectiva que se comporta de manera idéntica <form>pero puede anidarse. Esto le permite tener formas anidadas, lo cual es muy útil cuando se usan directivas de validación angular en formularios que se generan dinámicamente usando la ngRepeatdirectiva. ( fuente )

roufamatic
fuente
Esta fue la respuesta que estaba buscando :) Y sí, tiene sentido anidar el formulario porque si tiene varias pestañas pero desea realizar la validación en una sola pestaña, entonces con el formulario anidado puede hacerlo.
NeverGiveUp161
¿Es lo mismo para los componentes web?
Gangadhar JANNU
31

Como es 2019, me gustaría dar una respuesta actualizada a esta pregunta. Es posible lograr el mismo resultado que las formas anidadas, pero sin anidarlas. HTML5 introdujo el atributo de formulario. Puede agregar el atributo de formulario a los controles de formulario fuera de un formulario para vincularlos a un elemento de formulario específico (por id).

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

De esta manera puede estructurar su html de esta manera:

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

El atributo de formulario es compatible con todos los navegadores modernos. Sin embargo, IE no es compatible con esto, pero IE ya no es un navegador, sino una herramienta de compatibilidad, como lo confirmó Microsoft: https://www.zdnet.com/article/microsoft-security-chief-ie-is-not-a -browser-so-stop-using-it-as-your-default / . Ya es hora de que dejemos de preocuparnos por hacer que las cosas funcionen en IE.

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

De la especificación html:

Esta característica permite a los autores evitar la falta de soporte para elementos de formulario anidados.

Creativo
fuente
¿Cual es la diferencia aquí? Solo puedo ver entradas fuera del formulario. Todavía necesitaría que JS envíe ambos formularios al mismo tiempo. ¿No es así?
sdlins
@sdlins No, la idea es diseñar el componente principal y el subcomponente como desea que se vean, anidados. Las 2 etiquetas de formulario reales serán invisibles. Cada botón de envío activará su respectivo formulario de envío. No se requiere javascript.
Creativo
si quieres activar solo una u otra forma, está bien. Pero, ¿cómo se resolvería cuando necesite activar el "padre"? forma con sus formas secundarias como si fuera una y sin js?
sdlins
@sdlins de eso no se trata esta pregunta. La pregunta es sobre 2 formas diferentes, pero anúdelas. Me pregunto por qué quieres tener 2 formularios pero aún 1 función de envío. ¿No puedes tener 1 formulario entonces? De hecho, tendrá que recurrir a JavaScript para algo tan extraño como eso: P
Creativo
Sí, tienes razón, esa no es la pregunta de OP. Publicaré el mío. ¡Gracias!
sdlins
12

Otra forma de solucionar este problema, si está utilizando un lenguaje de script del lado del servidor que le permite manipular los datos publicados, es declarar su formulario html de esta manera:

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

Si imprime los datos publicados (usaré PHP aquí), obtendrá una 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',
      ),
    );

Entonces puedes hacer algo como:

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

Su $ _POST ahora solo tiene sus datos de "formulario principal", y sus datos de subformulario se almacenan en otra variable que puede manipular a voluntad.

¡Espero que esto ayude!

Pierre
fuente
11

Como dijo Craig, no.

Pero, con respecto a su comentario sobre por qué :

Puede ser más fácil usar 1 <form>con las entradas y el botón "Actualizar", y usar entradas ocultas de copia con el botón "Enviar pedido" en otro <form>.

Jonathan Lonowski
fuente
Hice mi página de carrito de esa manera, él simplemente tomó un camino diferente y no quiso cambiarlo. Tampoco era positivo si su método era tan válido.
Levi
9

¡Tenga en cuenta que no puede anidar elementos FORM!

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

https://www.w3.org/TR/html4/appendix/changes.html#hA.3.9 (la especificación html4 no observa cambios con respecto a los formularios de anidación de 3.2 a 4)

https://www.w3.org/TR/html4/appendix/changes.html#hA.1.1.12 (la especificación html4 no observa cambios con respecto a los formularios de anidación de 4.0 a 4.1)

https://www.w3.org/TR/html5-diff/ (la especificación html5 no observa cambios en los formularios de anidación de 4 a 5)

https://www.w3.org/TR/html5/forms.html#association-of-controls-and-forms comentarios a "Esta característica permite a los autores evitar la falta de soporte para elementos de formulario anidados", pero no cito donde se especifica esto, creo que están asumiendo que debemos asumir que está especificado en la especificación html3 :)

Mark Peterson
fuente
23
No tengo idea de por qué publicaría una pregunta que ha sido respondida 3 años y medio, pero lo más problemático es el enlace a HTML3, que no ha sido una recomendación durante mucho tiempo.
Aidiakapi
77
Es una referencia a cuánto tiempo se ha respondido la pregunta subyacente, que creo que es constructiva. También encontré el mensaje "¡Tenga en cuenta que no puede anidar elementos FORM!" dentro de la especificación para ser humorístico.
Mark Peterson
1
Este es un problema porque tengo que insertar una API que es un formulario y porque la aplicación .net (que envuelve una etiqueta <form> alrededor de todo). ¿Cómo superas este problema?
jelly46
4

Una solución simple es usar un iframe para contener el formulario "anidado". Visualmente, el formulario está anidado pero en el lado del código está en un archivo html por completo.

Ezion
fuente
1
Se
acabó el
3

También puede usar formaction = "" dentro de la etiqueta del botón.

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

Esto estaría anidado en la forma original como un botón separado.

Jefe de amigos
fuente
esto no responde a la pregunta, pero esto sólo me ayudó a resolver otro problema que tenía dando así upvote
codeAndStuff
ignorar arriba (no me deja editar después de 5 minutos ... hmm). gran ayuda aquí, exactamente mapeado sobre lo que estaba intentando hacer esta mañana. es por eso que todos amamos SO
codeAndStuff
2

Incluso si pudiera hacer que funcione en un navegador, no hay garantía de que funcione de la misma manera en todos los navegadores. Entonces, si bien es posible que pueda hacer que funcione algunas veces, ciertamente no podrá hacerlo funcionar todo el tiempo.

Mike Hofer
fuente
2

Incluso tendría problemas para hacerlo funcionar en diferentes versiones del mismo navegador. Así que evita usar eso.

MP.
fuente
2

Si bien no presento una solución para formularios anidados (no funciona de manera confiable), sí presento una solución alternativa que funciona para mí:

Escenario de uso: una superforma que permite cambiar N elementos a la vez. Tiene un botón "Enviar todo" en la parte inferior. Cada elemento quiere tener su propio formulario anidado con un botón "Enviar elemento # N". Pero no puedo ...

En este caso, se puede utilizar realmente una sola forma, y luego tener el nombre de los botones sean submit_1.. submit_Ny submitAlly manejar los servidores de juego, con sólo mirar params que terminan en _1si el nombre del botón era 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, no es un gran invento, pero hace el trabajo.

Peter V. Mørch
fuente
1

Acerca de los formularios de anidación: pasé 10 años una tarde tratando de depurar un script ajax.

mi respuesta / ejemplo anterior no tenía en cuenta el marcado html, lo siento.

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

form_2 fallaba constantemente diciendo inválido form_2.

Cuando trasladé el contenedor ajax que produjo form_2 <i>outside</i>de form_1, volví al negocio. Es la respuesta a la pregunta de por qué uno podría anidar formas. Quiero decir, realmente, ¿para qué sirve la identificación si no es para definir qué formulario se utilizará? Debe haber una mejor y más flexible solución.

larry
fuente
1

Use una etiqueta de formulario vacía antes de su formulario anidado

Probado y trabajado en Firefox, Chrome

No probado en IE

<form name="mainForm" action="mainAction">
  <form></form>
  <form name="subForm"  action="subAction">
  </form>
</form>
Fatih
fuente
cuando probé esto en Chrome, muestra este <form name = "mainForm"> </form> <form name = "subForm"> </form>
ianace
1
¿Lo intentaste con el botón Enviar? He usado este método muchas veces y siempre funcionó.
Fatih
10
Esto es una violación de la especificación y su uso es suplicar problemas futuros.
Oskar Berggren
Las versiones más recientes de webkit simplemente eliminan los elementos de formulario anidados.
woens
0

Aunque la pregunta es bastante antigua y estoy de acuerdo con @everyone en que la anidación de formularios no está permitida en HTML

Pero esto es algo que todos querrían ver esto

donde puedes hackear (lo llamo un hack porque estoy seguro de que esto no es legítimo) html para permitir que el navegador tenga un formulario anidado

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

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

Viren
fuente
0

No, no puede tener un formulario anidado. En su lugar, puede abrir un modal que contiene el formulario y realizar el envío del formulario Ajax.

Shree Sthapit
fuente
0

Realmente no es posible ... No pude anidar etiquetas de formulario ... Sin embargo, utilicé 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>

con {% csrf_token %}y esas cosas

y aplicó un poco de 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
fuente
-1

Hoy, también me quedé atrapado en el mismo problema y resolví el problema. Agregué un control de usuario y
en este control uso este 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>

y en el evento PreRenderComplete de la página, llame a 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);
    }

Creo que esto ayudará.

Shivanshu
fuente
-1

Antes de darme cuenta de que no se suponía que debía hacer esto, había anidado formularios con el fin de tener varios botones de envío. Funcionó de esa manera durante 18 meses, miles de transacciones de registro, nadie nos llamó sobre ninguna dificultad.

Los formularios anidados me dieron una identificación para analizar la acción correcta que debo tomar. No se rompió hasta que intenté adjuntar un campo a uno de los botones y Validar se quejó. No fue un gran problema desenredarlo: utilicé un stringify explícito en el formulario externo, por lo que no importó el envío y el formulario no coincidía. Sí, sí, debería haber tomado los botones de un envío a un clic.

El punto es que hay circunstancias en las que no está completamente roto. Pero "no completamente roto" es quizás un estándar demasiado bajo para disparar :-)

Roger Krueger
fuente