Czy umiesz zagnieżdżać formularze HTML?

451

Czy można zagnieżdżać takie formularze HTML?

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

aby obie formy działały? Mój przyjaciel ma z tym problem, część subFormprac, podczas gdy inna część tego nie ma.

Levi
źródło
Przygotowuje wózek, w którym ilość aktualizacji znajduje się w formularzu, który śledzi sumy. Ja bym tego nie zrobił, ale ma problemy z uruchomieniem tego.
Levi,
1
Wygląda na to, że lepiej byłoby mu używać Javascript do kopiowania wartości z jednej formy do drugiej, niż próbować ich zagnieżdżać. Nie sądzę, żeby zagnieżdżanie działało.
Ben,
15
Stare pytanie, ale aby odpowiedzieć na komentarz, konieczne może być zagnieżdżenie formularzy, aby uniknąć JavaScript. Rozumiem to, ponieważ chciałbym zagnieżdżać formularze dla przycisków „resetowania” podformularza, które nie wymagają włączonej obsługi JavaScript.
vol7ron
1
Możliwy duplikat: stackoverflow.com/questions/597596/…
yankee

Odpowiedzi:

459

Jednym słowem nie. Na stronie możesz mieć kilka formularzy, ale nie powinny być one zagnieżdżane.

Z wersji roboczej HTML5 :

4.10.3 formElement

Model zawartości:

Przepływ treści, ale bez potomków elementów formularza.

Craig
źródło
126
Zgadzam się z odpowiedzią, ale żeby zapytać inną, dlaczego nie? Dlaczego HTML nie pozwala na zagnieżdżanie formularzy? Wydaje mi się, że byłoby to ograniczenie, bez którego lepiej byśmy byli. Istnieje wiele przykładów, w których korzystanie z formularzy zagnieżdżonych byłoby łatwiejsze do zaprogramowania (tj. Użycie formularza przesyłania zdjęcia z formularzem edycji profilu).
Ryan,
20
@Nilzor nie pyta, czy nie można tego zrobić, pyta DLACZEGO nie. Zgadzam się; zagnieżdżanie formularzy jest naprawdę bardzo przydatne. Więc jeśli masz jednostronicową aplikację z kartami, każda karta ma swój własny formularz (więc możesz przesłać ją, aby zapisać postęp), a wszystkie są opakowane w formularz, który możesz przesłać, aby zapisać wszystko. Dla mnie to ma sens.
Rob Grant,
5
Zgadzam się z tym, co powiedzieli inni. To ograniczenie wydaje się arbitralne i szkodliwe.
aroth
12
Potrzebujemy więc HTML 5.1 z zagnieżdżonymi formularzami.
Hector
3
Problem z zagnieżdżonymi formularzami polega na architekturze formularzy w HTML, gdzie działanie w tej formie prowadzi do zdarzenia przesłania. Pytanie dotyczy włosów, co należy przesłać. Możesz mieć kilka pól w formularzu lub kilka formularzy w div, ale tak naprawdę nie ma sensu mieć formularzy w formularzu. Jeśli treść idzie w parze, jest to jedna forma; jeśli treść jest przesyłana osobno, to naprawdę osobne formularze, które nie wymagają zewnętrznego formularza.
Kyle Baker
96

Zetknąłem się z podobnym problemem i wiem, że nie jest to odpowiedź na pytanie, ale może pomóc komuś, kto ma tego rodzaju problem:
jeśli zachodzi potrzeba umieszczenia elementów dwóch lub więcej form w danej sekwencji , atrybut HTML5 <input> form może być rozwiązaniem.

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

  1. Atrybut formularza jest nowy w HTML5.
  2. Określa <form>elementem <input>elementem należy. Wartość tego atrybutu musi być atrybutem id <form>elementu w tym samym dokumencie.

Scenariusz :

  • input_Form1_n1
  • input_Form2_n1
  • input_Form1_n2
  • input_Form2_n2

Realizacja :

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

Tutaj znajdziesz kompatybilność przeglądarki.

Cliff Burton
źródło
1
działa świetnie! powinien zostać uwzględniony w zaakceptowanej odpowiedzi
Nahouto
1
Wystarczy wskazać tabelę obsługi przeglądarki: caniuse.com/#feat=form-attribute Wznawianie - działa wszędzie (Chrome, Firefox, Opera, Egde, Safari, przeglądarka Android ...) oprócz IE (w tym najnowszej wersji v11) .
dmikam
@ Cliff-Burton, jaka jest tutaj różnica? Po prostu widzę dane wejściowe poza formularzem. Nadal potrzebowałoby JS do przesłania obu formularzy jednocześnie. Prawda?
sdlins
Minęło sporo czasu, odkąd ostatnio go użyłem, ale myślę, że JS nie jest wymagane do przesłania formularza. Pod warunkiem, że <input type="submit"jest związana z jej <form>, która określa action, że <input />(y) związane z tym samym <form>będzie używany w tym żądaniu
Cliff Burton
90

