LINUX.ORG.RU

Как переопредлить eventlistener на кнопке?

 


0

2

Есть кнопка формы, на которую повешан eventlistener.
Мне надо на этой же кнопке сделать событие on submit. Проблема в том, что листенер вызывается первым и успевает отправить поля формы на сервер до того, как произойдет мое событие (проверка данных и показ ошибки, если не прошли проверку)
событие листенера тоже нужно оставить - оно делает полезные вещи.

вроде как логичное решение - убрать листенер, при нажатии кнопки сначала отработать свое событие и потом поставить то, которое было.

Вот собственно вопрос - как это сделать?


Ещё можно подменить элемент клоном, тогда умрут все обработчики (ну кроме делегируемых) сразу.

Kalashnikov ★★★
()
Ответ на: комментарий от Kalashnikov

А вернуть обратно?
Желательно, даже - собрать все листенеры, деактивировать,
выполнить свое событие и выполнить все действия, которые должны были делать листенеры.

spdooh
() автор топика
Ответ на: комментарий от spdooh

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

Ещё наверно можно ивент поймать раньше (на родителе на стадии погружения), но тут надо покурить доки про ивенты и посмотреть как это делается в конкретно тоём случае.

Я так понимаю, ты юзерскрипт пишешь? Иначе проще наверно пересмотреть то как вешаются оригинальные обработчики.

Kalashnikov ★★★
()

Если мне не изменяет память, событие onsubmit весит не на кнопке, а на форме (тег <form>), и отправка данных происходит только тогда, когда его вызов вернет тру.

Можно хоть какой-то пример кода.

sphericalhorse ★★★★★
()
Ответ на: комментарий от Kalashnikov

Во, как-то так. Второй ивент всегда будет выполнятся перед первым. С jQuery тут всё совсем красиво было бы.

Kalashnikov ★★★
()
Ответ на: комментарий от sphericalhorse

ага, неправильно сформулировал.
Он сабмит - на форме, а на кнопке - листенер.
Листенер вызывается первым и сам отсылает данные.
Пример кода завтра покажу - на работе остался.

spdooh
() автор топика
Ответ на: комментарий от spdooh

Так просто отключаешь форме сабмит:

<form onsubmit="return false;">
    <!-- ... -->
</form>

или так:

<script>
document.getElementById('idТвоейФормы').onsubmit = function() {
    /* тут по ходу можно (или даже нужно) писать код для обработки и отправки данных */
    return false
}
</script>

а там уже отправляешь как хочешь.

Идея в том, что браузер ничего делать не будет, если вызов onsubmit вернет ложь.

ПС: отправлять файлы (те, которые <input type=«file» ... />) через AJAX можно только в новых браузерах. Это если вдруг в подальшем всплывет.

Вообще оффтоп: можешь сказать где и кем работаешь? Это так, для себя очень интересно.

sphericalhorse ★★★★★
()
Ответ на: комментарий от spdooh

Пример кода завтра покажу - на работе остался.

Да вроде уже разобрались и в этом нет потребности. А так, если что, — обращайся.

sphericalhorse ★★★★★
()
Ответ на: комментарий от sphericalhorse

вместо return false лучше использовать e.preventDefault и e.stopPropagation

xpahos ★★★★★
()
Ответ на: комментарий от sphericalhorse

Вот, собственно код:

<script type="text/javascript">
// код, который уже висит на кнопке
	initQuickReply: function()
	{
		if($('quick_reply_form') && use_xmlhttprequest == 1)
		{
			Event.observe($('quick_reply_submit'), "click", Thread.quickReply.bindAsEventListener(this));
		}
	},

	quickReply: function(e)
	{
		Event.stop(e);

		if(this.quick_replying)
		{
			return false;
		}

		this.quick_replying = 1;
		var post_body = Form.serialize('quick_reply_form');
		this.spinner = new ActivityIndicator("body", {image: imagepath + "/spinner_big.gif"});
		new Ajax.Request('newreply.php?ajax=1', {method: 'post', postBody: post_body, onComplete: function(request) { Thread.quickReplyDone(request); }});
		return false;
	},
</script>

<script type="text/javascript">
// мой код, до которого дело доходит, когда уже данные улетели аяксом.
document.getElementById('quick_reply_form').onsubmit = function() {
	if (<some_check>)
		return true 
	else
		return false;
}
</script>
<form method="post" action="newreply.php?tid=2&processed=1" name="quick_reply_form" id="quick_reply_form">
	<textarea style="width: 100%; padding: 4px; margin: 0;" rows="8" cols="80" name="message" id="message" tabindex="1"></textarea>
	<input type="submit" class="button" value="Post Reply" tabindex="2" accesskey="s" id="quick_reply_submit" />
</form>

Вставить сюда onsubmit = false - не поможет, так как данные отправляются не формой, а ивентом на кнопке.
Менять форму и/или коментить скрипт - тоже не стоит - пишу плагин, и чем меньше он затронет в родном коде - тем лучше.



[offtop]работаю пых-пых кодером, три недели) js вижу практически в первый раз ( [/offtop]

spdooh
() автор топика
Ответ на: комментарий от spdooh

А доки фреймворка который тут используется не курил? Может он даёт доступ к привязанным обработчикам.

Как вариант, можно валидацию проводить по keyup текстареи (change не прокатит) и переключать кнопку из disabled если всё в порядке.

Ну или делегироваться на контейнер и лочить кнопку/ставить use_xmlhttprequest в false.

Kalashnikov ★★★
()
Ответ на: комментарий от Kalashnikov

Конечно не курил, как только проблема - сразу на форум)
Собственно, в доках prototype не нашел описания перехвата - все-таки это не сильно часто надо.
на textarea не получится привязаться - проверка делается не по нему.

