Preventing an event before other callback finished - javascript

I have an application that uses backbone.js and jQuery for UI. I have a form on a page, attached to the form's text box blur event is a function that under certain conditions shows the user a popup and awaits it's input - the conditions are checked using an ajax call to a WCF service.
Everything works fine until i click the form's submit button while the focus is set on the text field - then the popup is displayed but behind it the form is submitted.
Of course the proper result would be cancelling the second event(if the popup is displayed the form definitely cannot be submitted)
How can I achieve this?

i can'T understand you but probably this is what you need: event.stopPropagation();
http://api.jquery.com/event.stopPropagation/
Or .off()
http://api.jquery.com/off/

You can bind to the submit event of the <form> and call its preventDefault() method to inhibit submission if the popup is visible:
$("form").submit(function(e) {
if ($("selector_matching_your_popup").is(":visible")) {
e.preventDefault(); // Cancel submission.
}
});
You can also return false from the handler instead of calling preventDefault(), but this will also stop the propagation of the submit event to ancestor elements, which you may not want.

Are you saying that the clicking of 'submit' is causing the popup to display - and this is not one of the 'certain conditions' where it should be displayed? I would consider adding a condition to the blur handler that checks to see if the submit button was clicked. Dont display the popup in this case.
Cancel the event in the onSubmit handler -
form.addEventListener("submit", function(evt){
evt.cancel()
//dont want to catch it again
form.removeEventListener(this)
popup.show()
//have the popup call submit when done, it wont be caught again
}

Related

Binding to the click event of a submit button, will our JS run before the form submits?

We are currently binding to the click event of a submit button (there are reasons why we are not binding to the submit event for the form). Is it guaranteed that our JS will run before the form submits (as we are entering values into hidden fields that we want to submit) or do we need to prevent the form from submitting and then call the submit again?
$(function() {
$('#button').on('click', function() {
// Do some stuff here - needs to finish before the form submits
return true;
});
});
Thanks in advance!
It will work before the submit event is sent, but you are only listening for the click event. If the user hits enter, the form will be submitted without running your code. I think you should stick to the submit event. The callback function will receive as argument the event (and you can do things like e.preventDefault(); or e.stopPropagation();
$("form").on("submit",function(event){});
In my expierience the code in the click event will always run first.
I just ran a simple test on latest chrome with a loop that loops 10,000 times. The form did not submit until after the loop was finished (~5 seconds).
If you try to run some ajax call, or setTimeout in the click function though, the form will most likely submit before your callback/ajax is finished.

html-javascript: page refreshes whenever an event is fired

I have an html page with buttons and such, to which I assign event listeners. Whenever one of the buttons is clicked, the page goes back to its original state, as if the browser had been closed and opened again. So if I have text fields into which I've inputted some info, they will be cleared as soon as a button is clicked, even if its event listener does nothing.
Likewise, if I include this event listener into the html, <body onload="pageLoaded();">, the pageLoaded() function will be called whenever a button is clicked.
Why is this happening, and how can I prevent it from happening?
Presumably you are using submit buttons, which will submit the form they are in unless you cancel the default action.
eventObject.preventDefault();
See the documentation.
Maybe your click event listener was added to a link or a button within a form. If so, you may add return false a the end of the listener to prevent the default behaviour being executed.
var link = $("#mybutton");
link.click(function() {
alert("clicked");
return false;
});
Setting the button type to "button" will resolve this issue. The default type is "submit" which as the others have said will submit the form.
<button type="button">Button</button>

JQUERY click handler from DIFFERENT element triggered on enter?

URL is here: http://prorankstudios.com/sandbox/wtf/
Using IE9, with focus on the User or Pass field, hit the ENTER key...
Notice that this whole page reloads.
What's happening is that the click handler for the #live_site_link (assigned on line 30 of common.js) is running when no click has happened on #live_site_link at all...
Login Submit code:
Login.Submit = function(e)
{
Login.feedback.empty();
if (Login.user.val() == '')
{
Camo.ErrorAlert('Invalid username.',Login.feedback);
Login.user.focus().select();
return false;
}
if (Login.pass.val() == '')
{
Camo.ErrorAlert('Invalid password.',Login.feedback);
Login.pass.focus().select();
return false;
}
Camo.AJAXStart('Logging in...');
postData =
{
user:Login.user.val(),
pass:Login.pass.val()
}
Camo.AJAXPost('index/login/',Login.Success,Login.Failure,postData);
return false;
}
live_site_link click handler:
$('#live_site_link').click(function()
{
window.location.href = './';
});
In fact, the handlers for the login form (both a keyup and a click on Go button assigned in login.js lines 22 and 24 respectively) sometimes run AFTER the page has reloaded, strangely enough.
In IE7/compatibility mode, the keyup and click handlers for login_submit properly work and the page does not reload. This is also the case in all other browsers I tested.
What is IE9 doing?
Try calling e.preventDefault() or e.stopPropagation() before you return false in Login.SubmitOnEnter
It would be better though if you wrapped a form around your form elements, then attached an event for the form submit. That way it will still work without javascript and you wouldn't have to have a separate event for click and enter press.
The only "fix" for this I could figure out short of changing the live site link button to a regular anchor tag was actually to enclose the login fields and button inside form tags.
Apparently without those enclosing form tags, IE9 is using the live_site_link button instead of the GO button to submit the form on a natural enter key press before the keyup handlers on the inputs and the click handler on the Go button of the login form ever get a chance to trigger, which causes the page to reload (as that's what the click handler for live_site_link does).
Now I have to handle logins without AJAX...
You would probably manage the login submittal process easier by using a submit handler rather than needing to catch enter key and make it click on submit button. Seems like extra code to work around doing it a simpler way
$('form').submit(function(){
var valid=someValidionFunction();
return valid;
})
Edited due to no ajax

ASP MVC3: Disable unobtrusive validation on the onsubmit event

I'm having a performance problem due to a big form I have where there is a table that can contain 100+ records. The reason is that when I submit the form the validation for every single item is fired and this is causing a 5s delay which is unacceptable.
Is there a way to disable this just for this event in this form? I'm performing the validations on the onblur event and on the serverside, so I think it will be safe if I just skip it on the onsubmit event.
I've tried the following and it has not worked:
//1
$.validator.setDefaults({
onsubmit: false
});
//2
var validationSettings = $.data($('form')[0], 'validator').settings;
validationSettings.onsubmit = false;
//3
$("form").validate().cancelSubmit = true; //This is on the onclick of the submit button
If you add the class cancel to your submit button, that will signal jquery.validate.js that validation should not be done when the submit button is clicked.
UPDATE
jquery.validate.js contains the following:
// allow suppresing validation by adding a cancel class to the submit button
inputsAndButtons.filter(".cancel").click(function () {
validator.cancelSubmit = true;
});
Based on the behavior you are reporting, you must have something else attached to your submit event which is overriding the behavior of jquery.validate for a submit button with the cancel class.
Please examine each step in the image you posted of the event progress. There is almost certainly something in that tree which will indicate where the default behavior is being overridden.

How can I trigger an element's default event within an event handler?

I have an HTML button that needs to check several conditions, and if they pass allow the default action to occur.
The following works in Firefox, but it fails in IE. I setup a click handler on the button:
Ext.get('send').on('click', handleSend, this, {
preventDefault: true
});
which pops up one of several message boxes if one of the conditions isn't met. If all conditions are met, I remove the click listener from the button and click the button again:
Ext.get('send').un('click', handleSend, this);
Ext.getDom('send').click();
As far as I can tell, it fails in IE (and possibly other browsers) because click() isn't a standard function for a DOM element.
If the default action were a simple form submit, I could just do that after the checks pass, but we're using Tapestry 4 with a listener, which doesn't get executed on a normal form submit.
I've tried submitting the form with
tapestry.form.submit('composeForm', 'doSend');
but the doSend listener isn't getting called.
Conditionally allowing the default event is the best solution I've come up with, but there are a couple of options that may be possible:
Is there some other way to cause a Tapestry 4 listener to be fired from within Javascript?
Is there any way to recognize the normal form submit in my Tapestry Page and thereby trigger the listener?
JSFiddle added
In this jsfiddle, the default action is to submit the form; this is prevented when the checkbox is unchecked. When checked it removes the handler, but the call to click() doesn't work in IE.
Is there a way to simulate a click in IE?
Update
Another snag in the problem is that I have to display an 'are you sure' dialog, so in order to give them time to answer, the event has to be stopped. If they click OK, the default action needs to occur. JSFiddle doesn't seem to have ExtJS widgets like MessageBox, so I'm not sure how to demo this behavior.
At #Ivan's suggestion I tried
Ext.getDom('send').fireEvent('onclick');
but it returns false, meaning the event is being cancelled somewhere. I then tried
var evt = document.createEvent("Event");
evt.initEvent('click', false, false);
var cancelled = Ext.getDom('send').fireEvent('onclick', evt);
but IE9 says that document.createEvent doesn't exist, even though this is how MSDN says to do it.
If all conditions are met, I remove the click listener from the button
and click the button again:
Don't.
You should rather check the conditions in the click handler and call stopEvent there like so:
Ext.get('send').on('click', handleClick);
function handleClick(e) {
if (condition) {
e.stopEvent();
}
}
Internet explorer does not support click. You should use fireEvent method instead e.g.
Ext.getDom('send').fireEvent('onclick');
That should work for IE. For other browsers I guess click is ok. Anyway If I should do similar task I'll try to write an adapter for tapestry and use tapestry javascript library.
There's a listener parameter on Form components; from the Tapestry 4 doc:
Default listener to be invoked when the form is submitted. Invoked
only if another listener (success, cancel or refresh) is not invoked.
Setting this parameter to my listener method like so:
<binding name="listener" value="listener:doSend" />
causes a Tapestry form submit
tapestry.form.submit('myFormId');
to trigger the listener.

Categories

Resources