Множественные submit для формы. Странное поведение html form submit Где прописывается адрес submit формы html

С приходом HTML5 формы сталее более универсальными. Элемент input теперь может содержать электронные адреса, даты и много другое, их можно отмечать как обязательные не прибегая к javascript – и это всего лишь некоторые из наиболее ценных возможностей. Также теперь для одной формы можно задействовать несколько submit кнопок, а также теперь есть возможность вынести кнопку submit за пределы формы.

Несколько submit внутри одной формы

До недавнего времени в форму можно было вставить только одну кнопку submit, в противном случае форма обрабатывала только последнюю кнопку. Добавляя method="post" и url к элементу формы "form" мы получали рабочую форму.

Теперь ситуация изменилась – в HTML добавили новые свойства "formmethod" и "formaction". Они позволяют добавить метод post и url непосредственно в кнопку "submit", таким образом к form ничего дописывать не нужно. Имея эти параметры, прикрепленные к кнопке "submit", а не к form – все это добавляет больше гибкости форме. Теперь можно сделать столько кнопок, сколько будет необходимо для формы.

Теперь каждая кнопка "submit" относится к разным url и все это избавляет от того, что при верстке необходимо писать javascript код. Все это отлично работает и теперь по нажатии на какую-нибудь кнопку форма получит formmethod и formaction, которые перезапишут стандартные параметры method и action. Если в форме будет присутствовать обычная кнопка "submit" без новых параметров, то он вернет форме значения, установленные для элемента form.

Свойства formmethod и formaction поддерживаются всеми популярными браузерами

Элементы формы (input, select, textarea) за пределами формы

Общепринятый факт, что все элементы формы, принадлежащие ей должны находится внутри элемента . Это уменьшает гибкость при разработке дизайна самих форм. Благодаря новому атрибуту "form" теперь любой элемент можно вынести за пределы формы и разместь любой элемент формы в любой части страницы. Для этого всего лишь необходимо форме добавить идентификатор ID и затем значение этого идентификатора добавить ко всем элементам в качестве аттрибута.

На сегодняшний день аттрибут form поддерживается всеми популярными браузерами, за исключением Internet Explorer (вплоть до 10й версии).

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

Естественно, при отправке данных на сервер, необходимо было воспользоваться JavaScript методом form.submit () . Каково же было мое удивление, когда я обнаружил, что метод отправки данных с помощью кнопки submit и работа JavaScript метода формы submit () кардинально отличаются.

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

Пример отправки данных на сервер (post) с помощью обычной кнопки и предварительная обработка onsubmit будет выглядеть так:

Отправить

при таком коде HTML, поведение формы будет следующим: если нажать кнопку «Отправить», сначала выскочит окошко с предупреждением об отправке данных на сервер, а после нажатия на кнопку «ОК», данные будут отправлены на сервер.

А что же будет, если заменить кнопку submit на JavaScript метод form.submit () ?

Отправить

а вот в этом случае, и произойдет то самое, странное поведение формы — событие onsubmit не сработает, но данные будут отправлены на сервер.

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

А что же по этому поводу говорит спецификация W3C и основные производители браузеров.

У Microsoft более лаконичное описание, «The submit method does not invoke the onsubmit event handler.» (Метод submit не вызывает событие onsubmit ).

Как же выйти из этой ситуации?

Одним из решений может быть создание невидимой кнопки submit и вызов ее метода click () . Но это не сильно красивое решение. Поэтому можно подключить библиотеку jQuery и написать несколько строк кода на JavaScript для программной генерации событий.

$.fn.fireEvent = function(eventType) { return this.each(function() { if (document.createEvent) { var event = document.createEvent("HTMLEvents"); event.initEvent(eventType, true, true); return !this.dispatchEvent(event); } else { var event = document.createEventObject(); return this.fireEvent("on" + eventType, event) } }); };

Использовать данный метод очень просто. С помощью селектора jQuery находим нужный нам объект и вызываем метод fireEvent () , передав ему в качестве параметра, имя нужного события, без приставки on .

$("myform").fireEvent("submit");

На просторах сети, я находил еще одно решение — это использование метода trigger () , вместо метода fireEvent () , только он тоже не работает так как надо, потому и не буду его приводить тут.

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

Этот вопрос входит, наверное, в ТОП10 вопросов на форумах:) Скорей всего это требование дизайнера или заказчика.

Итак, решение, на первый взгляд, простое:

Отправить

Но тут же возникает (как ни странно:) следующий вопрос это, а если JS будет у посетителя отключен?

Изменим наш код на:

И добавим немного JS:

addEvent(window, "load" , windowLoad) ;

/* Кроссбраузерное добавление обработчика события */
function addEvent(obj, evType, fn) {
if (obj.addEventListener ) {
obj.addEventListener (evType, fn, false ) ;
} else if (obj.attachEvent ) {
obj.attachEvent ("on" + evType, fn) ;
}
}

/* Получаем родительскую форму для элемента */
function getParentForm(obj) {
while ((obj = obj.parentNode ) ) {
if (obj.nodeName == "FORM" ) {
break ;
}
}
return obj;
}

