Как преодолеть ограничение вложенности HTML-формы? - PullRequest
196 голосов
/ 28 февраля 2009

Я знаю, что xhtml не поддерживает вложенные теги форм, и я уже прочитал другие ответы
здесь в stackoverflow относительно этой темы, но я до сих пор не нашел элегантного решения проблемы.

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

Давайте рассмотрим очень простой пример:

Вы создаете приложение для блога, и у вас есть форма с некоторыми полями для создания нового поста и панель инструментов с «действиями», такими как «Сохранить», «Удалить», «Отмена».

<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, либо отправьте все"?

Ответы [ 16 ]

0 голосов
/ 23 ноября 2013

Я обошел проблему, включив флажок в зависимости от того, какую форму человек хотел сделать. Затем использовали 1 кнопку, чтобы отправить всю форму.

0 голосов
/ 22 ноября 2012

Что ж, если вы отправляете форму, браузер также отправляет имя и значение отправки ввода. Итак, что вы можете сделать, это

<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="action:save" value="Save" />
        <input type="submit" name="action:delete" value="Delete" />
        <input type="submit" name="action:cancel" value="Cancel" />
    </div>
</form>

так что на стороне сервера вы просто ищете параметр, который запускает строку ширины "action:", а остальная часть говорит вам, какое действие предпринять

поэтому, когда вы нажимаете кнопку Сохранить, браузер отправляет вам что-то вроде foo = asd & action: save = Save

0 голосов
/ 15 марта 2012

Я только что придумал хороший способ сделать это с помощью jquery.

<form name="mainform">    
    <div id="placeholder">
    <div>
</form>

<form id="nested_form" style="position:absolute">
</form>

<script>
   $(document).ready(function(){
      pos = $('#placeholder').position();
      $('#nested_form')
         .css('left', pos.left.toFixed(0)+'px')
         .css('top', pos.top.toFixed(0)+'px');
   });
</script>
0 голосов
/ 09 сентября 2011

В ответ на вопрос, опубликованный Яром в комментарии к его собственному ответу, я представляю некоторый JavaScript, который изменит размер iframe. В случае кнопки формы можно предположить, что iframe будет в том же домене. Это код, который я использую. Вам придется изменить математические / константы для вашего собственного сайта:

function resizeIFrame(frame)
{
    try {
        innerDoc = ('contentDocument' in frame) ? frame.contentDocument : frame.contentWindow.document;
        if('style' in frame) {
            frame.style.width = Math.min(755, Math.ceil(innerDoc.body.scrollWidth)) + 'px';
            frame.style.height = Math.ceil(innerDoc.body.scrollHeight) + 'px';
        } else {
            frame.width = Math.ceil(innerDoc.body.scrollWidth);
            frame.height = Math.ceil(innerDoc.body.scrollHeight);
        }
    } catch(err) {
        window.status = err.message;
    }
}

Тогда назовите это так:

<iframe ... frameborder="0" onload="if(window.parent && window.parent.resizeIFrame){window.parent.resizeIFrame(this);}"></iframe>
0 голосов
/ 27 января 2011

В качестве альтернативы вы можете назначить форму actiob на лету ... может быть не лучшим решением, но, безусловно, облегчает логику на стороне сервера ...

<form name="frm" method="post">  
    <input type="submit" value="One" onclick="javascript:this.form.action='1.htm'" />  
    <input type="submit" value="Two" onclick="javascript:this.form.action='2.htm'" />  
</form>
0 голосов
/ 28 февраля 2009

Если вы действительно не хотите использовать несколько форм (например, Джейсон Сугестс), используйте кнопки и обработчики onclick.

<form id='form' name='form' action='path/to/add/edit/blog' method='post'>
    <textarea name='message' id='message'>Blog message here</textarea>
    <input type='submit' id='save' value='Save'>
</form>
<button id='delete'>Delete</button>
<button id='cancel'>Cancel</button>

А затем в javascript (здесь я использую jQuery для простоты) (хотя добавление некоторых обработчиков onclick излишне)

$('#delete').click( function() {
   document.location = 'path/to/delete/post/id'; 
});
$('#cancel').click( function() {
   document.location = '/home/index';
});

Также я знаю, что это сделает половину страницы не работающей без JavaScript.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...