Drugi formularz zostanie zignorowany, zobacz na przykład fragment kodu z 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;
}
Vitalii Fedorenko
źródło
43

Zwykły HTML nie pozwala na to. Ale dzięki javascript możesz to zrobić. Jeśli używasz javascript / jquery, możesz sklasyfikować elementy formularza za pomocą klasy, a następnie użyć serialize (), aby serializować tylko te elementy formularza dla podzbioru elementów, które chcesz przesłać.

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

Następnie w javascript możesz to zrobić, aby serializować elementy klasy1

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

Dla klasy 2 możesz to zrobić

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

Dla całej formy

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

lub po prostu

$("#formid").submit();
użytkownik2420019
źródło
31

Jeśli używasz AngularJS, wszelkie <form>tagi wewnątrz ng-appsą zastępowane w czasie wykonywania ngFormdyrektywami, które są zaprojektowane do zagnieżdżania.

W Kątach można zagnieżdżać formy. Oznacza to, że formularz zewnętrzny jest ważny, gdy wszystkie formularze potomne są również ważne. Jednak przeglądarki nie pozwalają na zagnieżdżanie <form>elementów, więc Angular zapewnia ngFormdyrektywę, która zachowuje się identycznie, <form>ale może być zagnieżdżona. Pozwala to na tworzenie zagnieżdżonych formularzy, co jest bardzo przydatne podczas korzystania z dyrektyw walidacji kątowej w formularzach generowanych dynamicznie za pomocą ngRepeatdyrektywy. ( źródło )

Roufamatic
źródło
To była odpowiedź, której szukałem :) I tak, sensowne jest zagnieżdżanie formularza, ponieważ jeśli masz wiele kart, ale chcesz przeprowadzić sprawdzanie poprawności tylko na jednej karcie, możesz to zrobić za pomocą formy zagnieżdżonej.
NeverGiveUp161
Czy to samo dotyczy komponentów internetowych?
Gangadhar JANNU
31

Ponieważ jest rok 2019, chciałbym udzielić zaktualizowanej odpowiedzi na to pytanie. Możliwe jest osiągnięcie tego samego wyniku co formy zagnieżdżone, ale bez ich zagnieżdżania. HTML5 wprowadził atrybut formularza. Możesz dodać atrybut formularza do formantów formularza poza formularzem, aby połączyć je z określonym elementem formularza (według identyfikatora).

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

W ten sposób możesz uporządkować swój HTML:

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

Atrybut formularza jest obsługiwany przez wszystkie nowoczesne przeglądarki. IE nie obsługuje tego, ale IE nie jest już przeglądarką, a raczej narzędziem kompatybilności, co potwierdza sam Microsoft: https://www.zdnet.com/article/microsoft-security-chief-ie-is-not-a -browser-so-stop-using-it-as-your-default / . Najwyższy czas, abyśmy przestali dbać o to, by działało w IE.

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

Ze specyfikacji HTML:

Ta funkcja pozwala autorom obejść brak obsługi zagnieżdżonych elementów formularza.

Twórczy
źródło
jaka jest tutaj różnica? Po prostu widzę dane wejściowe poza formularzem. Nadal potrzebowałoby JS do przesłania obu formularzy jednocześnie. Prawda?
sdlins
@sdlins Nie, chodzi o styl głównego i podskładnika tak, aby wyglądał jak zagnieżdżony. Rzeczywiste 2 tagi formularza będą niewidoczne. Każdy przycisk wysyłania spowoduje uruchomienie odpowiedniego formularza przesłania. Nie jest wymagany javascript.
Kreatywny
jeśli chcesz uruchomić tylko jedną lub inną formę, ok. Ale jak to rozwiązałoby, kiedy trzeba uruchomić „rodzica” Forma z formami potomnymi, jak to była jedna i bez JS?
sdlins
@sdlins nie o to chodzi w tym pytaniu. Pytanie dotyczy 2 różnych form, ale należy je zagnieżdżać. Zastanawiam się, dlaczego chcesz mieć 2 formularze, ale nadal 1 funkcję przesyłania? Czy nie możesz mieć tylko 1 formularza? Rzeczywiście będziesz musiał skorzystać z javascript, aby uzyskać coś tak dziwnego: P
Creative
tak, masz rację, to nie jest pytanie OP. Zamieszczę własne. Dziękuję Ci!
sdlins
12

