Pull to refresh

Как отправить форму по нажатию на ссылку?

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

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

<a href="#" onclick="document.getElementById('myform').submit(); return false;">Отправить</a>


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

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

<input type="submit" value="Отправить" class="link" />


И добавим немного 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++) {
  if (buttons[i].getAttribute('type') == 'submit' && buttons[i].className == 'link') {
   var link = document.createElement('a');
   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 добавить подчеркивание текста.

<button type="submit" class="link"><span>Отправить</span></button>


Также изменим соответственно часть 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; чтобы текст кнопки можно было выделять, но я сомневаюсь в такой надобности.

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

Несколько примечаний:
  1. К кнопке не удастся применить псевдоклассы active, visited, а для IE6 и hover
  2. В IE6 не будут нормально работать несколько button для одной формы
  3. Без JS можно обойтись. Все зависит от того, насколько вам важна естественность ссылки


UPD
insa предложил еще один очень хороший вариант, единственный минус которого в том, что label не сможет получить фокус.

<form>
<input type="text" name="a" />
<input type="submit" id="push-me" style="display:none" />
</form>
 
<label for="push-me">fake submit</label>


UPD2
К сожалению, вариант, предложенный insa, не кроссбраузерный (читайте комментарии).

Ссылки по теме:
  1. HTML <button> Test
  2. Styling buttons to look like links


Рабочий пример можно посмотреть здесь.
Tags:
Hubs:
+16
Comments141

Articles

Change theme settings