Можете ли вы вложить HTML формы?

451

Можно ли вложить HTML-формы, как это

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

так что обе формы работают? У моего друга проблемы с этим, часть subFormработ, а другая - нет.

Леви
источник
Он настраивает корзину, где количество обновлений находится внутри формы, которая отслеживает итоги. Лично я бы так не поступил, но он сталкивается с проблемами, заставляя это работать.
Леви
1
Похоже, ему лучше использовать Javascript для копирования значений из одной формы в другую, а не пытаться их вложить. Я не думаю, что вложение будет работать.
Бен
15
Старый вопрос, но чтобы ответить на комментарий, могут потребоваться вложенные формы, чтобы избежать JavaScript. Я сталкиваюсь с этим, потому что я хотел бы вложить формы для кнопок сброса подчиненной формы, для которых не требуется JavaScript.
vol7ron
1
Возможный дубликат: stackoverflow.com/questions/597596/…
янки

Ответы:

459

Одним словом, нет. На странице может быть несколько форм, но они не должны быть вложенными.

Из рабочего проекта html5 :

4.10.3 formЭлемент

Модель контента:

Содержимое потока, но без потомков элементов формы.

Craig
источник
126
Я согласен с ответом, но спросить другого, почему бы и нет? Почему HTML не позволяет создавать вложенные формы? Мне кажется, это ограничение, без которого нам было бы лучше. Есть много примеров, когда использование вложенных форм было бы проще запрограммировать (например, использовать форму загрузки фотографий с формой редактирования профиля).
Райан
20
@ Нильзор, он не спрашивает, нельзя ли это сделать, он спрашивает, ПОЧЕМУ нет. Согласен; Вложенные формы на самом деле действительно полезны. Таким образом, если у вас есть одностраничное приложение с вкладками, каждая вкладка представляет собой собственную форму (чтобы вы могли отправить ее для сохранения прогресса), и все они обернуты в форму, которую вы можете отправить, чтобы сохранить все. Имеет смысл для меня.
Роб Грант
5
Я согласен с тем, что сказали другие. Это ограничение кажется произвольным и вредным.
aroth
12
Итак, нам нужен HTML 5.1 с вложенными формами.
Гектор
3
Проблема с вложенными формами заключается в архитектуре форм в HTML, где действие в этой форме приводит к событию отправки. Вопрос в волосах о том, что нужно представить. У вас может быть несколько полей внутри формы или несколько форм внутри div, но на самом деле не имеет смысла иметь формы внутри формы. Если контент идет вместе, это все одна форма; если контент представлен отдельно, это действительно отдельные формы, которые не нуждаются во внешней форме.
Кайл Бейкер,
96

Я столкнулся с подобной проблемой, и я знаю, что это не ответ на вопрос, но он может помочь кому-то с такой проблемой:
если необходимо поместить элементы двух или более форм в заданную последовательность , то HTML5 <input> form атрибут может быть решением.

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

  1. Атрибут формы является новым в HTML5.
  2. Определяет , какой <form>элемент <input>элемент принадлежит. Значением этого атрибута должен быть атрибут id <form>элемента в том же документе.

Сценарий :

  • input_Form1_n1
  • input_Form2_n1
  • input_Form1_n2
  • input_Form2_n2

Реализация :

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

Здесь вы найдете совместимость браузера.

Клифф Бертон
источник
1
это прекрасно работает! должны быть включены в принятый ответ
Науто
1
Просто чтобы указать таблицу поддержки браузера: caniuse.com/#feat=form-attribute Resuming - он работает везде (Chrome, Firefox, Opera, Egde, Safari, браузер Android ...), кроме IE (включая последнюю версию v11) ,
dmikam
@ Cliff-Burton, в чем здесь разница? Я просто вижу входные данные за пределами формы. Это все еще должно было бы JS подать обе формы одновременно. Не так ли?
Сдлинс
Ну, прошло много времени с тех пор, как я последний раз использовал это, но я думаю, что JS не требуется для отправки формы. При условии, что объект <input type="submit"связан с тем, <form>который указывает action, <input />ссылки, связанные с тем же самым, <form>будут использоваться в этом запросе
Клифф Бертон
90

Вторая форма будет игнорироваться, см. Фрагмент из 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 не может позволить вам сделать это. Но с помощью JavaScript вы можете сделать это. Если вы используете javascript / jquery, вы можете классифицировать элементы формы с помощью класса, а затем использовать serialize () для сериализации только тех элементов формы для подмножества элементов, которые вы хотите отправить.

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

Тогда в вашем javascript вы можете сделать это для сериализации элементов class1

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

Для класса 2 вы могли бы сделать

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

Для всей формы

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

или просто

$("#formid").submit();
user2420019
источник
31

Если вы используете AngularJS, любые <form>теги внутри вас ng-appзаменяются во время выполнения ngFormдирективами, которые предназначены для вложения.

