Czy poprawne jest posiadanie formularza HTML w innym formularzu HTML?


331

Czy poprawny HTML zawiera następujące elementy:

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

Więc kiedy podasz „b”, otrzymujesz tylko pola w wewnętrznej formie. Gdy prześlesz „a”, otrzymasz wszystkie pola minus te w „b”.

Jeśli nie jest to możliwe, jakie obejścia tej sytuacji są dostępne?


28
Wydaje mi się, że w rzeczywistości jest to bardzo powszechna potrzeba znana z interfejsów db - jeśli formularz aktualizuje tabelę A, a ta tabela ma pole powiązane z tabelą B, często chcemy sposobu na aktualizację lub utworzenie wpisów dla tego połączone pole bez konieczności opuszczania bieżącego formularza. Zagnieżdżone formularze podrzędne byłyby bardzo intuicyjnym sposobem (i interfejs użytkownika jest implementowany przez kilka baz danych na komputerach stacjonarnych).
monotasker

3
To nie jest poprawne. Istnieją obejścia, ale należy użyć innej metody uzyskania tych danych. Rozważ jeden formularz wysyłający wszystkie dane do skryptu pocztowego PHP, który następnie przesyła część (część z a) jako jeden e-mail, a część (część z b) jako inny e-mail. Lub do bazy danych lub cokolwiek robisz z tymi danymi. Można zagnieżdżać formularze, ale to NIE jest odpowiedź!


Pytanie jest dobre, ale szybkie wyszukiwanie w Google (nawet bez klikania podanych linków) pokazuje, czy formularze w formularzach są prawidłowe, czy nie. Ja osobiście podobała mi się odpowiedź @Andreas.
Jarett Lloyd

Odpowiedzi:


380

A. To nie jest poprawny HTML ani XHTML

W oficjalnej specyfikacji W3C XHTML sekcja B. „Zakazy elementów” stanowi, że:

"form must not contain other form elements."

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

Jeśli chodzi o starszą specyfikację HTML 3.2 , sekcja dotycząca elementu FORMS stwierdza, że:

„Każda forma musi być zawarta w elemencie FORM. W jednym dokumencie może znajdować się kilka formularzy, ale element FORM nie może być zagnieżdżony”.

B. Obejście

Istnieją obejścia używania JavaScript bez konieczności zagnieżdżania znaczników formularzy.

„Jak utworzyć zagnieżdżony formularz”. (pomimo tytułu nie jest to zagnieżdżony znacznik formularza, ale obejście JavaScript).

Odpowiedzi na to pytanie StackOverflow

Uwaga: Chociaż można oszukać W3C Validators, aby przekazać stronę, manipulując DOM za pomocą skryptów, nadal nie jest to legalny HTML. Problem z użyciem takich podejść polega na tym, że zachowanie Twojego kodu nie jest teraz gwarantowane w różnych przeglądarkach. (ponieważ nie jest to standard)


4
Zobacz mój komentarz powyżej ... To wspaniała odpowiedź, świetne obejście, ale okropna praktyka. Możesz zrobić dokładnie to samo, bez kłopotów z przesyłaniem wszystkich danych do skryptu PHP oraz dzieleniem i wysyłaniem stamtąd do ich własnych miejsc docelowych. Chociaż odpowiedziałeś na pytanie, które jest świetne, jest to po prostu zła i bezcelowa praktyka, ponieważ możesz to zrobić we właściwy sposób w krótszym czasie.

53

Jeśli ktoś znajdzie ten post tutaj, to świetne rozwiązanie bez potrzeby JS. Użyj dwóch przycisków przesyłania z różnymi atrybutami nazwy w języku serwera, który przycisk został naciśnięty, ponieważ tylko jeden z nich zostanie wysłany na serwer.

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

Po stronie serwera może wyglądać mniej więcej tak, jeśli używasz php:

<?php
    if(isset($_POST['save']))
        echo "Stored!";
    else if(isset($_POST['delete']))
        echo "Deleted!";
    else
        echo "Action is missing!";
?>

To nie to samo, w tym przypadku chcesz przejść do tej samej strony i wykonać różne czynności, za pomocą 2 formularzy możesz przejść do różnych stron i / lub otrzymać różne informacje w każdym przypadku.
Luis Tellez,

Możesz użyć pliku php jako opakowania i dołączyć dowolny plik, jeśli chcesz kod w różnych plikach. Więc zamiast (echo „przechowywane!”;) Możesz napisać (dołącz „a.php”;)
Andreas

