I'm learning how to use jQuery and I'd like to understand what the purpose of using the off() method before submitting a form is. For example, in the following code, the form is first prevented from sending using preventDefault(), some Ajax is done and when finished, the form is finally submitted. But why do I need to use off() before submit()?
$(document).ready(function() {
$('form[name="Payment"]').on('submit', function( e ) {
e.preventDefault();
AjaxCall();
$(document).ajaxStop(function() {
$('form[name="Payment"]').off('submit').submit(); // Once Ajax request are finished, submit the form.
});
});
});
Because triggering the same event would run all that same event handler code again.
The default would always be prevented, the ajax would be called ....and then the event would be triggered again and you would have an infinite loop without changing something.
Removing the event listener would make any subsequent submit use browser default process
There are other ways around this...but this answer explains what was asked
Related
I have action what first need to render form by ajax and then need to update existing values. I already get rendered form with proper values, but when I click to submit form by ajax I cant prevent form submission, I have this script:
$('#edit-comment').click(function (e) {
e.preventDefault();
console.log(1);
});
But submitting with still work ! What I am doing wrong. And I dont know how I need to handle submitted form in the edit action. Here is existing part of it:
/**
* #Route("/edit/comment", name="chat_edit", options={"expose"=true})
*/
public function editAction(Request $request)
{
$comment_id = json_decode($request->getContent(), true)['commentId'];
$comment = $this->get('comment.repository')->find($comment_id);
$form = $this->createForm(new CommentType(), $comment);
return $this->render("ChatCommentBundle:Comment:form.html.twig",
array('form' => $form->createView())
);
}
Link to gist with form type
Update:
The original answer (below) still applies, but given that the form is actually loaded using AJAX, you can't bind the event listeners in the $(document).ready callback. The best option for you is to use event delegation. This is done by attaching an event listener to a DOM element that does exist from the start, but have that listener pick up on events for elements that might be added later on. For example: the body element will always exist, so you can listen for a form submission there, whether or not that form exists doesn't matter:
$('body').on('submit', '#form-id', function(e)
{
console.log('#form-id was submitted, do AJAX => submission stopped');
return false;
//or
e.preventDefault();
e.stopPropagation();
});
The why and how this works is very well explained here. It boils down to the fact that all events pass through all of the parent DOM elements of the target node, so you can attach listeners anywhere in the DOM, and handle the events before they reach their target.
I think this old answer of mine might explain a thing or 2, too. It doesn't use jQ, but it contains a simplified version of the code that jQ uses internally for delegation.
You're preventing the default effects of the click event on $('#edit-comment'), but that event still propagates through to the form. You might want to add e.stopPropagation(), too. Or simply return false; from the callback (which prevents the default and stops propagation).
However, a better way to prevent the form from being submitted is to use the submit event, and stop the submission there:
$('#form-id').on('submit', function(e)
{
console.log('Do ajax call here');
return false;
//or
e.preventDefault();
e.stopPropagation();
});
I'm newbie in jquery and saw a piece of code with something strange given the functionality of a method, the "preventDefault". Well, to test, i created a test page and made two functions with "preventDefault" inside of it.
I have two questions on the same subject, i hope you can answer me.
$(document).ready( function( ) {
$('a').click( function( event ) {//Func 1
event.preventDefault( );
});
$("#ok").click( function( event ) {//Func 2
event.preventDefault( );
alert("Wut");
//...
});
});
1- Why, in the second function, the "alert( )" runs even if i comment "event.preventDefault( );" and the first function does not happen the same? If i comment "event.preventDefault();" in the first function, the link doesn't work!
I found it strange because regardless of the method "event.preventDefault();" whether or not commented in the second function, the "alert" works the same way. I think even what comes after "alert" would run.
2- What is the real utility of this method, "event.preventDefault ();"? Why, in the second function, it seems to be useless. Can you give me some example of when it might be useful?
Thanks!
The purpose of preventDefault is to prevent the browser's default action related to the event. Your alert isn't the browser's default action, and is unaffected. Following a link is the browser's default action, and so preventing the default prevents following the link.
preventDefault is crucial in many situations. For instance, when handling a form's submit event, we need preventDefault (directly or indirectly) if we do client-side form validation and the form isn't valid; otherwise, the browser would submit the invalid form.
(I said "directly or indirectly" above because jQuery handles the return value of event handlers in a special way: If you return false, it calls preventDefault and stopPropagation for you.)
It prevents the default action of the control. If it a link, it stops the link being followed. If it is a form submission, it prevents the form from being submitted.
It doesn't interact with other JS event handlers on the same element.
Examples of situations where you might use it:
Stopping the browser following a link because you have used Ajax and pushState to load the content and update the URL
Stopping the browser from submitting a form because you have tested the data entered and found a problem with it
The .preventDefault() function prevents the browser from carrying out the normal implicit behavior of an interactive element. If you click on an <a> tag, then apart from anything your JavaScript does the browser will attempt to follow the "href" value and reload the page. That's the "default" behavior that the function name refers to.
Your alert() runs because .preventDefault() has nothing to do with the code in your event handler. If you want to "abort" an event handler, you'd just return from it.
Note that jQuery also gives you .stopPropagation() and .stopImmediatePropagation() to cancel the process of event bubbling. Those also have no direct effect on the code in your event handler.
event.preventDefault() disables the default behaviour of the event. In case of an link the redirect. It does not effect your own code, in this case the alert() call.
I've got a web app which I'm trying to make run as fast as possible, one of the ways is by reducing the amount of event listeners I have attached.
I have a lot of forms (around 12). I currently check if they are submitted with:
$('#form-id').on('submit', function(){
//actions here
});
for each form. Is there a way I can do this but with only attaching one listener for a submit? and then doing a switch statement based on the forms ID to decide what actions to do?
Use delegation for submit event for all selected forms. $(this) will be the current form.
$(document).on("submit", "form", function () {
// actions here
// $(this).something...
return false;
});
return false is used to prevent the default browser behavior.
Use event delegation
$(document).on('submit', 'form', function(e) {
e.preventDefault();
// ....
});
This adds just one listener to the document which gets called anytime a form is submitted.
You can use
$('form').on('submit', function() {
//you can use $(this).attr('id') to get id of submitted form
}
to catch submit event for all form.
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.
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
}