Puoi nidificare moduli HTML?


451

È possibile nidificare moduli HTML come questo

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

in modo che entrambe le forme funzionino? Il mio amico sta avendo problemi con questo, una parte delle subFormopere, mentre un'altra parte no.


Sta installando un carrello, in cui la quantità di aggiornamento è all'interno del modulo che tiene traccia dei totali. Personalmente non lo farei, ma sta incontrando problemi nel farlo funzionare.
Levi,

1
Sembra che sarebbe meglio usare Javascript per copiare i valori da una forma all'altra, piuttosto che cercare di nidificarli. Non penso che l'annidamento funzionerà.
Ben

15
Vecchia domanda, ma per rispondere al commento, potrebbero essere necessari moduli di nidificazione per evitare JavaScript. Mi sto imbattendo in questo perché vorrei annidare i moduli per i pulsanti "reset" della sottomaschera, che non richiedono l'attivazione di JavaScript.
vol7ron,

1
Possibile duplicato di: stackoverflow.com/questions/597596/…
yankee

Risposte:


459

In una parola, no. Puoi avere diversi moduli in una pagina ma non devono essere nidificati.

Dalla bozza di lavoro html5 :

4.10.3 L' formelemento

Modello di contenuto:

Flusso di contenuto, ma senza discendenti di elementi del modulo.


126
Sono d'accordo con la risposta, ma per chiedere un altro, perché no? Perché HTML non consente moduli di nidificazione? Per me, sembra essere un limite senza il quale staremmo meglio. Esistono molti esempi in cui l'utilizzo di moduli nidificati sarebbe più facile da programmare (ovvero l'utilizzo di un modulo di caricamento foto con un modulo di modifica del profilo).
Ryan,

20
@Nilzor non sta chiedendo se non può essere fatto o no, sta chiedendo PERCHÉ no. Sono d'accordo; le forme di nidificazione sono in realtà davvero utili. Quindi, se hai un'app di una pagina con le schede, ogni scheda ha il suo modulo (quindi puoi inviarlo per salvare i progressi) e sono tutti racchiusi in un modulo, che puoi inviare per salvare tutto. È sensato per me.
Rob Grant,

5
Sono d'accordo con quello che gli altri hanno detto. Questa limitazione sembra arbitraria e dannosa.
aroth

12
Quindi abbiamo bisogno di HTML 5.1 con moduli nidificati.
Ettore,

3
Il problema con i moduli nidificati è l'architettura del modulo in HTML, in cui l'azione all'interno di quel modulo porta a un evento di invio. La domanda fa capolino su ciò che deve essere presentato. Potresti avere più campi all'interno di un modulo o più moduli all'interno di un div, ma non ha davvero senso avere moduli all'interno di un modulo. Se il contenuto va insieme, è tutto in una forma; se il contenuto viene inviato separatamente, si tratta in realtà di moduli separati che non richiedono un modulo esterno.
Kyle Baker,

96

Ho riscontrato un problema simile e so che non è una risposta alla domanda, ma può essere di aiuto a qualcuno con questo tipo di problema:
se è necessario inserire gli elementi di due o più forme in una determinata sequenza , l' attributo HTML5 <input> form può essere la soluzione.

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

  1. L' attributo form è nuovo in HTML5.
  2. Specifica a quale elemento appartiene <form>un <input>elemento. Il valore di questo attributo deve essere l'attributo id di un <form>elemento nello stesso documento.

Scenario :

  • input_Form1_n1
  • input_Form2_n1
  • input_Form1_n2
  • input_Form2_n2

Implementazione :

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

Qui troverai la compatibilità del browser.


1
funziona benissimo! dovrebbe essere incluso nella risposta accettata
Nahouto

1
Giusto per indicare la tabella di supporto del browser: caniuse.com/#feat=form-attribute Ripresa: funziona ovunque (Chrome, Firefox, Opera, Egde, Safari, browser Android ...) tranne IE (incluso l'ultimo v11) .
dmikam,

@ cliff-burton, qual è la differenza qui? Posso solo vedere input al di fuori del modulo. Sarebbe comunque necessario che JS inviasse entrambi i moduli contemporaneamente. No?
sdlins

Uh, è passato molto tempo dall'ultima volta che l'ho usato, ma penso che JS non sia richiesto per l'invio del modulo. A condizione che il <input type="submit"sia collegato al suo <form>che specifica un action, il <input />(i) collegato (i) allo stesso <form>verrà usato in quella richiesta
Cliff Burton

90

Il secondo modulo verrà ignorato, ad esempio vedere lo snippet di WebKit:

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

43

HTML semplice non può permetterti di farlo. Ma con javascript puoi essere in grado di farlo. Se si utilizza javascript / jquery è possibile classificare gli elementi del modulo con una classe e quindi utilizzare serialize () per serializzare solo quegli elementi del modulo per il sottoinsieme degli elementi che si desidera inviare.

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

Quindi nel tuo JavaScript puoi farlo per serializzare gli elementi di classe 1

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

Per class2 potresti farlo

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

Per l'intera forma

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

o semplicemente

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

31

Se stai utilizzando AngularJS, tutti i <form>tag all'interno di te ng-appvengono sostituiti in fase di esecuzione con ngFormdirettive progettate per essere nidificate.

In forme angolari possono essere nidificati. Ciò significa che la forma esterna è valida quando sono valide anche tutte le forme figlio. Tuttavia, i browser non consentono l'annidamento di <form>elementi, quindi Angular fornisce la ngFormdirettiva che si comporta in modo identico <form>ma che può essere nidificata. Ciò consente di avere moduli nidificati, che è molto utile quando si utilizzano le direttive di convalida angolare in moduli generati dinamicamente mediante la ngRepeatdirettiva. ( fonte )


Questa era la risposta che stavo cercando :) E sì, ha senso nidificare il modulo perché se hai più schede ma vuoi eseguire la convalida su una sola scheda, allora con la forma nidificata puoi farlo.
NeverGiveUp161,