Innym sposobem na obejście tego problemu, jeśli używasz języka skryptowego po stronie serwera, który pozwala manipulować opublikowanymi danymi, jest zadeklarowanie formularza HTML w następujący sposób:

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

Jeśli wydrukujesz opublikowane dane (użyję tutaj PHP), otrzymasz tablicę podobną do tej:

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

Następnie możesz po prostu zrobić coś takiego:

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

Twój $ _POST ma teraz tylko dane „głównej postaci”, a dane podformularza są przechowywane w innej zmiennej, którą możesz dowolnie modyfikować.

Mam nadzieję że to pomoże!

Pierre
źródło
11

Jak powiedział Craig, nie.

Ale jeśli chodzi o twój komentarz, dlaczego :

Łatwiej może być użyć 1 <form>z danymi wejściowymi i przyciskiem „Aktualizuj”, a innego użyć ukrywania danych wejściowych za pomocą przycisku „Prześlij zamówienie” <form>.

Jonathan Lonowski
źródło
Tak zrobiłem stronę mojego koszyka, po prostu poszedł inną drogą i nie chciał jej zmieniać. Nie byłem pewien, czy jego metoda była równie ważna.
Levi,
9

Pamiętaj, że nie możesz zagnieżdżać elementów FORM!

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

https://www.w3.org/TR/html4/appendix/changes.html#hA.3.9 (specyfikacja html4 nie odnotowuje zmian dotyczących zagnieżdżania formularzy od 3.2 do 4)

https://www.w3.org/TR/html4/appendix/changes.html#hA.1.1.12 (specyfikacja html4 nie odnotowuje zmian dotyczących formularzy zagnieżdżania z 4.0 do 4.1)

https://www.w3.org/TR/html5-diff/ (specyfikacja html5 nie zauważa zmian dotyczących formularzy zagnieżdżania od 4 do 5)

https://www.w3.org/TR/html5/forms.html#association-of-controls-and-forms komentarze do „Ta funkcja pozwala autorom obejść brak obsługi zagnieżdżonych elementów formularza”. nie cytuj, gdzie jest to określone, myślę, że zakładają, że powinniśmy założyć, że jest to określone w specyfikacji html3 :)

Mark Peterson
źródło
23
Nie mam pojęcia, dlaczego napisałeś na pytanie, na które udzielono odpowiedzi 3 i pół roku, ale bardziej problematyczne jest linkowanie do HTML3, które od dawna nie było rekomendacją.
Aidiakapi
7
Jest to odniesienie do tego, jak długo udzielono odpowiedzi na podstawowe pytanie, co moim zdaniem było konstruktywne. Znalazłem również bezdotykowe „Uwaga: nie możesz zagnieżdżać elementów FORM!” w ramach specyfikacji być zabawnym.
Mark Peterson
1
Jest to problem, ponieważ muszę wstawić interfejs API będący formularzem oraz ponieważ aplikacja .net (która otacza wszystko tagiem <form>). Jak rozwiązać ten problem.
galaretka 46
4

Prostym obejściem jest użycie iframe do przechowywania „zagnieżdżonej” formy. Forma jest zagnieżdżona, ale po stronie kodu znajduje się w osobnym pliku HTML.

Ezion
źródło
1
Czas na iframe
muhammad tayyab,
3

Możesz także użyć formaction = "" wewnątrz tagu przycisku.

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

Byłoby to zagnieżdżone w oryginalnej formie jako osobny przycisk.

Chief Buddy
źródło
to nie odpowiada na pytanie, ale pomogło mi to rozwiązać inny problem, który tak bardzo dawałam upvote
codeAndStuff
zignoruj ​​powyżej (nie pozwolę edytować po 5 minutach ... hmm). ogromna pomoc tutaj - dokładnie odwzorowana na to, co próbowałem zrobić dziś rano. dlatego wszyscy kochamy SO
codeAndStuff
2

Nawet jeśli możesz sprawić, by działał w jednej przeglądarce, nie ma gwarancji, że będzie działał tak samo we wszystkich przeglądarkach. Więc chociaż możesz być w stanie sprawić, by działało przez jakiś czas, na pewno nie będziesz w stanie sprawić, aby działało przez cały czas.

Mike Hofer
źródło
2

Miałbyś nawet problemy z uruchomieniem go w różnych wersjach tej samej przeglądarki. Więc unikaj tego.