Mam wiele przycisków usuwania w moim formularzu (powód, dla którego przybyłem tutaj, biorąc pod uwagę zagnieżdżony formularz) 1 dla każdego rekordu i pole wyboru listy na każdym, aby wykonać zbiorcze usuwanie. Twoja odpowiedź zachęciła mnie do ponownego przemyślenia mojego planu, myśląc teraz, że powinienem nazwać przyciski do indywidualnego usunięcia za pomocą identyfikatora numerycznego i masowego usunięcia jako takiego. Zmuszę php do sortowania.
Chris

@Andreas ma pieniądze. Jest to naturalne rozwiązanie, które zmienia sposób interpretacji danych wejściowych formularza. Jeśli użyjesz opcji Post / Redirect / Get, miejsce docelowe może się również różnić. Jeśli jednak nie masz elastyczności po stronie serwera, aby połączyć swoje działania w jeden punkt końcowy „aORb”, to myślę, że utknąłeś w hacku, obawiam się.

27

HTML 4.xi HTML5 nie zezwalają na zagnieżdżone formularze, ale HTML5 pozwoli na obejście z atrybutem „forma” („właściciel formularza”).

W przypadku HTML 4.x możesz:

  1. Użyj dodatkowych formularzy z tylko ukrytymi polami i JavaScript, aby ustawić dane wejściowe i przesłać formularz.
  2. Użyj CSS, aby wyrównać kilka formularzy HTML, aby wyglądały jak jedna całość - ale myślę, że to zbyt trudne.

1
Nie jestem pewien, dlaczego zostało to odrzucone. Oto link do sekcji W3C właścicieli formularzy: w3.org/TR/html5/…
SooDesuNe

5
@SooDesuNe Twój link jest nieaktualny, oto nowy w3.org/TR/html5/forms.html#form-owner
chiliNUT

13

Jak powiedzieli inni, nie jest to prawidłowy HTML.

Wygląda na to, że robisz to, aby wizualnie pozycjonować formularze. Jeśli tak jest, po prostu wykonaj dwa osobne formularze i użyj CSS, aby je ustawić.


1
Myślałem, że potrzebuję tej witryny, ale chciałbym uzyskać przykład, jak to zrobić.
Brian Peterson

8

Nie, specyfikacja HTML stwierdza, że ​​żaden FORMelement nie powinien zawierać innego FORMelementu.


5

Możesz bardzo łatwo odpowiedzieć na swoje pytanie, wprowadzając kod HTML w W3 Validator . (Zawiera pole wprowadzania tekstu, nie musisz nawet umieszczać kodu na serwerze ...)

(I nie, to się nie potwierdzi.)


5

raczej użyj niestandardowej metody javascript w atrybucie akcji formularza!

na przykład

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

5

Istnieje możliwość umieszczenia elementu iframe wewnątrz formy zewnętrznej. Ramka iframe zawiera formę wewnętrzną. Pamiętaj, aby użyć <base target="_parent" />tagu wewnątrz tagu head iframe, aby formularz zachowywał się jako część strony głównej.



1

Nie, to nie jest poprawne. Ale „rozwiązaniem” może być utworzenie okna modalnego poza formą „a” zawierającą formę „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>

Można to łatwo zrobić, jeśli używasz bootstrapu lub zmaterializujesz css. Robię to, aby uniknąć używania iframe.


0

Obejście inne niż JavaScript dotyczące zagnieżdżania znaczników formularzy:

Ponieważ na to pozwalasz

wszystkie pola minus te w „b”.

podczas przesyłania „a” działałyby następujące elementy, przy użyciu zwykłych formularzy internetowych bez wymyślnych sztuczek JavaScript:

Krok 1. Umieść każdy formularz na własnej stronie internetowej.

Krok 2. Wstaw ramkę iframe wszędzie tam, gdzie ma się pojawiać ten podformularz.

Krok 3. Zysk.

Próbowałem użyć witryny z placem zabaw dla kodu, aby pokazać wersję demonstracyjną, ale wiele z nich zabrania osadzania swoich stron w ramkach iframe, nawet w obrębie własnej domeny.


-1

Jeśli potrzebujesz formularza do przesłania / zatwierdzenia danych do relacyjnej bazy danych 1: M, zaleciłbym utworzenie wyzwalacza DB „po wstawieniu” w tabeli A, który wstawi dane niezbędne do tabeli B.


-2

Nie, to nie jest poprawne, ale możesz oszukać swoją wewnętrzną pozycję formularza HTMLprzy pomocy CSSi jQueryużyciu. Najpierw utwórz div div kontenera w formularzu nadrzędnym, a następnie w dowolnym innym miejscu strony div z formularzem dziecka (wewnętrznym):

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

Daj kontenerowi div stabilną heaght

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

Dzięki trickowi pozycja „other_form” względem div kontenera.

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

PS: Będziesz musiał grać liczbami, aby wyglądało ładnie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.