È lo stesso per i webcomponents?
Gangadhar JANNU,

31

Dal 2019 vorrei dare una risposta aggiornata a questa domanda. È possibile ottenere lo stesso risultato delle forme nidificate, ma senza nidificarle. HTML5 ha introdotto l'attributo form. È possibile aggiungere l'attributo del modulo ai controlli del modulo all'esterno di un modulo per collegarli a un elemento del modulo specifico (per ID).

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

In questo modo puoi strutturare il tuo html in questo modo:

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

L'attributo form è supportato da tutti i browser moderni. IE non supporta questo, ma IE non è più un browser, ma uno strumento di compatibilità, come confermato da Microsoft stesso: https://www.zdnet.com/article/microsoft-security-chief-ie-is-not-a -browser-so-stop-using-it-as-your-default / . È ora che smettiamo di preoccuparci di far funzionare le cose in IE.

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

Dalle specifiche html:

Questa funzionalità consente agli autori di aggirare la mancanza di supporto per gli elementi di modulo nidificati.


qual è la differenza qui? Posso solo vedere input al di fuori del modulo. Sarebbe comunque necessario che JS inviasse entrambi i moduli contemporaneamente. No?
sdlins

@sdlins No, l'idea è di modellare il componente principale e il componente secondario come si desidera, nidificati. I tag dei 2 moduli effettivi saranno invisibili. Ogni pulsante di invio attiverà il rispettivo modulo di invio. Non è richiesto JavaScript.
Creativo

se vuoi attivare solo una o l' altra forma, ok. Ma come potrebbe risolversi quando è necessario attivare & quot; parent & quot; forma con le sue forme figlio com'era una e senza js?
sdlins

@sdlins non è questo il problema. La domanda riguarda 2 forme diverse, ma le hai nidificate. Mi chiedo perché vuoi avere 2 moduli ma ancora 1 funzione di invio? Allora non puoi avere solo 1 modulo? Dovrai davvero ricorrere a JavaScript per qualcosa di così strano: P
Creativo

