¿Es válido tener un formulario html dentro de otro formulario html?

331

¿Es válido html tener lo siguiente:

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

Entonces, cuando envías "b" solo obtienes los campos dentro del formulario interno. Cuando envía "a", obtiene todos los campos menos los que están dentro de "b".

Si no es posible, ¿qué soluciones para esta situación están disponibles?

allyourcode
fuente
28
Me parece que esta es una necesidad muy común que es familiar desde las interfaces db: si un formulario actualiza la tabla A y esa tabla tiene un campo vinculado a la tabla B, a menudo queremos una forma de actualizar o crear entradas para ese campo vinculado sin tener que abandonar el formulario actual. Las subformas anidadas serían una forma muy intuitiva de hacerlo (y es la interfaz de usuario implementada por varias bases de datos de escritorio).
monotasker
3
No es valido Existen soluciones alternativas, pero debería utilizar otro método para obtener estos datos. Considere un formulario que envía todos los datos a un script de correo PHP, que luego envía parte (la parte de a) como un correo electrónico y parte (la parte de b) como otro correo electrónico. O en una base de datos, o lo que sea que estés haciendo con estos datos. Los formularios de anidación se pueden hacer, ¡pero NO es la respuesta!
2
posible duplicado de ¿Puedes anidar formularios html?
usuario
La pregunta es buena, pero una búsqueda rápida en Google (incluso sin hacer clic en los enlaces proporcionados) revela si los formularios dentro de los formularios son válidos o no. Personalmente, me gustó la respuesta de @Andreas.
Jarett Lloyd

Respuestas:

380

A. No es HTML ni XHTML válido

En la especificación oficial W3C XHTML, Sección B. "Prohibiciones de elementos", establece que:

"form must not contain other form elements."

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

En cuanto a la especificación HTML 3.2 anterior , la sección sobre el elemento FORMS establece que:

"Cada formulario debe estar encerrado dentro de un elemento FORM. Puede haber varios formularios en un solo documento, pero el elemento FORM no se puede anidar".

B. La solución

Existen soluciones alternativas que utilizan JavaScript sin necesidad de anidar etiquetas de formulario.

"Cómo crear un formulario anidado". (a pesar del título, esto no son etiquetas de formulario anidadas, sino una solución alternativa de JavaScript).

Respuestas a esta pregunta de StackOverflow

Nota: Aunque se puede engañar a los Validadores del W3C para que pasen una página manipulando el DOM mediante secuencias de comandos, todavía no es HTML legal. El problema con el uso de tales enfoques es que el comportamiento de su código ahora no está garantizado en todos los navegadores. (ya que no es estándar)

GeneQ
fuente
44
Vea mi comentario arriba ... Esta es una respuesta maravillosa, una gran solución, pero una práctica terrible. Puede hacer exactamente lo mismo con menos problemas al enviar todos los datos a un script PHP y dividirlos y enviarlos a sus propios destinos desde allí. Aunque respondiste la pregunta que es genial, es una práctica mala e inútil porque puedes hacerlo de la manera correcta en menos tiempo.
53

En caso de que alguien encuentre esta publicación aquí, es una gran solución sin la necesidad de JS. Use dos botones de envío con diferentes atributos de nombre, verifique en el idioma de su servidor qué botón de envío se presionó porque solo uno de ellos se enviará al 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>

El lado del servidor podría verse así si usa php:

<?php
    if(isset($_POST['save']))
        echo "Stored!";
    else if(isset($_POST['delete']))
        echo "Deleted!";
    else
        echo "Action is missing!";
?>
Andreas
fuente
Esto no es lo mismo, en este caso desea ir a la misma página y realizar diferentes acciones, con 2 formularios puede ir a diferentes páginas y / o recibir información diferente en cada caso.
Luis Tellez
Puede usar un archivo php como envoltorio e incluir cualquier archivo que desee si desea el código en diferentes archivos. Entonces, en lugar de (echo "almacenado";) podría escribir (incluir "a.php";)
Andreas
Tengo varios botones de eliminación en mi formulario (la razón por la que vine aquí considerando un formulario anidado) 1 para cada registro y una casilla de verificación de lista en cada uno para hacer una eliminación masiva. Su respuesta me ha llevado a repensar mi plan, estoy pensando ahora que debería nombrar los botones para la eliminación individual con una identificación numérica y la eliminación masiva como esa. Haré que PHP haga la clasificación.
Chris
@Andreas está en el dinero. Esta es la solución natural para variar la forma en que se interpreta la entrada de formulario. Si usa Post / Redirect / Get, el destino también puede variar. Sin embargo, si no tiene la flexibilidad en el lado del servidor para combinar sus acciones en un único punto final 'aORb', entonces creo que está atrapado en un truco, me temo.
27

