So, I've got a tampermonkey script being injected into Twitter, and I want to add action to the beginning of an eventqueue when the Tweet button is clicked. So far, I have my action firing, but return false; and e.preventDefault() neither one stop the form from submitting when adding a click listener to the button or a submit listener to the form. The submit listener event never actually is triggered, but the button one is. So, my question is, what's the best way to make sure:
My action happens first
No other actions happen until my ajax is done
I can't seem to stop or find the way that Twitter is submitting the tweet. Unfortunately, my action fires off an ajax call and that ajax call doesn't call its done callback until after the tweet is submitted.
UPDATE: I've also tried e.stopImmediatePropogation() to no avail..
This is only a guess and maybe not that much helpful, but i think on the submit is already a linked javascript eventListener/function from Twitter.
Don't know if this is part of the problem how you can handle this.
See (open the browser console to see the output):
var myApp = new function() {
this.init = function() {
var myForm = document.getElementById('myForm');
//first eventListener
myForm.addEventListener("submit", function(e){
e.preventDefault();
console.log('submit');
});
//second eventListener
myForm.addEventListener("submit", function(e){
e.preventDefault();
console.log('submit2');
e.stopPropagation();
return false;
});
}
};
myApp.init();
<form id="myForm">
<input type="submit" value="click" />
</form>
Edit: i found this and it's possible helpful:
How to find event listeners on a DOM node when debugging or from the JavaScript code?
Related
Bare bones Example:
<form id="tForm">
<input type="submit" id="tSubmit" value="Submit">
</form>
<script>
$(document).on( 'click','#tSubmit', function(e) { someFunction(<fire-and-forget-action)});
</script>
Usage scenario:
1.) User clicks form Submit button
2.) someFunction( ) is called
3.) tForm is submitted as the default behavior of the HTML input element of type=submit.
Am I guaranteed that the someFunction( ) call will happen before the submission of tForm? There has been an issue raised that the possibility exists that the someFunction( ) call would not complete before tForm is submitted and a new page is rendered.
If the function fire-and-forget-action is an asycronous request then all bets are off.
You need to prevent the form submission (return false or call preventDefault() on the event argument) and execute it once the inner function has completed. You might, for example, have to refactor the 'fire and forget action' to do this, but without a big more information about what it contains, it's hard to help further.
Note that even then you have an issue where the form can be submitted in other ways. You're shadowing the submit click action, but there are other ways to submit the form. Ideally you'd observe the form submit event instead.
Here is a slight abstract example of how you should do it:
$('#theForm').submit(function(e) {
var f = this;
setTimeout(function() {
f.submit();
}, 1000);
return false;
});
The setTimeout is basically equivalent to some asynchronous request happening outside of the original handler. The point is, the inner function knows about the original form and submits it when complete.
I am trying to disable the default confirm box that fires onSubmit. I have been trying for a while now with no success. This is what I tried...
My Markup
<form method="post" action="special.php" id="myForm" onsubmit="return confirm('Are you sure you ready to submit this order?\n\n')">
//input fields
</form>
My JavaScript
$('.excelDL').click(function(){
$('#myForm').trigger('submit', function(e){
window.alert = function() {}; //overwrite default alert
$.post('mail.php', $(this).serialize(), function (data) {})
e.preventDefault();
});
});
The confirm box appears because of the onsubmit="return confirm(...)" attribute on your <form>. If you remove that, the confirm dialog will not appear when you submit the form via JQuery.
If you need this confirmation to appear except when submit the form using your $('#myForm').trigger(...) code, then remove your window.alert = function() {}; line and add the line $('#myForm').submit(function(){ return true; }); before you call .trigger(). This will remove the onsubmit handler for the form before submitting it.
It's generally a bad idea to try to override the built in methods (like confirm()) it's a much better idea to just not call them.
To begin with you're not firing an alert, you're firing a confirm. so change
window.alert = function() {};
to
window.confirm = function() {};
then move it outside the submit function so that it overwrites the native function before the submit happens.
The jQuery docs don't mention that you can pass a function to .trigger as second parameter and I don't believe it actually works.
If you just want to make the Ajax request without triggering .submit, you can make the call directly
$.post('mail.php', $('#myForm').serialize(), function (data) {});
or trigger only event handlers bound with jQuery using .triggerHandler. In both cases a native submit event won't generated and event handlers bound with other ways won't be triggered.
As others said, binding all event handlers with jQuery instead of using inline event handlers would improve the code as well.
just take this out
onsubmit="return confirm('Are you sure you ready to submit this order?\n\n')"
then you can manually decide when to use the alert in this function
$('#myForm').trigger('submit', function(e){
// cal the confirm here , or write your own pop up script that looks the way you want.
});
Is there any way we can intercept the html form's onsubmit event?
In my web application, there are several screens containing forms etc. The issue we are facing is when the user presses any button multiple times, the server gets overloaded with same requests.
Some of the forms have event handlers already attached to them(like onSubmit, button.onClick etc).
One way can be to "inject" my button disable code by going through all the screens.
But what I am looking for is a generic solution which can be applied to all the screens by just including the script where the function is written.
I know I can setup callback using jQuery (capturing onSubmit for form), but in the issue in this case is if any screen has a onSubmit registered already, it may not get called.
Any help in this regard appreciated!
I think this piece of code is a good place to start. It should be placed in separate file and included where you want to use it (if you appear to have global list of scripts - its a good place for it)
var suppressed_items = [];
function allowOnlyOne(item,e){
if (jQuery.inArray(item, suppressed_items)==-1){
//hi little item, I haven't saw you before, please go on... but I remember you
suppressed_items.push(item);
return true;
}
else{
//Hey, you have been submitted already, stay where you are!
return false; //or e.preventDefault(), it's a matter of faith :)
}
}
jQuery(document).ready(function(){
//don't worry, it won't replace your `ready` handlers, but just append new handler
jQuery("from").submit(function(e){
return allowOnlyOne(jQuery(this),e);
});
});
You can use the allowOnlyOne function with any item you wish. So, for example to allow single click on all hyperlinks, inside that ready handler add:
jQuery("a").click(e){
return allowOnlyOne(jQuery(this),e);
}
I hope you get the basic idea: catch the event, get the ID of the element that trigger it, fed it to AllowOnlyOne along with event.
Of course you can wrap it all around into self-executing closure to achieve incapsulation and so on...
If you already have jQuery I suggest you use it... All you need to do is make sure is that your form's onsubmit do not have a "return false" or else it can block jQuery's on submit.
Here's what you need to do:
Remove any return false from your form's onsubmit (if any). Don't worry we'll take care of this later in jQuery.
Add a class to your forms... something like "disableOnSubmit". Example:
<form action="something" onsubmit="yourExistingCode" class="disableOnClick">
</form>
OR
<form action="something" onsubmit="yourExistingCode" class="someOtherClass disableOnClick">
</form>
Implement a code similar to:
<script type="text/javascript">
$(document).ready(function(){
$('form.disableOnClick').submit(function(e){
// preventDefault() does the same as "return false;". It
// will not submit the form. If you're not using return false
// and want the form to be submitted remove the line below
e.preventDefault();
// Now diable any submit button
$('input[type=submit], button[type=submit]').attr('disabled, 'disabled');
});
});
</script>
I have an ASP.NET Web Form application developed by another developer.
This developer made extensive use of ASP.NET controls therefore there are many automatically generated Javascript functions wired to HTML elements' event.
Now I have been asked to add a functionality: disable the submit button upon first stroke, in order to avoid the users to click several times on the button.
Here is the jQuery code that I use http://jsfiddle.net/2hgnZ/80/ and the HTML DOM is identical to the one I use:
$('#form1').submit(function(e) {
$(this).find('input[type=submit]').attr('disabled', 'disabled');
// this is to prevent the actual submit
e.preventDefault();
return false;
});
This script in my code does not work and after many attempts I am sure it depends on the JavaScript event wired to the onSubmit event of the button.
How can I postpone the execution of this Javascript on favour of the jQuery unobtrusive function?
hmm. Can you confirm that your event is firing? I cheked the submit docs, and it is bound rather than live, which is good.
How about wiring to the button, instead? It would not be perfect, because the enter key doesn't use the button, but if it works that way you'll learn something
Have you tried calling e.stopImmediatePropagation(); http://api.jquery.com/event.stopImmediatePropagation/
This piece of code delays the execution of function amount you want.
// delay code for one second
$(document).ready(function()
{
window.setTimeout(function()
{
// delayed code goes here
}, 1000);
});
This piece of code should help you get the original event and then trigger it after your desired code.
$(function(){
var $button = $('#actionButton'),
clickEvent = $button.data("events")['click'][0].handler; //saves the original click event handler
$button.unbind('click'); //and removes it from the button
//create a new click event.
$button.click(function(e){
// doWhatever we need to do
$.ajax({
url: url,
data: data,
success: function(){
$.proxy(clickEvent,$button)(e);//attach the original event to the button
}
});
});
});
I've got a page with a normal form with a submit button and some jQuery which binds to the form submit event and overrides it with e.preventDefault() and runs an AJAX command. This works fine when the submit button is clicked but when a link with onclick='document.formName.submit();' is clicked, the event is not caught by the AJAX form submit event handler. Any ideas why not or how to get this working without binding to all the a elements?
A couple of suggestions:
Overwrite the submit function to do your evil bidding
var oldSubmit = form.submit;
form.submit = function() {
$(form).trigger("submit");
oldSubmit.call(form, arguments);
}
Why not bind to all the <a> tags? Then you don't have to do any monkey patching, and it could be as simple as (assuming all the links are inside the form tag):
$("form a").click(function() {
$(this).parents().filter("form").trigger("submit");
});
If you are using jQuery, you should be attaching events via it's own event mechanism and not by using "on" properties (onclick etc.). It also has its own event triggering method, aptly named 'trigger', which you should use to activate the form submission event.
Thanks Eran
I am using this event binding code
this._form.bind('submit', Delegate.create(this, function(e) {
e.preventDefault();
this._searchFadeOut();
this.__onFormSubmit.invoke(this, new ZD.Core.GenericEventArgs(this._dateField.attr('value')));
});
but there is legacy onclick code on the HTML and I would prefer not to change it as there are just so many links.
This worked for me:
Make a dummy button, hide the real submit with the name submit,
and then:
$("#mySubmit").click(function(){
$("#submit").trigger("click"); });
set an event handler on your dummy to trigger click on the form submit button. let the browser figure out how to submit the form... This way you don't need to preventDefault on the form submit which is where the trouble starts.
This seemed to work around the problem.