sì, hai ragione, questa non è la domanda del PO. Pubblicherò il mio. Grazie!
sdlins

12

Un altro modo per aggirare questo problema, se si utilizza un linguaggio di scripting lato server che consente di manipolare i dati pubblicati, è dichiarare il modulo HTML in questo modo:

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

Se stampi i dati pubblicati (userò PHP qui), otterrai un array come questo:

//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',
      ),
    );

Quindi puoi semplicemente fare qualcosa del tipo:

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

Il tuo $ _POST ora ha solo i tuoi dati "modulo principale", e i tuoi dati di sottomaschera sono memorizzati in un'altra variabile che puoi manipolare a piacimento.

Spero che sia di aiuto!


11

Come ha detto Craig, no.

Ma, per quanto riguarda il tuo commento sul perché :

Potrebbe essere più semplice utilizzare 1 <form>con gli input e il pulsante "Aggiorna" e utilizzare gli input nascosti copia con il pulsante "Invia ordine" in un altro <form>.


Ho creato la mia pagina del carrello in quel modo, ha semplicemente fatto una strada diversa e non voleva cambiarla. Non ero positivo se il suo metodo fosse altrettanto valido.
Levi,

9

Nota che non ti è permesso nidificare gli elementi FORM!

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

https://www.w3.org/TR/html4/appendix/changes.html#hA.3.9 (la specifica html4 non rileva alcuna modifica relativa ai moduli di nidificazione da 3.2 a 4)

https://www.w3.org/TR/html4/appendix/changes.html#hA.1.1.12 (la specifica html4 non rileva alcuna modifica relativa ai moduli di nidificazione dalla 4.0 alla 4.1)

https://www.w3.org/TR/html5-diff/ (la specifica html5 non rileva alcuna modifica relativa ai moduli di nidificazione da 4 a 5)

https://www.w3.org/TR/html5/forms.html#association-of-controls-and-forms commenti a "Questa funzione consente agli autori di aggirare la mancanza di supporto per gli elementi di modulo nidificati", ma non non cito dove questo è specificato, penso che stiano assumendo che dovremmo presumere che sia specificato nella specifica html3 :)


23
Non ho idea del perché pubblichi una domanda a cui è stata data risposta 3 anni e mezzo, ma più problematico è il collegamento a HTML3 che non è stato una raccomandazione per molto tempo.
Aidiakapi,

7
È un riferimento a quanto tempo è stata data risposta alla domanda di fondo, che ho ritenuto costruttiva. Inoltre ho trovato il "privo di tatto" Nota che non è consentito nidificare gli elementi FORM! " all'interno delle specifiche per essere divertente.
Mark Peterson,

1
Questo è un problema perché devo inserire un'API che è un modulo e perché l'app .net (che avvolge un tag <form> attorno a tutto). Come superare questo problema.
jelly46

4

Una semplice soluzione consiste nell'utilizzare un iframe per contenere il modulo "nidificato". Visivamente il modulo è nidificato ma sul lato del codice è del tutto in un file html separato.


1
Tempo
scaduto

3

Puoi anche utilizzare formaction = "" all'interno del tag pulsante.

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

Questo sarebbe nidificato nella forma originale come un pulsante separato.


questo non risponde alla domanda ma questo mi ha solo aiutato a risolvere un altro problema che stavo avendo così dare
voto

ignora sopra (non mi lascerebbe modificare dopo 5 minuti ... hmm). grande aiuto qui - mappato esattamente su ciò che stavo tentando di fare stamattina. questo è il motivo per cui amiamo tutti SO
codeAndStuff

2

Anche se riesci a farlo funzionare in un browser, non c'è garanzia che funzioni allo stesso modo in tutti i browser. Quindi, mentre potresti riuscire a farlo funzionare un po ' di tempo, sicuramente non sarai in grado di farlo funzionare tutto il tempo.


2

Avresti anche problemi a farlo funzionare in diverse versioni dello stesso browser. Quindi evita di usarlo.