В угловых формах могут быть вложенными. Это означает, что внешняя форма действительна, когда все дочерние формы также действительны. Однако браузеры не допускают вложение <form>элементов, поэтому Angular предоставляет ngFormдирективу, которая ведет себя идентично, <form>но может быть вложенной. Это позволяет вам иметь вложенные формы, что очень полезно при использовании директив Angular validation в формах, которые динамически генерируются с использованием ngRepeatдирективы. ( источник )

roufamatic
источник
Это был ответ, который я искал :) И да, имеет смысл вкладывать форму, потому что если у вас есть несколько вкладок, но вы хотите выполнить проверку только на одной вкладке, то с помощью вложенной формы вы можете сделать это.
NeverGiveUp161
Это то же самое для веб-компонентов?
Гангадхар ЯННУ
31

Поскольку сейчас 2019 год, я бы хотел дать обновленный ответ на этот вопрос. Можно достичь того же результата, что и вложенные формы, но без их вложения. HTML5 ввел атрибут формы. Вы можете добавить атрибут формы для элементов управления формы вне формы, чтобы связать их с определенным элементом формы (по идентификатору).

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

Таким образом, вы можете структурировать ваш 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>

Атрибут формы поддерживается всеми современными браузерами. IE не поддерживает это, хотя IE уже не браузер, а скорее инструмент совместимости, что подтверждается самой Microsoft: https://www.zdnet.com/article/microsoft-security-chief-ie-is-not-a -browser-so-stop-using-it-as-your-default / . Пора перестать заботиться о том, чтобы все работало в IE.

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

Из спецификации HTML:

Эта функция позволяет авторам обойти отсутствие поддержки вложенных элементов формы.

творческий
источник
какая здесь разница? Я просто вижу входные данные за пределами формы. Это все еще должно было бы JS подать обе формы одновременно. Не так ли?
Сдлинс
@sdlins Нет, идея состоит в том, чтобы стилизовать основной компонент и подкомпонент так, как вы хотите, чтобы они выглядели, вложенными. Фактические 2 тега формы будут невидимы. Каждая кнопка отправки запускает соответствующую форму отправки. Никакого JavaScript не требуется.
Творческий
если вы хотите вызвать только одну или другую форму, хорошо. Но как это разрешится, когда вам нужно вызвать & quot; parent & quot; Форма с дочерними формами, как это было одно и без JS?
Сдлины
@sdlins это не то, о чем этот вопрос. Вопрос о 2 разных формах, но есть ли они вложенные. Мне интересно, почему вы хотите иметь 2 формы, но все еще 1 функцию отправки? Разве вы не можете просто иметь 1 форму? Вам действительно придется прибегнуть к javascript для чего-то столь странного, как это: P
Creative
да, ты прав, это не вопрос ОП. Я опубликую свою. Спасибо!
Сдлинс
12

Другой способ обойти эту проблему, если вы используете какой-либо серверный язык сценариев, который позволяет вам манипулировать опубликованными данными, это объявить свою HTML-форму следующим образом:

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

Если вы напечатаете опубликованные данные (я буду использовать PHP здесь), вы получите массив, подобный этому:

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

Тогда вы можете просто сделать что-то вроде:

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

Ваш $ _POST теперь содержит только ваши данные «главной формы», а ваши данные подчиненной формы хранятся в другой переменной, которой вы можете манипулировать по своему желанию.

Надеюсь это поможет!

пьер
источник
11

Как сказал Крейг, нет.

Но относительно вашего комментария относительно того, почему :

Может быть проще использовать 1 <form>со входами и кнопку «Обновить», а также использовать копирование скрытых входов с кнопкой «Отправить заказ» в другое <form>.

Джонатан Лоновски
источник
Я сделал свою корзину так, он пошел другим путем и не хотел ее менять. Я не был уверен, если его метод был так же действителен.
Леви
9

Обратите внимание, что вам не разрешено вложить элементы FORM!

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

https://www.w3.org/TR/html4/appendix/changes.html#hA.3.9 (спецификация html4 не отмечает никаких изменений в отношении вложенных форм с 3.2 до 4)

https://www.w3.org/TR/html4/appendix/changes.html#hA.1.1.12 (спецификация html4 не отмечает никаких изменений, касающихся вложенности форм с 4.0 до 4.1)

https://www.w3.org/TR/html5-diff/ (спецификация html5 не отмечает никаких изменений, касающихся вложенности форм с 4 по 5)

https://www.w3.org/TR/html5/forms.html#association-of-controls-and-forms комментирует «Эта функция позволяет авторам обойти отсутствие поддержки вложенных элементов формы.», но делает не указывайте, где это указано, я думаю, что они предполагают, что мы должны предполагать, что это указано в спецификации html3 :)

Марк Петерсон
источник
23
Я понятия не имею, почему вы бы опубликовали вопрос, на который ответили три с половиной года, но более проблематичным является ссылка на HTML3, который долгое время не был рекомендацией.
Aidiakapi
7
Это ссылка на то, как долго на основной вопрос был дан ответ, который я считал конструктивным. Также я обнаружил, что нет такта "Обратите внимание, что вы не можете вкладывать элементы FORM!" в рамках спецификации, чтобы быть юмористическим.
Марк Петерсон
1
Это проблема, потому что я должен вставить API, который является формой, и потому что приложение .net (которое оборачивает тег <form> вокруг всего). Как вы преодолеваете эту проблему.
jelly46
4