HTML 4.xy HTML5 no permiten formularios anidados, pero HTML5 permitirá una solución alternativa con el atributo "formulario" ("propietario del formulario").

En cuanto a HTML 4.x puedes:

  1. Use uno o varios formularios adicionales con solo campos ocultos y JavaScript para configurar sus entradas y enviar el formulario.
  2. Use CSS para alinear varios formularios HTML para que parezca una sola entidad, pero creo que es demasiado difícil.
Nishi
fuente
1
No estoy seguro de por qué esto fue rechazado. Aquí el enlace a la sección W3C de propietarios de formularios: w3.org/TR/html5/…
SooDesuNe
55
@SooDesuNe su enlace está desactualizado, aquí está el nuevo w3.org/TR/html5/forms.html#form-owner
chiliNUT
13

Como han dicho otros, no es HTML válido.

Parece que está haciendo esto para colocar las formas visualmente entre sí. Si ese es el caso, solo haga dos formas separadas y use CSS para colocarlas.

usuario64075
fuente
1
Esto es lo que estaba pensando que necesitaría para mi sitio web, pero me encantaría un ejemplo de cómo hacerlo.
Brian Peterson el
8

No, la especificación HTML establece que ningún FORMelemento debe contener otro FORMelemento.

David Grant
fuente
5

Puede responder su propia pregunta muy fácilmente ingresando el código HTML en el Validador W3 . (Cuenta con un campo de entrada de texto, ni siquiera tendrá que poner su código en un servidor ...)

(Y no, no se validará).

Christian Studer
fuente
5

¡más bien use un método javascript personalizado dentro del atributo de acción del formulario!

p.ej

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

Una posibilidad es tener un iframe dentro de la forma externa. El iframe contiene la forma interna. Asegúrese de utilizar la <base target="_parent" />etiqueta dentro de la etiqueta principal del iframe para que el formulario se comporte como parte de la página principal.

Robin Manoli
fuente
1

No, no es valido. Pero una "solución" puede ser crear una ventana modal fuera del formulario "a" que contenga el formulario "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>

Se puede hacer fácilmente si está utilizando bootstrap o materializa css. Estoy haciendo esto para evitar usar iframe.

Jonathas Hortense
fuente
0

Una solución alternativa que no es JavaScript para anidar etiquetas de formulario:

Porque permites

todos los campos menos aquellos dentro de "b".

al enviar "a", lo siguiente funcionaría, utilizando formularios web regulares sin trucos sofisticados de JavaScript:

Paso 1. Coloque cada formulario en su propia página web.

Paso 2. Inserta un iframe donde quieras que aparezca este subformulario.

Paso 3. Beneficio.

Traté de usar un sitio web de código de juegos para mostrar una demostración, pero muchos de ellos prohíben incrustar sus sitios web en iframes, incluso dentro de su propio dominio.

ADJenks
fuente
-1

Si necesita su formulario para enviar / confirmar datos en una base de datos relacional 1: M, recomendaría crear un disparador de base de datos "después de insertar" en la tabla A que insertará los datos necesarios para la tabla B.

cbWrites
fuente
-2

No, no es válido, pero puede engañar su posición de forma interna en el HTMLcon ayuda CSSy jQueryuso. Primero cree un contenedor div dentro de su formulario padre y luego, en cualquier otro lugar de la página, el div con su formulario hijo (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>

Dale a tu contenedor div algo de peso estable

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

Agradezca el truco de la posición "other_form" relativa al contenedor 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>

PD: Tendrás que jugar con números para que se vea bien.

Yaroslav Varkhol
fuente