/* Ищем все submit-кнопки с классом link и заменяем их на ссылки */
function windowLoad() {
var buttons = document.getElementsByTagName ("input" ) ;
for (var i = 0; i < buttons.length ; i++ ) {


link.appendChild (document.createTextNode (buttons[ i] .getAttribute ("value" ) ) ) ;
link.setAttribute ("href" , "#" ) ;
addEvent(link, "click" , linkClick) ;

var parent = buttons[ i] .parentNode ;
parent.removeChild (buttons[ i] ) ;
parent.appendChild (link) ;
}
}
}

/* Отправляем форму по нажатию на ссылку */
function linkClick(e) {
var e = window.event || e;
var target = e.target || e.srcElement ;
var parentForm = getParentForm(target) ;
parentForm.submit () ;

if (window.event ) { e.returnValue = false ; } else { e.preventDefault () ; }
}

Теперь, если JS будет отключен, посетитель увидит вместо ссылки кнопку и все равно сможет отправить форму. Но мы на этом не остановимся. Заставим кнопку выглядеть как ссылка даже если отключен JS. Для того чтобы стилизировать кнопку изменим тег на button , а span нужен для того чтобы можно было в Firefox добавить подчеркивание текста.

Отправить

Также изменим соответственно часть JS.

var buttons = document.getElementsByTagName ("button" ) ;
for (var i = 0; i < buttons.length ; i++ ) {
if (buttons[ i] .getAttribute ("type" ) == "submit" && buttons[ i] .className == "link" ) {
var link = document.createElement ("a" ) ;
link.appendChild (document.createTextNode (buttons[ i] .firstChild .firstChild .nodeValue ) ) ;

CSS будет выглядеть следующим образом:

button.link {
/* Первые два свойства нужны чтобы убрать отступы в IE */
overflow : visible ;
width : auto ;

/* Убираем отступы */
margin : 0;
padding : 0;

/* Убираем все элементы оформления кнопки */
background : none ;
border : none ;

/* Обычный для ссылок курсор */
cursor : pointer ;
}

/* Ссылка обычно подчеркнута */
button.link span {
color : #00f ;
text-decoration : underline ;
}

Для Firefox можно еще добавить -moz-user-select: text; чтобы текст кнопки можно было выделять, но я сомневаюсь в такой надобности.

Остальные стили будут уже зависеть от конкретного дизайна.

Несколько примечаний:

  • К кнопке не удастся применить псевдоклассы active, visited, а для IE6 и hover
  • В IE6 не будут нормально работать несколько button для одной формы
  • Без JS можно обойтись. Все зависит от того, насколько вам важна естественность ссылки
  • UPD
    insa , не кроссбраузерный (читайте комментарии).

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

    handler(eventObject) — функция, которая будет установлена в качестве обработчика. При вызове она будет получать объект события eventObject .

    handler(eventObject) — см. выше.
    eventData — дополнительные данные, передаваемые в обработчик. Они должны быть представлены объектом в формате: {fName1:value1, fName2:value2, ...} .

    Убрать установленный обработчик можно с помощью метода unbind() .

    Все три варианта использования метода, являются аналогами других методов (см. выше), поэтому все подробности использования submit() , можно найти в описании этих методов.

    Событие submit происходит непосредственно перед отправкой формы на сервер и в обработчике можно инициировать отмену отправки формы, вызвав метод eventObject.preventDefault() или просто возвратив false .

    В IE событие submit в отличие от других событий не обладает свойством "всплытия вверх по иерархии". Однако начиная с jQuery-1.4 эта недоработка устранена и обработчики события submit , установленные на элементы, которые лежат выше элемента формы по иерархии, будут оповещены о предстоящей отправке данных на сервер.

    Пример

    // установим обработчик события submit, элементу с идентификатором foo, // после чего запретим отправку данных на сервер $("#foo" ) .submit (function () { alert ("Форма foo отправлена на сервер." ) ; return false ; } ) ; // вызовем событие submit на элементе foo $("#foo" ) .submit () ; // установим еще один обработчик события submit, на этот раз элементам // с классом block. В обработчик передадим дополнительные данные $(".block" ) .submit ({ a: 12 , b: "abc" } , function (eventObject) { var externalData = "a=" + eventObject.data .a + ", b=" + eventObject.data .b ; alert ("Форма foo отправлена на сервер. " + "В обработчик этого события переданы данные: " + externalData ) ; } ) ;

    Очень долго выдумывал какое дать название этой статье и ничего лучшего не смог придумать. Это единственное название, которое хоть как-то отражает суть изложенного. Я, если честно, не знаю как правильно это называется, поэтому назвал статью также, как пытался найти хоть какую-то информацию в поисковике по этой теме.

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

    Вот и выложил на Ваш суд.

    Суть проблемы

    После самостоятельной реализации, я все таки нашел несколько решения, которые основывались на использовании обычных кнопок, к которым прикручивался JS.

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

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

    Для того, чтобы было более проще понять что я хочу и как это работает вот реально рабочий пример, в виде формы, у который 2 submit`a, пересылающие данные на разные страницы.