Простой обходной путь - использовать iframe для хранения «вложенной» формы. Визуально форма вложенная, но на стороне кода она в отдельном html-файле.

Эцион
источник
1
Время для фреймов
истекло
3

Вы также можете использовать formaction = "" внутри тега кнопки.

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

Это будет вложено в исходную форму в виде отдельной кнопки.

Главный приятель
источник
это не отвечает на вопрос, но это только помогло мне решить другую проблему, которая у меня была, так что я поднял голос
codeAndStuff
игнорировать выше (не позволил бы мне редактировать через 5 минут ... хм). огромная помощь здесь - именно то, что я пытался сделать сегодня утром. именно поэтому мы все так любим
codeAndStuff
2

Даже если бы вы могли заставить его работать в одном браузере, нет гарантии, что он будет работать одинаково во всех браузерах. Таким образом, хотя вы могли бы заставить его работать некоторое время, вы, конечно, не сможете заставить его работать все время.

Майк Хофер
источник
2

У вас даже могут возникнуть проблемы с его работой в разных версиях одного и того же браузера. Поэтому избегайте этого.

MP.
источник
2

Хотя я не представляю решение для вложенных форм (оно не работает надежно), я предлагаю обходной путь, который работает для меня:

Сценарий использования: Суперформа, позволяющая изменять N элементов одновременно. Он имеет кнопку «Отправить все» внизу. Каждый элемент хочет иметь свою собственную вложенную форму с кнопкой «Отправить элемент № N». Но не могу ...

В этом случае можно реально использовать одну форму, а затем имя быть кнопки submit_1.. submit_Nи submitAllи обрабатывать его серверы на стороне, лишь глядя на Params , заканчивающихся в _1случае , если имя кнопки было 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>

Хорошо, так что не большая часть изобретения, но это делает работу.

Петр В. Мёрч
источник
1

О вложенных формах: один день я провел 10 лет, пытаясь отладить сценарий ajax.

мой предыдущий ответ / пример не учитывал разметку 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 постоянно терпел неудачу, говоря неправильный form_2.

Когда я переместил ajaxContainer, который создал form_2 <i>outside</i>из form_1, я вернулся в бизнес. Это ответ на вопрос, почему можно вкладывать формы. Я имею в виду, на самом деле, какой идентификатор, если не определить, какую форму использовать? Должна быть лучшая, приятная работа вокруг.

Larry
источник
1

Используйте пустой тег формы перед вашей вложенной формой

Протестировано и работало на Firefox, Chrome

Не проверено на IE

<form name="mainForm" action="mainAction">
  <form></form>
  <form name="subForm"  action="subAction">
  </form>
</form>
Фатих
источник
когда я попробовал это на chrome, он выводит этот <form name = "mainForm"> </ form> <form name = "subForm"> </ form>
января
1
Вы пробовали с кнопкой отправки. Я использовал этот метод много раз и всегда работал.
Фатих
10
Это является нарушением спецификации, и его использование требует новых проблем.
Оскар Берггрен
Более новые версии webkit просто удаляют вложенные элементы формы.
woens
0

Хотя вопрос довольно старый, и я согласен с @everyone, что в HTML не разрешено вложение форм

Но это то, что все, возможно, захотят увидеть это

где вы можете взломать (я называю это взломом, так как я уверен, что это не законно) HTML, чтобы браузер имел вложенную форму

<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
источник
0

Нет, вы не можете иметь вложенную форму. Вместо этого вы можете открыть модал, содержащий форму и выполнить отправку формы Ajax.

Шри Стхапит
источник
0

На самом деле не возможно ... Я не мог вкладывать теги формы ... Однако я использовал этот код:

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

с {% csrf_token %}и прочее

и применил некоторые 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
источник
-1

Сегодня я также застрял в той же проблеме, и решить проблему, я добавил пользовательский элемент управления и
на этом элементе управления я использую этот код

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

и на событии PreRenderComplete страницы вызовите этот метод

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

Я верю, что это поможет.

Shivanshu
источник
-1

Прежде чем я знал, что не должен был этого делать, у меня были вложенные формы для нескольких кнопок отправки. Пробежал так за 18 месяцев тысячи регистрационных транзакций, никто не звонил нам о каких-либо трудностях.

Вложенные формы дали мне идентификатор для анализа на правильное действие. Не сломался, пока я не попытался прикрепить поле к одной из кнопок, и Валидат пожаловался. Ничего страшного в этом не было - я использовал явное stringify для внешней формы, поэтому не имело значения, что submit и форма не совпадали. Да, да, надо было взять кнопки из отправки на клик.

Дело в том, что есть обстоятельства, когда он не полностью нарушен. Но "не полностью сломанный", возможно, слишком низкий стандарт, чтобы стрелять :-)

Роджер Крюгер
источник