Ловля мух и сабмитов

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

Важно было исключить любое явное проявление скрипта в коде формы, что-то вроде «onsubmit» или «onclick» в коде кнопки отправки. Еще я хотел бы иметь простую возможность отключать такую ловлю сабмитов. Ну и для аккуратности, форма должна была, автоматически накрывается полупрозрачным слоем, который блокировал ее на время запроса к серверу. Пока я не уверен, хорош ли последний пункт, но все же.
Придумал я такую форму:

<form action="/">
    <input type="text" name="mail" placeholder="Ваша почта">
    <input type="text" name="password" placeholder="Пароль">
    <input type="submit" value="Войти">
</form>


Как видно, ничего интересного в ней нет.
Немножко помозговав, я пришел к выводу, что просто поймать сабмит я не знаю как, зато знаю как поймать клик на кнопке и даже узнать, что за форма.
document.onclick = function(e) {
if(e.target.tagName.toLowerCase() == "input" && e.target.type == "submit") //Узнаем, сабмит это или нет
{
    var elem = e.target.parentNode;
    while (elem)
    {//Ищем форму
        if(elem.tagName.toLowerCase() == "form") break;
        elem = elem.offsetParent;
    }


Потом я узнавал что делать с формой, отправить синхронно или асинхронно, для этого я проверил наличие атрибута method тега form. Как выяснилось, если он не указан явно, то его значение пустая строка.

if(elem.method == "")


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

var input_type = ["input", "textarea", "select"]
for(var i=0; i<elems.length; i++)
{
	if(elems[i].tagName != undefined)
	{
	    if(in_array(elems[i].tagName.toLowerCase(), input_type))
    	{
	    	name = elems[i].name;
	    	value = elems[i].value;
	    	data[name] = value;
    	}
    }
}


Ну и накрываем дивом форму, который вписываем в начало. Стиль его можно редактировать через id, для этого стоит удалить background и opacity из текущего описания:

Для удобства чтения разбил на строки, на самом деле это одна строка
elem.innerHTML = "<div id='cover' style='
width:" + elem.offsetWidth + "px;
height:" + elem.offsetHeight + "px;
background:#ffffff;opacity:0.5;
top:" + elem.offsetTop + "px;
left:" + elem.offsetLeft + "px;
position:absolute;'></div>" + elem.innerHTML;


Первая последняя вещь, это отправка запроса, удаление объекта со значениями формы и предотвращение синхронной отправки формы. Для асинхронной отправки, я использую класс kirik-а, читать про него на phpforum.ru

var AJAX = new AjaxRequest(action);
AJAX.OnComplete(formSubmitResult);
AJAX.Post(data);
delete data;
return false


И вторая последняя вещь, это функция, которая выполняется при ответе сервера. единственная строка в ней удаляет созданную ширму на форме.

function formSubmitResult(text)
{
    globals.form.removeChild(ida('cover'));
}


Привожу полный код и две функции, которые использовались, но не упоминались.

function ida(id){return document.getElementById(id);}
var globals = new Object();

document.onclick = function(e) {
	if(e.target.tagName.toLowerCase() == "input" && e.target.type == "submit") //Узнаем, сабмит это или нет
	{
		var elem = e.target.parentNode;
		while (elem)
	    {//Ищем форму
	        if(elem.tagName.toLowerCase() == "form") break;
	        elem = elem.offsetParent;
	    }
		globals = {"form" : elem};
			if(elem.method == "")//e.target.parentNode.submit();
			{
				action = elem.action;
				var data = new Object;
				
				elems = elem.getElementsByTagName('*');
				var input_type = ["input", "textarea", "select"]
				for(var i=0; i<elems.length; i++)
				{
					if(elems[i].tagName != undefined)
					{
					    if(in_array(elems[i].tagName.toLowerCase(), input_type))
				    	{
					    	name = elems[i].name;
					    	value = elems[i].value;
					    	data[name] = value;
				    	}
				    }
				}
				elem.innerHTML = "<div id='cover' style='width:" + elem.offsetWidth + "px;height:" + elem.offsetHeight + "px;background:#ffffff;opacity:0.5;top:" + elem.offsetTop + "px;left:" + elem.offsetLeft + "px;position:absolute;'></div>" + elem.innerHTML;

				var AJAX = new AjaxRequest(action);
				AJAX.OnComplete(formSubmitResult);
				AJAX.Post(data);
				delete data;
			    return false
			}
	}
		
}

function formSubmitResult(text)
{
	globals.form.removeChild(ida('cover'));
	ida('text').innerHTML = text;
}

function in_array(needle, haystack, strict) {
	var found = false, key, strict = !!strict;
	for (key in haystack) {
		if ((strict && haystack[key] === needle) || (!strict && haystack[key] == needle)) {
			found = true;
			break;
		}
	}
	return found;
}


Все, всем удачи!
  • 0
  • 22 октября 2010, 23:19
  • haZe

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.