2

Sebbene non presenti una soluzione ai moduli nidificati (non funziona in modo affidabile), presento una soluzione alternativa che funziona per me:

Scenario di utilizzo: una superforma che consente di cambiare N elementi contemporaneamente. Ha un pulsante "Invia tutto" in basso. Ogni articolo vuole avere il proprio modulo nidificato con un pulsante "Invia articolo # N". Ma non posso ...

In questo caso, si può effettivamente utilizzare un solo modulo e quindi avere il nome dei pulsanti siano submit_1.. submit_Ned submitAlle gestire i server-side, da solo guardando params che terminano con _1se il nome del pulsante è stato 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, quindi non c'è molto di un'invenzione, ma fa il lavoro.


1

Informazioni sui moduli di nidificazione: ho trascorso 10 anni un pomeriggio cercando di eseguire il debug di una sceneggiatura Ajax.

la mia risposta / esempio precedente non ha tenuto conto del markup html, scusa.

<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 costantemente fallito dicendo form_2 non valido.

Quando ho spostato l'AjaxContainer che produceva form_2 <i>outside</i>di form_1, ero di nuovo in affari. È la risposta alla domanda sul perché si potrebbero nidificare le forme. Voglio dire, davvero, qual è l'ID se non definire quale modulo deve essere utilizzato? Deve esserci un lavoro migliore e più fluido.


1

Usa il tag del modulo vuoto prima del modulo nidificato

Testato e lavorato su Firefox, Chrome

Non testato su IE

<form name="mainForm" action="mainAction">
  <form></form>
  <form name="subForm"  action="subAction">
  </form>
</form>

quando l'ho provato su Chrome, viene emesso questo <form name = "mainForm"> </form> <form name = "subForm"> </form>
ianace

1
Hai provato con il pulsante di invio. Ho usato questo metodo molte volte e ho sempre lavorato.
Fatih,

10
Questa è una violazione della specifica e il suo utilizzo sta implorando problemi futuri.
Oskar Berggren,

Le versioni più recenti di webkit rimuovono semplicemente gli elementi del modulo nidificati.
male il

0

Anche se la domanda è piuttosto vecchia e concordo con @everyone, la nidificazione del modulo non è consentita in HTML

Ma questo qualcosa che tutti potrebbero voler vedere questo

dove puoi hackerare (lo chiamo hack perché sono sicuro che questo non è legittimo) html per consentire al browser di avere una forma nidificata

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


0

No, non puoi avere un modulo nidificato. Invece puoi aprire un Modale che contiene un modulo ed eseguire l'invio del modulo Ajax.


0

Davvero impossibile ... Non ho potuto nidificare i tag del modulo ... Tuttavia ho usato questo codice:

<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 %} e roba

e applicato alcuni 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
      }
  }
});

-1

Oggi, mi sono bloccato anche nello stesso problema e risolvo il problema Ho aggiunto un controllo utente e
su questo controllo uso questo codice

<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 all'evento PreRenderComplete della pagina chiama questo metodo

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);
    }

Credo che questo aiuterà.


-1

Prima di rendermi conto che non avrei dovuto farlo, avevo moduli nidificati allo scopo di avere più pulsanti di invio. Ho funzionato in questo modo per 18 mesi, migliaia di transazioni di iscrizione, nessuno ci ha chiamato per eventuali difficoltà.

I moduli nidificati mi hanno fornito un ID per analizzare l'azione corretta da eseguire. Non ho rotto fino a quando ho cercato di collegare un campo a uno dei pulsanti e Convalida si è lamentato. Non è stato un grosso problema per districare - ho usato un stringify esplicito sul modulo esterno in modo che non importasse l'invio e il modulo non corrispondevano. Sì, sì, avrei dovuto prendere i pulsanti da un invio a un onclick.

Il punto è che ci sono circostanze in cui non è completamente rotto. Ma "non del tutto rotto" è forse uno standard troppo basso per cui sparare :-)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.