1 сентября 2009, 23:56

JavaScript: submit buttons like default links

При попытке оформить submit как ссылку, мы напоремся на множество костылей, и толстый цсс в итоге. Если подумать, то проще заменить сам сабмит с помощью JavaScriptа на ссылку, с его екшеном и ивентами ;)
function submitToLinks(){
	// Если старые брозеры, уходим ;)
	if(!document.getElementById || !document.createTextNode){return;}
  
	var inputs,i,newLink,newText,leng;
	var formId = -1;
	// Соберём все инпуты и посчитаем
	inputs=document.getElementsByTagName('input');
	leng = inputs.length;
	
	// поехали по инпутам
	for (i = 0; i < leng; i++){
		// не определён - уходим
		if (typeof inputs[i] == "undefined") return;
		// проверка на тип инпута, нам нужны сабмиты
		check = inputs[i].getAttribute && inputs[i].getAttribute('type');
		// если тип пустой, не строка, или 0 - следующий
		if (typeof check != "string" || check.length == null || check.length == 0) continue;
		// если тип не сабмит - следующий
		if(check.toLowerCase()!='submit') continue;
		// приступим к операции на сабмите
		var submit2kill = inputs[i];
		// создадим тэг А, с равными value
		newLink=document.createElement('a');
		newText=document.createTextNode(submit2kill.getAttribute('value'));
		newLink.appendChild(newText);
		// если у сабмита был онКлик, прибиндим к ссылке
		if (typeof submit2kill.onclick == "function"){
			if (newLink.addEventListener){// не ИЕ
				newLink.addEventListener('click', submit2kill.onclick, false);
			} else if (newLink.attachEvent){// ИЕее
				newLink.attachEvent('onclick',submit2kill.onclick);
			}  
		}
		// пора узнать в какой мы форме, их то может много быть
		var ourform = submit2kill.parentNode;
		while (ourform.tagName.toLowerCase() != "form") {
			// наш шабмит можеть быть в яйце, а яйцо в курке и т.д.
			// то есть, если сабмит вложен, ищем пока форму не найдём
			// если нету формы, что мы сдесь забыли-то?
			if (ourform.tagName.toLowerCase() == "body") return;
			ourform = ourform.parentNode;
		}
		
		// у каждой формы есть порядковый номер по ДОМу
		// так его выцепить нельзя, ну мы тогда его приклеим	
		if (typeof ourform.number == "undefined") {
			formId++;
			ourform.number = formId;
		}
		
		// у формы может быть ещё и вент онСабмит, вешаем через ЕвилМагию ;)
		// чёрная сторона ДЖс
		if (typeof ourform.onsubmit == "function" 
		&& typeof ourform.submitReplacer == "undefined") {
			// в кратце, мы старый нативный сабмит, перебинживаем
			// и запускаем опосля ивента онСабмит.
			eval(
				"document.forms["+formId+"].submitReplacer = "
				+"document.forms["+formId+"].submit;"
				+"document.forms["+formId+"].submit = function(){"
					+"document.forms["+formId+"].onsubmit();"
					+"document.forms["+formId+"].submitReplacer();"
				+"}"
			);
		}
  	// делаем таки для ссылки/формы сабмит екшон
  	newLink.setAttribute('href','javascript:document.forms['+formId+'].submit()');
  	// убиваем старый добрый сабмит, и вешаем надёжный линк ;)
		submit2kill.parentNode.replaceChild(newLink,submit2kill);
		// после убийства, массив inputs странным образом худает
		// мы это начинаем учитывать декриментом
		i--;
	}
}
// по загрузке делаем магию
window.onload=submitToLinks;



По сути, функция не несёт какой-либо пользы, но на ней просто много фич %), и вообще хорошая тренировка для мозгов. Задача была придумана случайно, и от её решения получен клёвый сатисфекшен.

зы: может кто подскажет, как избавится от eval?

5 комментариев РСС

CTAPbIu_MABP
по-моему всю проверку (3 строки) типа инпута можно заменить на

’submit’ != inputs[i].getAttribute(’type’)

это нормально отработает даже если тип не указан

и помоему вызывать eval там не обязательно
Vitaliy Bogdanets
Когда тэг просто <input />, получаем ошибку.
eval: Да, нет... если не евал, будет вызыватся Сабмит и онСабмит только последней формы, попробуйте поигратся :-/ Хотя, по логике, должно всё работать.
jquery
Ожешь $(«#linkID#).click(function(){ $(this).parents(»form«).submit();});
Vitaliy Bogdanets
хм... клик занят уже это раз!
на джиквери каждый может, это 2 ;)
перед сабмитом есть ещё онСабмит это 3.
sartas
Хм.. А не проще сразу сделать ссылку?

oncklick=’this.form.submit();return false’
Vitaliy Bogdanets
есть ивент самого сабмита (тот же клик), есть ивент онсабмита (самой формы). условие читаем внимательно :)
sartas
>клик занят уже это раз
>перед сабмитом есть ещё онСабмит

тогда чем у кнопки будут отличаться onClick и onSubmit?


>При попытке оформить submit как ссылку

Наверно имелось ввиду «При попытке оформить BUTTON как ссылку», тогда приведенный в статье код помогает решить проблему, а сабмит ссылкой сделать легко.

Vitaliy Bogdanets
sartas
Да, ступил submit этож итак кнопка. Я сначала подумал что submit — это отправка формы и проблема в отрправке формы по ссылке:)

Ваш комментарий

адрес не будет опубликован

ХТМЛ не работает


Ctrl + Enter