Можете ли вы вложить HTML формы?
Можно ли вложить HTML-формы, как это
<form name="mainForm">
<form name="subForm">
</form>
</form>
так что обе формы работают? У моего друга проблемы с этим, часть subForm
работает, а другая часть - нет.
22 ответа
Одним словом, нет. На странице может быть несколько форм, но они не должны быть вложенными.
4.10.3
form
элементМодель контента:
Содержимое потока, но без потомков элементов формы.
Я столкнулся с подобной проблемой, и я знаю, что это не ответ на вопрос, но он может помочь кому-то с такой проблемой:
если необходимо поместить элементы двух или более форм в заданную последовательность, HTML5 <input> form
атрибут может быть решением.
С http://www.w3schools.com/tags/att_input_form.asp:
- Атрибут формы является новым в HTML5.
- Определяет, какой
<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" />
Здесь вы найдете совместимость браузера.
Поскольку сейчас 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" form="sub-form" value="Save"/>
</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/
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html
Из спецификации HTML:
Эта функция позволяет авторам обойти отсутствие поддержки вложенных элементов формы.
Вторая форма будет игнорироваться, см. Фрагмент из 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;
}
Простой 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();
Если вы используете AngularJS, любой <form>
теги внутри вашего ng-app
заменяются во время выполнения ngForm
директивы, которые предназначены для вложенности.
В угловых формах могут быть вложенными. Это означает, что внешняя форма действительна, когда также допустимы все дочерние формы. Однако браузеры не допускают вложения
<form>
элементы, поэтому Angular обеспечиваетngForm
директива, которая ведет себя идентично<form>
но может быть вложенным. Это позволяет вам иметь вложенные формы, что очень полезно при использовании директив проверки Angular в формах, которые динамически генерируются с использованиемngRepeat
директивы. ( источник)
Другой способ обойти эту проблему, если вы используете какой-либо серверный язык сценариев, который позволяет вам манипулировать опубликованными данными, это объявить свою 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 теперь содержит только ваши данные "главной формы", а ваши данные подчиненной формы хранятся в другой переменной, которой вы можете манипулировать по своему желанию.
Надеюсь это поможет!
Как сказал Крейг, нет.
Но относительно вашего комментария относительно того, почему:
Это может быть проще в использовании 1 <form>
с входами и кнопкой "Обновить", и используйте копирование скрытых входов с кнопкой "Отправить заказ" в другом <form>
,
Обратите внимание, что вам не разрешено вложить элементы FORM!
http://www.w3.org/MarkUp/html3/forms.html
https://www.w3.org/TR/html4/appendix/changes.html (спецификация html4 не отмечает никаких изменений в отношении вложенных форм с 3.2 до 4)
https://www.w3.org/TR/html4/appendix/changes.html (спецификация html4 не отмечает никаких изменений, касающихся вложенности форм с 4.0 до 4.1)
https://www.w3.org/TR/html5-diff/ (спецификация html5 не отмечает никаких изменений, касающихся вложенности форм с 4 по 5)
https://www.w3.org/TR/html5/forms.html комментирует: "Эта функция позволяет авторам обойти отсутствие поддержки вложенных элементов формы". не указывайте, где это указано, я думаю, что они предполагают, что мы должны предполагать, что это указано в спецификации html3:)
Вы также можете использовать formaction="" внутри тега кнопки.
<button type="submit" formaction="/rmDog" method='post' id="rmDog">-</button>
Это будет вложено в исходную форму в виде отдельной кнопки.
Простой обходной путь - использовать iframe для хранения "вложенной" формы. Визуально форма вложенная, но на стороне кода она находится в отдельном HTML-файле.
Даже если бы вы могли заставить его работать в одном браузере, нет гарантии, что он будет работать одинаково во всех браузерах. Поэтому, хотя вы могли бы заставить его работать некоторое время, вы, конечно, не сможете заставить его работать все время.
О вложенных формах: один день я провел 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 я вернулся в бизнес. Это ответ на вопрос, почему можно вкладывать формы. Я имею в виду, на самом деле, что за идентификатор, если не определить, какую форму следует использовать? Должна быть лучшая, приятная работа вокруг.
Хотя вопрос довольно старый, и я согласен с @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
Хотя я не представляю решение для вложенных форм (оно не работает надежно), я предлагаю обходной путь, который работает для меня:
Сценарий использования: Суперформа, позволяющая изменять N элементов одновременно. Он имеет кнопку "Отправить все" внизу. Каждый элемент хочет иметь свою собственную вложенную форму с кнопкой "Отправить элемент № N". Но не могу...
В этом случае фактически можно использовать одну форму, а затем название кнопок будет submit_1
..submit_N
а также submitAll
и обрабатывать его на стороне сервера, только глядя на параметры, заканчивающиеся на _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>
Хорошо, так что не большая часть изобретения, но это делает работу.
Используйте пустой тег формы перед вашей вложенной формой
Протестировано и работало на Firefox, Chrome
Не проверено на IE
<form name="mainForm" action="mainAction">
<form></form>
<form name="subForm" action="subAction">
</form>
</form>
У вас даже могут возникнуть проблемы с тем, чтобы он работал в разных версиях одного и того же браузера. Поэтому избегайте этого.
Действительно невозможно... Я не мог вкладывать теги форм... Однако я использовал этот код:
<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
}
}
});
Прежде чем я знал, что не должен был этого делать, у меня были вложенные формы для нескольких кнопок отправки. Пробежал так за 18 месяцев тысячи регистрационных транзакций, никто не звонил нам о каких-либо трудностях.
Вложенные формы дали мне идентификатор для анализа на правильное действие. Не сломался, пока я не попытался прикрепить поле к одной из кнопок, и Валидат пожаловался. Ничего страшного в этом не было - я использовал явное stringify для внешней формы, поэтому не имело значения, что submit и форма не совпадали. Да, да, надо было взять кнопки от отправки на клик.
Дело в том, что есть обстоятельства, когда он не полностью нарушен. Но "не полностью сломанный", возможно, слишком низкий стандарт, чтобы стрелять:-)
Нет, вы не можете иметь вложенную форму. Вместо этого вы можете открыть модал, содержащий форму и выполнить отправку формы Ajax.
простой трюк, просто не используйте другие внутри другого тега формы используйте те же элементы без использования тега формы.
см. пример ниже "" не используйте другую форму // просто вспомните элемент в ней ""
Сегодня я также застрял в той же проблеме, и решить проблему, я добавил пользовательский элемент управления и
на этом контроле я использую этот код
<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);
}
Я верю, что это поможет.