Я знаю, что XHTML не поддерживает вложенные теги форм, и я уже читал другие ответы здесь на Stack Overflow относительно этой темы, но я до сих пор не нашел элегантного решения проблемы.
Некоторые говорят, что вам это не нужно, и что они не могут придумать сценарий, если бы это было необходимо. Ну, лично я не могу придумать сценарий, который мне не нужен.
Давайте посмотрим на очень простой пример:
Вы создаете приложение для блога, и у вас есть форма с некоторыми полями для создания нового сообщения и панель инструментов с «действиями», такими как «Сохранить», «Удалить», «Отмена».
<form
action="/post/dispatch/too_bad_the_action_url_is_in_the_form_tag_even_though_conceptually_every_submit_button_inside_it_may_need_to_post_to_a_diffent_distinct_url"
method="post">
<input type="text" name="foo" /> <!-- several of those here -->
<div id="toolbar">
<input type="submit" name="save" value="Save" />
<input type="submit" name="delete" value="Delete" />
<a href="/home/index">Cancel</a>
</div>
</form>
Наша цель - написать форму так, чтобы она не требовала JavaScript , просто старая HTML-форма и кнопки отправки.
Поскольку URL-адрес действия определен в теге Form, а не в каждой отдельной кнопке отправки, наш единственный вариант - опубликовать общий URL-адрес, а затем запустить «if ... then ... else», чтобы определить имя кнопки, которая был представлен. Не очень элегантно, но наш единственный выбор, так как мы не хотим полагаться на JavaScript.
Единственная проблема заключается в том, что нажатие «Удалить» отправит ВСЕ поля формы на сервер, хотя единственное, что необходимо для этого действия, - это скрытый ввод с post-id. В этом небольшом примере нет ничего сложного, но у меня есть формы с сотнями (так сказать) полей и вкладок в моих LOB- приложениях, которые (из-за требований) должны отправлять все за один раз, и в любом случае это кажется очень неэффективным и трата. Если бы поддержка вложенных форм была поддержана, я бы по крайней мере смог бы обернуть кнопку «Удалить» внутри своей формы только с полем post-id.
Вы можете сказать «Просто внедрите« Удалить »как ссылку вместо отправки». Это было бы неправильно на многих уровнях, но самое главное, потому что побочные действия, такие как «Удалить», никогда не должны быть запросом GET.
Итак, мой вопрос (особенно к тем, кто говорит, что им не нужна вложенность форм): что ВЫ делаете? Есть ли какое-то элегантное решение, которое я пропускаю, или нижняя строка действительно "Требуется JavaScript или отправьте все"?
Ответы:
Я бы реализовал это точно так, как вы описали: отправьте все на сервер и сделайте простой if / else, чтобы проверить, какая кнопка была нажата.
И затем я реализовал бы вызов Javascript, связывающий событие onsubmit формы, который проверял бы перед отправкой формы, и только отправлял соответствующие данные на сервер (возможно, через вторую форму на странице с идентификатором, необходимым для обработки вещи как скрытый ввод, или обновите местоположение страницы с данными, которые вам нужно передать как запрос GET, или отправьте сообщение Ajax на сервер, или ...).
Таким образом, люди без Javascript могут нормально использовать форму, но нагрузка на сервер компенсируется, потому что люди, у которых есть Javascript, представляют только один необходимый фрагмент данных. Сосредоточение внимания только на поддержке одного или другого действительно ограничивает ваши возможности без необходимости.
В качестве альтернативы, если вы работаете за корпоративным брандмауэром или чем-то другим, и у всех отключен Javascript, вы можете захотеть сделать две формы и поработать с CSS-магией, чтобы создать вид, что кнопка удаления является частью первой формы.
источник
Я знаю, что это старый вопрос, но HTML5 предлагает несколько новых опций.
Первый - это отделить форму от панели инструментов в разметке, добавить другую форму для действия удаления и связать кнопки на панели инструментов с соответствующими формами, используя
form
атрибут.Эта опция довольно гибкая, но в оригинальном сообщении также упоминалось, что может потребоваться выполнить различные действия с одной формой. HTML5 снова приходит на помощь. Вы можете использовать
formaction
атрибут на кнопках отправки, чтобы разные кнопки в одной форме могли отправлять разные URL-адреса. В этом примере просто добавляется метод клонирования на панель инструментов вне формы, но он будет работать так же, как вложенный в форму.http://www.whatwg.org/specs/web-apps/current-work/#attributes-for-form-submission
Преимущество этих новых функций заключается в том, что они делают все это декларативно без JavaScript. Недостатком является то, что они не поддерживаются в более старых браузерах, поэтому вам придется выполнить некоторое заполнение для старых браузеров.
источник
form=
нужна поддержка браузера - CanIUse на самом деле не говорит. caniuse.com/#feat=forms<input>
для объявления кнопок.<button>
элемент был введен 15 лет назад для этой цели. На самом деле люди.<input>
или<button>
элементы, не имеет значения, хотя кнопки, как вы говорите, обычно больше подходят для панелей инструментов. Кстати, элементы кнопок не поддерживаются всеми браузерами уже 15 лет.Вы можете иметь формы рядом на странице, но не вложенные. затем использовать CSS, чтобы все кнопки выстроились в ряд?
источник
В HTML5 есть идея «владелец формы» - атрибут «форма» для элементов ввода. Это позволяет эмулировать вложенные формы и решит проблему.
источник
Вид старой темы, но эта может быть полезна для кого-то:
Как кто-то упоминал выше - вы можете использовать пустышку. Мне пришлось преодолеть эту проблему некоторое время назад. Сначала я полностью забыл об этом ограничении HTML и просто добавил вложенные формы. Результат был интересным - я потерял свою первую форму из вложенного. Тогда оказалось, что это своего рода «хитрость» - просто добавить фиктивную форму (которая будет удалена из браузера) перед фактическими вложенными формами.
В моем случае это выглядит так:
Прекрасно работает с Chrome, FireFox и Safari. IE до 9 (не уверен около 10) и Opera не определяет параметры в основной форме. Глобальное $ _REQUEST пусто, независимо от входных данных. Внутренние формы, кажется, работают хорошо везде.
Не проверялось другое предложение, описанное здесь - набор полей вокруг вложенных форм.
РЕДАКТИРОВАТЬ : Frameset не работает! Я просто добавил основную форму после других (не больше вложенных форм) и использовал «клон» jQuery для дублирования входных данных в форме при нажатии кнопки. Добавлен .hide () к каждому из клонированных входов, чтобы сохранить макет без изменений, и теперь он работает как шарм.
источник
Я думаю, что Джейсон прав. Если ваше действие «Удалить» является минимальным, сделайте так, чтобы оно было в форме само по себе, и выровняйте его с другими кнопками, чтобы интерфейс выглядел как одна унифицированная форма, даже если это не так.
Или, конечно, переделать ваш интерфейс и позволить людям полностью удалить что-то еще, что не требует, чтобы они вообще видели enormo-форму.
источник
Один из способов сделать это без javascript - добавить набор переключателей, определяющих действие:
Тогда скрипт действия будет выполнять разные действия в зависимости от значения переключателя.
Другим способом было бы разместить две формы на странице, как вы предложили, только не вложенные. Макет может быть трудно контролировать, хотя:
Использование скрытого поля «задача» в скрипте обработки для соответствующего ветвления.
источник
Эта дискуссия по-прежнему интересует меня. За исходным постом стоят «требования», которые, по-видимому, разделяет ФП - то есть форма с обратной совместимостью. Как человек, чья работа на момент написания статьи иногда должна поддерживать IE6 (и на годы вперед), я копаю это.
Без продвижения структуры (все организации захотят убедиться в совместимости / надежности, и я не использую это обсуждение как оправдание для структуры), решения Drupal для этой проблемы интересны. Drupal также имеет прямое отношение, потому что у фреймворка давно существует политика «она должна работать без Javascript (только если вы хотите)», то есть проблема ОП.
Drupal использует довольно обширные функции form.inc, чтобы найти triggering_element (да, это имя в коде). Смотрите в нижней части кода, приведенного на странице API для form_builder (если вы хотите вникнуть в детали, рекомендуется источник - drupal-x.xx / includes / form.inc ). Построитель использует автоматическую генерацию HTML-атрибута и, таким образом, может по возвращении определить, какая кнопка была нажата, и действовать соответствующим образом (их также можно настроить для запуска отдельных процессов).
Помимо конструктора форм, Drupal разделяет действия по удалению данных на отдельные URL / формы, вероятно, по причинам, указанным в исходном посте. Для этого требуется какой-то шаг поиска / листинга ( стонать в другой форме!, Но удобный для пользователя) в качестве предварительного. Но это имеет то преимущество, что устраняет проблему «отправить все». Большая форма с данными используется по назначению, для создания / обновления данных (или даже для действия «слияния»).
Другими словами, один из способов решения проблемы состоит в том, чтобы разделить форму на две части, после чего проблема исчезает (и методы HTML также могут быть исправлены с помощью POST).
источник
Используйте
iframe
для вложенной формы. Если им нужно разделить поля, тогда ... это не совсем вложено.источник
Мое решение состоит в том, чтобы кнопки вызывали функции JS, которые пишут, а затем отправляют формы из основной формы.
источник
Если вы действительно не хотите использовать несколько форм (например, Jason sugests), используйте кнопки и обработчики onclick.
И затем в javascript (я использую jQuery здесь для простоты) (хотя это довольно излишне для добавления некоторых обработчиков onclick)
Также я знаю, что это сделает половину страницы не работающей без JavaScript.
источник
В ответ на вопрос, размещенный Яром в комментарии к его собственному ответу, я представляю некоторый JavaScript, который изменит размер iframe. В случае кнопки формы можно с уверенностью предположить, что iframe будет в том же домене. Это код, который я использую. Вам придется изменить математические / константы для вашего собственного сайта:
Тогда назовите это так:
источник
Я только что придумал хороший способ сделать это с помощью jquery.
источник
Что ж, если вы отправляете форму, браузер также отправляет входное имя и значение. Итак, что вы можете сделать, это
поэтому на стороне сервера вы просто ищете параметр, который запускает ширину строки "action:", а остальная часть говорит вам, какое действие предпринять
поэтому, когда вы нажимаете кнопку Сохранить, браузер отправляет вам что-то вроде foo = asd & action: save = Save
источник
Я обошел проблему, включив флажок в зависимости от того, какую форму человек хотел сделать. Затем использовали 1 кнопку, чтобы отправить всю форму.
источник
В качестве альтернативы вы можете назначить форму actiob на лету ... может быть, это не лучшее решение, но оно действительно облегчает логику на стороне сервера ...
источник