So I use this Javascript to handle forms:
$(':submit:not(.form-default-submit)').click(function(event) {
//Disable normal form submission, handle using ajax
});
It works correctly in most cases. So any submit element with the class form-default-submit is ignored, and all others are handled in this Javascript.
But I've just noticed that this doesn't work for Ajax-generated content. Which I'm guessing is because this code is run on page load, before the Ajax content is loaded.
I see people using:
$(document).on("click", selector, function(e){
As a fix for this. But in my case, I don't just apply it to the element directly. I have that condition to allow exceptions for elements with the class form-default-submit.
Is the only way to do this with the new Ajax-supported method to have an if statement within the function checking if the element has a particular class? Or can I do this within the selector itself? This is a bit above my current ability, so thanks for any help!
Try this:
$(document).on( "click",":submit:not(.form-default-submit)", function(e){
You can bind the submit event directly to the form and return false. This will also catch a form sent by using the enter key.
$("#form").on("submit", function(event){
// Send form data by AJAX
$.post(...);
// Prevent form to be sent the regular way
return false;
});
Related
I am using following code on my page which I am loading in ajax.
$(document).ready(function() {
$('#button_id').click(function() {
//Do Something
});
});
Now When I click on the button action happens multiple times. I know that its happening because I am loading the ajax page multiple times.
Please help me solve this.
You can use .off() to remove existing listeners:
$(function() {
$('#button_id').off('click').click(function() {
//Do Something
});
});
If I am wrong about your implementation I apologize. Your problem may exist because the binding is created on first page load and then on subsequent ajax loads with new scripts being inserted and creating duplicate bindings. You should prevent any bindings from being generated on ajax loads to prevent duplicate bindings unless you are good with cleanup.
If the button you are clicking on exists in the ajax loaded area then you should use delegation to ensure that the click handlers still work.
For example:
$( "body" ).on( "click", "#button_id", function() {
//do something
});
This will add a binding to the body element, but more specifically to the id #button_id. A click event on the button will propagate and bubble up to the body element (or whatever parent element you choose).
This makes it so that dynamic elements can be inserted in the DOM and only one event handler is needed to listen for it.
No need for .on() or .off() calls for individual ajax loads. This allows your bindings to be much cleaner.
Of course, if your button is not likely to exist on the page all the time then it would not be a good idea to keep extra bindings. Only create these types of binding if they are always needed to prevent optimization issues.
A cleaner solution would be to remove that code from the ajax loaded HTML and use one single event handler in the master page
I guess your problem is the event is firing many times.
To fire only once try this:
$(document).ready(function() {
$('#button_id').on("click",function(e) {
e.preventDefault(); // This prevents the default non-js action (very used for anchors without links or hashes)
e.stopPropagation(); // Prevent the bubling of the event and spread more times
//Do Something
});
});
If doesn't work with e.stopPropagation(); try with e.stopInmediatePropagation();
Adding documentation for the last method I suggested. It could solve your problem.
http://api.jquery.com/event.stopimmediatepropagation/
I am submitting a form using JQuery and an event listener bound to a div (not an input field) and I am trying to prevent multiple submits, so the customer does not get overcharged. I am trying to accomplish this by removing the submit-button class of the clicked div, so the next time the user clicks it, JQuery won't listen to the event that is associated with the submit-button preventing multiple submits.
Using the implementation below however, for some reason, does not prevent multiple submits, as intended.
HTML
<div class="submit-button button-style">Submit</div>
JQuery
$(".submit-button").click(function(){
$(this).removeClass("submit-button");
//**submit form**
});
NOTE: I must stick to a solution that uses the html above, so solutions using an input element of type submit, will not be useful.
I appreciate any suggestions on how to make this work. Many thanks in advance!
You can make use of .one() to prevent it from firing multiple times -
$(".submit-button").one('click',function(){
//**submit form**
});
http://api.jquery.com/one/
Edit :
In case of error :
function submitForm(){
//**submit form**
$.post('submit.php').error(function(){
// rebind event on error
$(".submit-button").one('click',submitForm);
});
}
$(".submit-button").one('click',submitForm);
You could use something like:
$('something').one('click', function(){
// submit code
});
Which will only fire once.
A significant portion of users don't bother clicking the submit button to submit a form - there's other more convenient ways, like hitting the enter key when the cursor focus is on a form field.
A more robust approach is to block the form via the forms submit event, and maintain a variable to keep track of the form submission state.
var submitted = false;
$("form#myForm").submit(function(evt){
if (submitted) {
evt.preventDefault();//stops form submission
return;
}
submitted = true;
});
I omitted form validation for this example.
So i have a form which i submit using jquery post method, and replaceWith the content of the division with the ajax returned data. Here is the code:
$(".filter_field").change(function() {
$.post("/business/feedbacks/", $("#filter_form").serialize(),
function(data) {
$('#table-content').replaceWith($('#table-content', $(data)));
});
});
Now i am facing two problems with this method:
1) I am also using a reset button which just reset the form's fields values to initial values and then trigger the change event like in the following code:
$('#filter_reset').click(function () {
$(':input','#filter_form')
.not(':button, :submit, :reset, :hidden')
.val('')
.removeAttr('checked')
.removeAttr('selected');
$(".filter_field").trigger('change');
});
Now whenever i click the reset button, it resets the form's fields and submits the form using ajax via a change event described above. So far so good, but now i am unable to trigger the change event anymore. Now matter which field i click on now in the form, it just doesn't submit the form anymore using ajax.
2) I have a soundmanager plugin installed in the #table-content division (multiple instances of it). Now after the ajax submit, that soundmanager plugin stops working, because i assume, as the soundmanager is loaded at ready event, it does not execute after the ajax submit and replaceWith, hence it stops working.
Any solutions to circumvent these issues? I am new to query, so sorry if i am doing the things wrongly, please guide me in right direction. Thanks a lot in advance.
Edit: It turns out that if i include $.getScript("/static/js/360player.js"); it works properly. Isn't there a method to attach the events to the elements replaced with using jquery replaceWith command. 'On' event doesn't seem to work at all.
Edit2: It turns out that i was using 'on' on a wrong division. My bad :(
When you replace the elements you also remove any attached event handlers. You need to use delegation to bind the event handler to existing elements and future elements...
$("body").on("change", ".filter_field", function() {
$.post("/business/feedbacks/", $("#filter_form").serialize(),
function(data) {
$('#table-content').replaceWith($('#table-content', $(data)));
});
});
Not sure about your second issue, but it sounds like a similar approach is required for that as well.
I've created a page in which I use a JavaScript validator on the input fields (using a script from javascript-coder.com), but I can't use my to submit the form, because it's conflicting with a function the validation script is using. My current submit button:
Submit
When i use a standard HTML submit button, the script works fine. Is there any other way or function to submit the form without conflicting with the validation script? I'm not confident enough in JS to begin taking the validation script apart.
Please help, and please ask if you need any additional info.
Thanks,
If that is your actual code, you are using the this keyword incorrectly. When called from an inline function, this refers to the element is is being called from, i.e. the anchor tag. (See here for more details: http://www.quirksmode.org/js/this.html.) As far as I am aware, you need to submit the form from the form tag.
What you should be using is something like one of these:
document.getElementById('myForm').submit();
document.forms[0].submit();
document.getElementsByClassName('submit')[0].submit(); /* not IE8 compatible */
Alternatively, if you cannot rely on your element having an ID tag, being in a known order on the page and you require IE compatibility, you could continue searching "up" the DOM until you find the form that the button sits in, then submit that:
var parentelem = this.parentNode;
while (parentelem.nodeName.toLowerCase() != 'form') {
parentelem = parentelem.parentNode;
if (parentelem == null) { break; }
}
if (parentelem != null) {
parentelem.submit()
}
Try this
Submit
The validation script uses the onsubmit event of the form to trigger the validations. When you submit the form programatically, the event does to get fired. This should work:
Submit
where yourform is the ID of your form. See this page for details:
http://www.javascript-coder.com/javascript-form/javascript-form-submit.phtml
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>