ставит use_xml... в false - надо до того, как прибиндится листенер - а это, насколько понимаю делается в самом начале

Лочить кнопку - это сделать так, чтоб она не смогла вызвать событие «click»?
А submit формы будет происходить, если кнопка залочена?
А то если будет, тогда надо будет только в своем скрипте после провеки произвести emit(«click»).

spdooh
() автор топика
Ответ на: комментарий от spdooh

ставит use_xml... в false - надо до того, как прибиндится листенер - а это, насколько понимаю делается в самом начале

Насколько можно судить по этому куску, флаг глобальный.

Лочить кнопку - это сделать так, чтоб она не смогла вызвать событие «click»? А submit формы будет происходить, если кнопка залочена?

Это я про аттрибут disabled=«disabled». С ним на неё кликнуть нельзя будет. Соответственно и форму отправить никак нельзя (по крайней мере в случае с одной текстареей).

Ещё вариант - переопределить Thread.quickReply добавив туда валидацию.

Kalashnikov ★★★
()
Ответ на: комментарий от spdooh
document.getElementById('quick_reply_form').onsubmit = function() {
    if (<some_check>) {
        send()
    }
    return false
}
sphericalhorse ★★★★★
()
Ответ на: комментарий от sphericalhorse

мне нужно убрать EventListener, выполнить свою проверку и запустить то, что забиндено на листенер чтоб оно выполнило отправку.

Иначе данные отправляются аяксом в quickReply и до моей проверки уже не доходит.

spdooh
() автор топика
Ответ на: комментарий от Kalashnikov

Ещё вариант - переопределить Thread.quickReply добавив туда валидацию.

А его можно переопределить, но старую сохранить под каким-либо псевдонимом, чтоб потом можно было вызвать?

spdooh
() автор топика

И вот ещё хинт тебе на будущее: данные передаються по значению (то есть строки, числа, булевские значения, etc.), всё другое - по ссылке (функции, объекты, массивы, елементы ДОМ, etc.).

sphericalhorse ★★★★★
()
Ответ на: комментарий от sphericalhorse

action будет undefined. В 21м веке в атрибуты обработчики никто не ставит. И ты это зря делаешь.

spdooh

старую сохранить под каким-либо псевдонимом, чтоб потом можно было вызвать?

Ну, эээ, положить её в переменную и вызывать через эту переменную, так-же как у Коня выше.

Kalashnikov ★★★
()
Ответ на: комментарий от sphericalhorse

Сначала не понял, в чем отличие с тем, что было, потом разобрался.
Да, именно то, что надо!

про значения и ссылке - логично (главное, чтоб разработчики языка так думали)

spdooh
() автор топика
Ответ на: комментарий от Kalashnikov

Ага, разобрался.
Завтра буду докуривать маны и основы js'a и, надеюсь, доделаю.
Спасибо обоим!

spdooh
() автор топика
Ответ на: комментарий от Kalashnikov

action будет undefined.

Тогда так:

var action = document.getElementByID('ИДформы').onsubmit

document.getElementByID('ИДформы').onsubmit = function() {
    if(<some_check>) {
        if (action) {
            return action()
        } else {
            return <...>
        }
    } else {
        return false
    }
}

или так:

var action = document.getElementByID('ИДформы').onsubmit || function() {return <...>}

document.getElementByID('ИДформы').onsubmit = function() {
    if(<some_check>) {
        return action()
    } else {
        return false
    }
}

или так:

var action = document.getElementByID('ИДформы').onsubmit

document.getElementByID('ИДформы').onsubmit = function() {
    if(<some_check>) {
        if (action) action()
        return <...>
    } else {
        return false
    }
}
sphericalhorse ★★★★★
()
Ответ на: комментарий от Kalashnikov

А андефайнед он будет потому-что обработчик вешается как рах таки через addEventListener и в onsubmit не будет ничего.

Как тогда предлагаешь его снять?

Да и вообще, вешается он на клик кнопки, а не сабмит формы.

Кто именно? Где именно?

sphericalhorse ★★★★★
()
Ответ на: комментарий от Kalashnikov

Я эти ваши прототайп не перевариваю. Розбирайтесь сами, я тут ничем помочь не могу.

sphericalhorse ★★★★★
()
Ответ на: комментарий от sphericalhorse

Кто именно? Где именно?

spdooh

Вот, собственно код:

Event.observe($('quick_reply_submit'), "click", Thread.quickReply.bindAsEventListener(this));

Линк на код Event.observe я выше уже кидал.

Как тогда предлагаешь его снять?

Это то и есть весёлая часть. На чистом жс можно было бы

form.removeEventListener('click', Thread.quickReply);
в прототайпе должна быть какая-нибудь обёртка, но я его не знаю.

Kalashnikov ★★★
()
Ответ на: комментарий от sphericalhorse

Прототайп - это для тех, кто пишет для форумов, написанных с использованием прототайпа)

spdooh
() автор топика
Ответ на: комментарий от Kalashnikov

Я, собственно, понял, что код коня сверху в лоб не используешь - что там все на onsubmit завязано.
Главное сам смысл - сохранить функцию в переменную и потом через нее вызвать.

spdooh
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.