POSEŁ.
źródło
2

Chociaż nie przedstawiam rozwiązania dla zagnieżdżonych formularzy (nie działa niezawodnie), przedstawiam obejście, które działa dla mnie:

Scenariusz użycia: superforma pozwalająca na zmianę N przedmiotów jednocześnie. Na dole znajduje się przycisk „Prześlij wszystko”. Każdy element chce mieć własną formę zagnieżdżoną z przyciskiem „Prześlij element nr N”. Ale nie mogę ...

W tym przypadku można rzeczywiście korzystać z jednego formularza, a następnie mieć nazwę przyciski być submit_1.. submit_Ni submitAlli obsługiwać go po stronie serwerów, przez tylko patrząc na params kończących się _1jeśli nazwa przycisku było 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, to niewiele z wynalazku, ale spełnia swoje zadanie.

Peter V. Mørch
źródło
1

O zagnieżdżaniu form: spędziłem 10 lat jednego popołudnia próbując debugować skrypt ajax.

przepraszam, moja poprzednia odpowiedź / przykład nie uwzględniała znaczników HTML.

<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 ciągle nie powiodło się, mówiąc niepoprawny form_2.

Kiedy przeniosłem ajaxContainer, który wytworzył formularz_2 <i>outside</i>formularza_1, wróciłem do pracy. To odpowiedź na pytanie, dlaczego można zagnieżdżać formy. Mam na myśli naprawdę, do czego służy identyfikator, jeśli nie definiuje, który formularz ma być użyty? Musi być lepsza, bardziej płynna praca.

Larry
źródło
1

Użyj pustego znacznika formularza przed zagnieżdżonym formularzem

Testowane i działające na Firefox, Chrome

Nie testowano w IE

<form name="mainForm" action="mainAction">
  <form></form>
  <form name="subForm"  action="subAction">
  </form>
</form>
Fatih
źródło
gdy próbowałem to na chromie wyprowadza to <nazwa formularza = "MainForm"> </ form> <form name = "podformularzu"> </ form>
ianace
1
Próbowałeś z przyciskiem Prześlij. Używałem tej metody wiele razy i zawsze działałem.
Fatih
10
Jest to naruszenie specyfikacji i używanie jej prosi o przyszłe problemy.
Oskar Berggren
Nowsze wersje webkita usuwają tylko zagnieżdżone elementy formularza.
woens,
0

Chociaż pytanie jest dość stare i zgadzam się z @everyone, że zagnieżdżanie formy jest niedozwolone w HTML

Ale to coś wszyscy mogą chcieć to zobaczyć

gdzie możesz włamać się (nazywam to włamaniem, ponieważ jestem pewien, że to nie jest uzasadnione) HTML, aby umożliwić przeglądarce zagnieżdżenie formularza

<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
źródło
0

Nie, nie możesz mieć zagnieżdżonej formy. Zamiast tego możesz otworzyć Modal, który zawiera formularz i wykonać przesłanie formularza Ajax.

Shree Sthapit
źródło
0

Naprawdę niemożliwe ... Nie mogłem zagnieździć znaczników formularzy ... Jednak użyłem tego kodu:

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

z {% csrf_token %} i takie tam

i zastosowałem trochę 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
źródło
-1

Dzisiaj również utknąłem w tym samym problemie. Rozwiązałem problem, dodałem kontrolę użytkownika i
na tej kontroli używam tego kodu

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

i na zdarzeniu PreRenderComplete strony wywołaj tę metodę

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

Wierzę, że to pomoże.

Shivanshu
źródło
-1

Zanim się zorientowałem, że nie powinienem tego robić, zagnieżdżałem formularze w celu posiadania wielu przycisków przesyłania. Trwało to przez 18 miesięcy, tysiące transakcji rejestracji, nikt nie dzwonił do nas o żadnych trudnościach.

Zagnieżdżone formularze dały mi identyfikator do przeanalizowania pod kątem prawidłowego działania. Nie złamałem się, dopóki nie próbowałem dołączyć pola do jednego z przycisków i Validate narzekał. Rozplątanie go nie było wielkim problemem - użyłem jawnego strify na zewnętrznym formularzu, więc nie miało znaczenia, że ​​przesłanie i formularz nie pasują. Tak, tak, powinienem wziąć guziki z poddania się po kliknięciu.

Chodzi o to, że są okoliczności, w których nie jest całkowicie zepsuty. Ale „nie do końca uszkodzony” jest być może zbyt niskim standardem, aby strzelać do :-)

Roger Krueger
źródło