type son los formularios formulario etiquetas estructura elementos ejemplos cuales html forms nested

son - input html



¿Cómo superar la limitación de anidamiento de formularios html? (16)

Acabo de llegar con una buena manera de hacerlo con jQuery.

<form name="mainform"> <div id="placeholder"> <div> </form> <form id="nested_form" style="position:absolute"> </form> <script> $(document).ready(function(){ pos = $(''#placeholder'').position(); $(''#nested_form'') .css(''left'', pos.left.toFixed(0)+''px'') .css(''top'', pos.top.toFixed(0)+''px''); }); </script>

Sé que xhtml no admite etiquetas de formulario anidadas y ya he leído otras respuestas
aquí en stackoverflow sobre este tema, pero todavía no he encontrado una solución elegante para el problema.

Algunos dicen que no lo necesita y que no pueden pensar en un escenario donde esto sería necesario. Bueno, personalmente no puedo pensar en un escenario que no lo haya necesitado.

Veamos un ejemplo muy simple:

Está creando una aplicación de blog y tiene un formulario con algunos campos para crear una nueva publicación y una barra de herramientas con "acciones" como "Guardar", "Eliminar", "Cancelar".

<form action="/post/dispatch/too_bad_the_action_url_is_in_the_form_tag_even_though_conceptually_every_submit_button_inside_it_may_need_to_post_to_a_diffent_distinct_url" method="post"> <input type="text" name="foo" /> <!-- several of those here --> <div id="toolbar"> <input type="submit" name="save" value="Save" /> <input type="submit" name="delete" value="Delete" /> <a href="/home/index">Cancel</a> </div> </form>

Nuestro objetivo es escribir el formulario de una manera que no requiera javascript , simplemente el formulario html antiguo y los botones de envío.

Dado que la url de acción está definida en la etiqueta del formulario y no en cada botón de envío individual, nuestra única opción es publicar en una url genérica y luego comenzar "si ... luego ... otra cosa" para determinar el nombre del botón que fué enviado. No es muy elegante, pero es nuestra única opción, ya que no queremos confiar en javascript.

El único problema es que al presionar "Eliminar", se enviarán TODOS los campos del formulario en el servidor, aunque lo único que se necesita para esta acción es una entrada Oculta con el post-id. No es gran cosa en este pequeño ejemplo, pero tengo formularios con cientos (por así decirlo) de campos y pestañas en mis aplicaciones LOB que (debido a los requisitos) tienen que enviar todo de una vez y, en cualquier caso, esto parece muy ineficaz y un desperdicio. Si se admitiera el anidamiento de formularios, al menos podría envolver el botón de "Eliminar" dentro de su propio formulario solo con el campo post-id.

Puede decir "Solo implemente" Eliminar "como enlace en lugar de enviar". Esto sería incorrecto en muchos niveles, pero lo más importante es que las acciones de efectos secundarios como "Eliminar" aquí, nunca deben ser una solicitud GET.

Así que mi pregunta (especialmente para aquellos que dicen que no han necesitado anidar la forma) es: ¿Qué hace USTED? ¿Hay alguna solución elegante que me esté perdiendo o el resultado final sea realmente "O requiera JavaScript o envíe todo"?


Alternativamente, puede asignar la forma actiob sobre la marcha ... puede que no sea la mejor solución, pero seguro que alivia la lógica del lado del servidor ...

<form name="frm" method="post"> <input type="submit" value="One" onclick="javascript:this.form.action=''1.htm''" /> <input type="submit" value="Two" onclick="javascript:this.form.action=''2.htm''" /> </form>


Bueno, si envía un formulario, el navegador también envía un nombre y valor de envío de entrada. Entonces lo que puedes hacer es

<form action="/post/dispatch/too_bad_the_action_url_is_in_the_form_tag_even_though_conceptually_every_submit_button_inside_it_may_need_to_post_to_a_diffent_distinct_url" method="post"> <input type="text" name="foo" /> <!-- several of those here --> <div id="toolbar"> <input type="submit" name="action:save" value="Save" /> <input type="submit" name="action:delete" value="Delete" /> <input type="submit" name="action:cancel" value="Cancel" /> </div> </form>

así que en el lado del servidor, simplemente busque el parámetro que comience con la cadena de ancho "acción:" y la parte restante le indicará qué acción debe tomar

así que cuando haces clic en el botón Guardar, el navegador te envía algo como foo = asd & action: save = Save


Creo que Jason tiene razón. Si su acción "Eliminar" es mínima, conviértala en un formulario por sí misma y alinéela con los otros botones para que la interfaz se vea como una forma unificada, incluso si no lo es.

O, por supuesto, rediseña tu interfaz y deja que la gente elimine por completo en otro lugar que no requiera que vean la forma enorme en absoluto.


En respuesta a una pregunta publicada por Yar en un comentario a su propia respuesta, presento un JavaScript que cambiará el tamaño de un iframe. Para el caso de un botón de formulario, es seguro asumir que el iframe estará en el mismo dominio. Este es el código que uso. Tendrá que modificar las matemáticas / constantes para su propio sitio:

function resizeIFrame(frame) { try { innerDoc = (''contentDocument'' in frame) ? frame.contentDocument : frame.contentWindow.document; if(''style'' in frame) { frame.style.width = Math.min(755, Math.ceil(innerDoc.body.scrollWidth)) + ''px''; frame.style.height = Math.ceil(innerDoc.body.scrollHeight) + ''px''; } else { frame.width = Math.ceil(innerDoc.body.scrollWidth); frame.height = Math.ceil(innerDoc.body.scrollHeight); } } catch(err) { window.status = err.message; } }

Entonces llámalo así:

<iframe ... frameborder="0" onload="if(window.parent && window.parent.resizeIFrame){window.parent.resizeIFrame(this);}"></iframe>


Esta discusión todavía me interesa. Detrás de la publicación original hay "requisitos" que el OP parece compartir, es decir, un formulario con compatibilidad hacia atrás. Como alguien cuyo trabajo en el momento de escribirlo a veces debe ser compatible con IE6 (y en los próximos años), lo entiendo.

Sin presionar el marco (todas las organizaciones querrán tranquilizarse con respecto a la compatibilidad / solidez, y no estoy utilizando esta discusión como justificación para el marco), las soluciones de Drupal para este problema son interesantes. Drupal también es directamente relevante porque el marco ha tenido una política de mucho tiempo de "debería funcionar sin Javascript (solo si lo desea)", es decir, el problema del OP.

Drupal usa sus funciones form.inc bastante extensas para encontrar el elemento de activación (sí, ese es el nombre en el código). Consulte la parte inferior del código que figura en la página de la API para form_builder (si desea profundizar en los detalles, se recomienda la fuente: drupal-x.xx / includes / form.inc ). El constructor utiliza la generación automática de atributos HTML y, a través de eso, puede, al regresar, detectar qué botón se presionó y actuar en consecuencia (estos también pueden configurarse para ejecutar procesos separados).

Más allá del creador de formularios, Drupal divide las acciones de "eliminación" de datos en urls / formularios separados, probablemente por las razones mencionadas en la publicación original. Esto requiere algún tipo de paso de búsqueda / listado (¡ gemir de otra forma !, pero es fácil de usar) como preliminar. Pero esto tiene la ventaja de eliminar el problema de "enviar todo". La forma grande con los datos se usa para su propósito, creación / actualización de datos (o incluso una acción de ''combinación'').

En otras palabras, una forma de resolver el problema es convertir el formulario en dos, luego el problema desaparece (y los métodos HTML también se pueden corregir a través de un POST).


HTML5 tiene una idea de "propietario del formulario": el atributo "formulario" para los elementos de entrada. Permite emular formularios anidados y resolverá el problema.


Mi solución es hacer que los botones llamen a las funciones JS que escriben y luego envían los formularios fuera del formulario principal.

<head> <script> function removeMe(A, B){ document.write(''<form name="removeForm" method="POST" action="Delete.php">''); document.write(''<input type="hidden" name="customerID" value="'' + A + ''">''); document.write(''<input type="hidden" name="productID" value="'' + B + ''">''); document.write(''</form>''); document.removeForm.submit(); } function insertMe(A, B){ document.write(''<form name="insertForm" method="POST" action="Insert.php">''); document.write(''<input type="hidden" name="customerID" value="'' + A + ''">''); document.write(''<input type="hidden" name="productID" value="'' + B + ''">''); document.write(''</form>''); document.insertForm.submit(); } </script> </head> <body> <form method="POST" action="main_form_purpose_page.php"> <input type="button" name="remove" Value="Remove" onclick="removeMe(''$customerID'',''$productID'')"> <input type="button" name="insert" Value="Insert" onclick="insertMe(''$customerID'',''$productID'')"> <input type="submit" name="submit" value="Submit"> </form> </body>


Revisé el problema incluyendo una casilla de verificación según la forma que la persona quería hacer. Luego usé 1 botón para enviar el formulario completo.


Sé que esta es una pregunta antigua, pero HTML5 ofrece un par de opciones nuevas.

La primera es separar el formulario de la barra de herramientas en el marcado, agregar otro formulario para la acción de eliminación y asociar los botones en la barra de herramientas con sus respectivos formularios utilizando el atributo de form .

<form id="saveForm" action="/post/dispatch/save" method="post"> <input type="text" name="foo" /> <!-- several of those here --> </form> <form id="deleteForm" action="/post/dispatch/delete" method="post"> <input type="hidden" value="some_id" /> </form> <div id="toolbar"> <input type="submit" name="save" value="Save" form="saveForm" /> <input type="submit" name="delete" value="Delete" form="deleteForm" /> <a href="/home/index">Cancel</a> </div>

Esta opción es bastante flexible, pero la publicación original también mencionó que puede ser necesario realizar diferentes acciones con un solo formulario. HTML5 viene al rescate, de nuevo. Puede utilizar el atributo de formaction en los botones de envío, por lo que diferentes botones en el mismo formulario pueden enviarse a diferentes URL. Este ejemplo solo agrega un método de clonación a la barra de herramientas fuera del formulario, pero funcionaría igual anidado en el formulario.

<div id="toolbar"> <input type="submit" name="clone" value="Clone" form="saveForm" formaction="/post/dispatch/clone" /> </div>

http://www.whatwg.org/specs/web-apps/current-work/#attributes-for-form-submission

La ventaja de estas nuevas funciones es que hacen todo esto de forma declarativa sin JavaScript. La desventaja es que no son compatibles con los navegadores más antiguos, por lo que tendría que hacer un poco de relleno múltiple para los navegadores más antiguos.


Si realmente no desea utilizar varios formularios (como sugiere Jason), use los botones y haga clic en los controladores.

<form id=''form'' name=''form'' action=''path/to/add/edit/blog'' method=''post''> <textarea name=''message'' id=''message''>Blog message here</textarea> <input type=''submit'' id=''save'' value=''Save''> </form> <button id=''delete''>Delete</button> <button id=''cancel''>Cancel</button>

Y luego en javascript (uso jQuery aquí para mayor facilidad) (aunque es un poco excesivo para agregar algunos controladores de clic)

$(''#delete'').click( function() { document.location = ''path/to/delete/post/id''; }); $(''#cancel'').click( function() { document.location = ''/home/index''; });

También sé que esto hará que la mitad de la página no funcione sin javascript.


Tipo de tema antiguo, pero este podría ser útil para alguien:

Como alguien mencionado anteriormente, puedes usar una forma ficticia. Tuve que superar este problema hace algún tiempo. Al principio, me olvidé por completo de esta restricción de HTML y acabo de agregar los formularios anidados. El resultado fue interesante: perdí mi primer formulario del anidado. Luego resultó ser una especie de "truco" simplemente agregar un formulario ficticio (que se eliminará del navegador) antes de los formularios anidados reales.

En mi caso se parece a esto:

<form id="Main"> <form></form> <!--this is the dummy one--> <input...><form id="Nested 1> ... </form> <input...><form id="Nested 1> ... </form> <input...><form id="Nested 1> ... </form> <input...><form id="Nested 1> ... </form> ...... </form>

Funciona bien con Chrome, FireFox y Safari. IE hasta 9 (no estoy seguro sobre 10) y Opera no detecta parámetros en el formulario principal. El $ _REQUEST global está vacío, independientemente de las entradas. Las formas internas parecen funcionar bien en todas partes.

No he probado otra sugerencia que se describe aquí: campo alrededor de formas anidadas.

EDIT : Frameset no funcionó! Simplemente agregué el formulario principal después de los otros (no más formularios anidados) y usé el "clon" de jQuery para duplicar las entradas en el formulario al hacer clic en el botón. Se agregó .hide () a cada una de las entradas clonadas para mantener el diseño sin cambios y ahora funciona como un encanto.


Una forma en que lo haría sin javascript sería agregar un conjunto de botones de radio que definan la acción a realizar:

  • Actualizar
  • Borrar
  • Lo que sea

Luego, el guión de acción tomaría diferentes acciones dependiendo del valor del conjunto de botones de radio.

Otra forma sería colocar dos formularios en la página como sugirió, pero no anidados. El diseño puede ser difícil de controlar aunque:

<form name="editform" action="the_action_url" method="post"> <input type="hidden" name="task" value="update" /> <input type="text" name="foo" /> <input type="submit" name="save" value="Save" /> </form> <form name="delform" action="the_action_url" method="post"> <input type="hidden" name="task" value="delete" /> <input type="hidden" name="post_id" value="5" /> <input type="submit" name="delete" value="Delete" /> </form>

Usar el campo oculto de "tarea" en el script de manejo para bifurcar adecuadamente.


Utilice un iframe para la forma anidada. Si necesitan compartir campos, entonces ... realmente no está anidado.


Yo implementaría esto exactamente como lo describió: envíe todo al servidor y haga un simple si / else para verificar en qué botón se hizo clic.

Y luego implementaría una llamada de Javascript vinculada al evento onsubmit del formulario que se verificará antes de enviar el formulario, y solo enviaré los datos relevantes al servidor (posiblemente a través de un segundo formulario en la página con la ID necesaria para procesar la cosa como una entrada oculta, o actualice la ubicación de la página con los datos que necesita pasar como una solicitud GET, o haga una publicación de Ajax en el servidor, o ...).

De esta manera, las personas sin Javascript pueden utilizar el formulario sin problemas, pero la carga del servidor se compensa porque las personas que tienen Javascript solo envían la única pieza de datos necesaria. Enfocarse solo en admitir uno u otro realmente limita sus opciones innecesariamente.

Alternativamente, si estás trabajando detrás de un firewall corporativo o algo y todo el mundo tiene Javascript deshabilitado, es posible que desees hacer dos formas y trabajar algo de magia CSS para que parezca que el botón de eliminar es parte de la primera forma.


puede tener los formularios lado a lado en la página, pero no anidados. entonces usa CSS para hacer que todos los botones se alineen bien?

<form method="post" action="delete_processing_page"> <input type="hidden" name="id" value="foo" /> <input type="submit" value="delete" class="css_makes_me_pretty" /> </form> <form method="post" action="add_edit_processing_page"> <input type="text" name="foo1" /> <input type="text" name="foo2" /> <input type="text" name="foo3" /> ... <input type="submit" value="post/edit" class="css_makes_me_pretty" /> </form>