Function Running Multiple Times in jQuery - javascript

I have created a function which makes an ajax request to a PHP file and then adds a product to the basket. This function works as it should on the first click, but on each subsequent click it runs the function again. So for example, on the 2nd click it runs the function twice, on the 3rd click it runs it three times and so on... The problem is reset when the page is refreshed...
Here's the on click code:
$("#add_123456").click(function () {
$("#add_123456").addClass('added');
var quantity = $("#qty_123456").val();
$('#basket_1').submit(function (event) {
event.preventDefault();
basket_add("feqf73nbdw7","123456","XYZ123","1","0.1","19.23");
});
});
Here's the function:
function basket_add(cartID, productID, code, quantity, weight, price) {
var item_add = {"Cart_ID": cartID,
"Product_ID" : productID,
"Code" : code,
"Qty" : quantity,
"Weight" : weight,
"Price" : price
};
$("#basketpop").animate({top: "40px"}, 200);
$.ajax({
url: '/templates/new/includes/ajax/add_to_basket.php',
type: 'POST',
data: item_add,
dataType: "html",
success: function(html){
$('.basket_content').empty().append(html);
$('.basket_content').css("height", "auto");
var item_add = null;
}
});
return false;
};
Don't think the issue is with the PHP file that is being called.
Cheers

Assuming the #add_123456 button is a submit button, the problem is because you are adding a new submit() handler to the form on each click of the button. Instead you only need to add the submit handler once and raise the event on the form on button click. Try this:
$('#basket_1').submit(function (event) {
event.preventDefault();
basket_add("feqf73nbdw7","123456","XYZ123","1","0.1","19.23");
});
$("#add_123456").click(function () {
$("#add_123456").addClass('added');
var quantity = $("#qty_123456").val();
$('#basket_1').submit();
});
If you are only submitting via AJAX though, you can remove the need to submit the form at all, like this:
$("#add_123456").click(function () {
$("#add_123456").addClass('added');
var quantity = $("#qty_123456").val();
basket_add("feqf73nbdw7","123456","XYZ123","1","0.1","19.23");
});

Because every time you click the #add_123456, the code $('#basket_1').submit(function (event) {...}) will be run, which will add a callback function to $('#basket_1').submit, you may want to bind the callback first, and trigger submit when click.
Something like:
$('#basket_1').submit(function (event) {
event.preventDefault();
basket_add("feqf73nbdw7","123456","XYZ123","1","0.1","19.23");
});
$("#add_123456").click(function () {
$("#add_123456").addClass('added');
var quantity = $("#qty_123456").val();
$('#basket_1').trigger('submit');
});

The issue could be created by the submit listener. A new one will be appended at every click.
Maybe you should have separate your submit listerer doing something like that:
$("#add_123456").click(function () {
$("#add_123456").addClass('added');
var quantity = $("#qty_123456").val();
});
$('#basket_1').submit(function (event) {
event.preventDefault();
basket_add("feqf73nbdw7","123456","XYZ123","1","0.1","19.23");
});
Another solution is to unbind your listener before binding:
$("#add_123456").click(function () {
$("#add_123456").addClass('added');
var quantity = $("#qty_123456").val();
$('#basket_1').unbind( 'submit' ).bind( 'submit', function (event) {
event.preventDefault();
basket_add("feqf73nbdw7","123456","XYZ123","1","0.1","19.23");
});
});

You are attaching another event handler every time the button is clicked.
Either attach the onsubmit handler outside of the onclick handler, or use
$('#basket_1').off('submit').on('submit',(function (event) {
event.preventDefault();
basket_add("feqf73nbdw7","123456","XYZ123","1","0.1","19.23");
});

Related

Adding Google Analytics event to form submit

I'm looking to add a Google Analytics event to a form that I can not access the inline html, so I can not add it as a onClick="" event straight to the html.
So my solution has been so far:
$(function() {
$(".form_submit input").on("click", function() {
dataLayer.push({
"event": "Kontakt",
"eventCategory": "Submit",
"eventAction": "Kirjuta meile",
"eventLabel": "Kirjuta meile"
});
});
});
Althought this does not seem to work as clicking the submit button possibly stops all functions and refreshes the page.
How can I run the function before submit and then submit the form after? I've been suggested using preventDefault(); and the after calling the submit again with $('form').one('submit', ... but have been unable to implement this due to lack of skill.
View site: http://avrame.com/en (the form is at the bottom of the page)
Any suggestions appreciated.
You can actually push functions to dataLayer, and it will be executed after the first event.
I would do
delegate the submit watch event to document level (see Jquery .on() submit event)
intercept the first submit, pushing event and preventing default behavior
and insert a function inside dataLayer, which submits the form again, but this time it won't be halted
The code:
window.submitGA = false;
$(function() {
$(document).on('submit','.form_submit',function(event){
if (!window.submitGA)
{
window.submitGA = true;
dataLayer.push({
"event": "Kontakt",
"eventCategory": "Submit",
"eventAction": "Kirjuta meile",
"eventLabel": "Kirjuta meile"
});
dataLayer.push(function(){
$('.form_submit').submit();
});
event.preventDefault();
}
});
});
Working solution ended up using this callback method:
var form = document.getElementsByClassName('.footer__contact form');
form.addEventListener('submit', function(event) {
event.preventDefault();
setTimeout(submitForm, 1000);
var formSubmitted = false;
function submitForm() {
if (!formSubmitted) {
formSubmitted = true;
form.submit();
}
}
ga('send', 'event', 'submit', 'Saada', 'Kirjuta meile', {
hitCallback: submitForm
});
});
Reference from: https://developers.google.com/analytics/devguides/collection/analyticsjs/sending-hits#hitcallback

Change behavior of button using AJAX

I'm trying to figure out how to change behaviour of a button using AJAX.
When the button is clicked, it means that user confirmed order recently created. AJAX calls /confirm-order/<id> and if the order has been confirmed, I want to change the button to redirect to /my-orders/ after next click on it. The problem is that it calls again the same JQuery function. I've tried already to remove class="confirm-button" attribute to avoid JQuery again but it does not work. What should I do?
It would be enough, if the button has been removed and replaced by text "Confirmed", but this.html() changes only inner html which is a text of the button.
$(document).ready(function () {
$(".confirm-button").click(function (b) {
b.preventDefault();
var $this = $(this);
var id = this.value;
var url = '/confirm-order/'+id;
$.ajax({
type: 'get',
url: url,
success: function (data) {
$this.empty();
$this.attr('href','/my-orders/');
$this.parent().attr("action", "/my-orders/");
$this.html('Confirmed');
}
})
});
});
The event handler will be still attached to the button, so this will run again:
b.preventDefault();
which will prevent the default, which is opening the href. You need to remove the event handler on success. You use the jQuery #off() method:
$(".confirm-button").off('click');
or more shortly:
$this.off('click');
You can add to your success function something like: $this.data('isConfirmed', true);
And then in your click handler start by checking for it. If it's true, redirect the user to the next page.
$(".confirm-button").click(function (b) {
b.preventDefault();
var $this = $(this);
if ($this.data('isConfirmed')) {
... redirect code ...
}
else {
... your regular code ...
}
}
You need to use .on() rather than .click() to catch events after the document is ready, because the "new" button appears later.
See http://api.jquery.com/on/
$(document).ready(function() {
$('.js-confirm').click(function(){
alert('Confirmed!');
$(this).off('click').removeClass('js-confirm').addClass('js-redirect').html('Redirect');
});
$(document).on('click', '.js-redirect', function(){
alert('Redirecting');
});
});
<button class="js-confirm">Confirm</button>

Preventing double event binding in jQuery

I have this code
$(".generate").click(function() {
$.getJSON("jsonfile.json").done(function(data) {
if (parseInt(data)>0) {
$(".mybutton").click(function() {
alert(data);
});
}
});
});
When the "generate" button is clicked, the getJSON function is called and if data says "ok" then I can press the "mybutton" to alert the data;
Only problem is if I press the "generate" button a few times (I want this to happen), the "mybutton" will alert "hello" also a number of times (depending on how many times I clicked the generate button).
I have tried e.stopPropagation(), but this did not help.
The reason is that every time you click the button .generate you add a new event handler on the element with the class .mybutton
It's not very clear what you're trying to do, but if the purpose is to store the data you get from the ajax call, you can do like this:
//data container
var localData;
//will show the actual content of the variable when .mybutton is clicked
$(".mybutton").click(function()
{
alert(localData);
});
//this will update the variable when .generate is clicked
$(".generate").click(function()
{
$.getJSON("jsonfile.json").done(function(data)
{
if (parseInt(data)>0)
{
localData = data;
//this will trigger the click event on the button .mybutton that will fire the handler with the alert
$(".mybutton").trigger('click');
}
});
});
You could unbind and re-bind the handler each time
if (parseInt(data)>0) {
$(".mybutton").off('click').click(function() {
alert(data);
});
}
What if you try it this way? (Didn't test this, but should work)
$(".generate").click(function() {
$(this).unbind('click').next()
$.getJSON("jsonfile.json").done(function(data) {
if (parseInt(data)>0) {
$(".mybutton").click(function() {
$(this).unbind('click').next()
alert(data);
});
}
});
});
Why do you always rebind the event. Is the button removed from the DOM after you click the generate button?
If not you could only bind the event once and just disable the button while no data is available:
$(".mybutton").prop('disabled', true); // initially disable
$(".mybutton").click(function() { // bind the event once
alert(data);
});
$(".generate").click(function() {
$(".mybutton").prop('disabled', true); // disable if new data starts to generate
$.getJSON("jsonfile.json").done(function(data) {
if (parseInt(data)>0) {
$(".mybutton").prop('disabled', false); // enable if everything is ok
}
});
});
Use delegation with on() like
$(function() {
var buttonData = {};
$(".generate").click(function() {
$.getJSON("jsonfile.json").done(function(data) {
if (parseInt(data) > 0) {
buttonData = data;
}
});
});
$(document).on('click', '.mybutton', function() {
alert(buttonData);
});
});
and bind it outside of the getJSON success handler

Trigger the event after making the HTML object in JQuery

I want an event to be triggered after the creation of the corresponding HTML object (href in my case).
I've written this code:
$(document).ready(function() {
$('body').on('click', '#stats-link', function(e) {
console.log('TRIGGERED'); // nothing is logged
e.preventDefault();
$.post('stats.php', {'email': $('#email').val()}, function() {
window.location = $(this).attr('href');
});
});
$('#submit_button').click(function(e) {
e.preventDefault();
...
$('#info').html('<p class="desc">bla bla bla</p>');
...
});
});
So, I make a href object identified by stats-link in the #submit_button function, then I want him to be triggered in the corresponding function (i.e., $('body').on(...), but it doesn't happen. What am I doing wrong?
Did you missed this line:
$('#stats-link').trigger('click');
This will trigger the click event. The code you shared only binds the event. You need to trigger it.
JS:
$(document).ready(function () {
$('body').on('click', '#stats-link', function (e) {
e.preventDefault();
alert('clicked')
$.post('stats.php', {
'email': $('#email').val()
}, function () {
window.location = $(this).attr('href');
});
});
$('#submit_button').click(function (e) {
e.preventDefault();
$('#info').html('<p class="desc">bla bla bla</p>');
$('#stats-link').trigger('click'); //This is where you trigger the click.
});
});
Working Demo: http://jsfiddle.net/lotusgodkk/artaq4xj/
What is e? Are you sure the click event isn't actually working, but just giving you a script error and bailing out before it does anything? Your callback function does not define the passed in event parameter e.
$('body').on('click', '#stats-link', function() { // <-- No e parameter supplied.
e.preventDefault(); // <---- What is e?
...
}
Your preventDefault() parameter is lacked :
$('body').on('click', '#stats-link', function(event) {
event.preventDefault();
$.post('stats.php', {'email': $('#email').val()}, function() {
window.location = $(this).attr('href');
});
});

jquery: Callback not received on clicking of button

I need to send a request on click of button but callback is not received on firing of click event of the button.
Following is code snippet:
$(document).ready(function () {
var counter = 0;
$("#trail").click(function () {
$("#dialog").dialog();
if (counter < 1) {
$("#searchboxdiv").after('<input type="text" id="searchbox">');
$("#searchbox").after('<input type="button" id="searchbutton" value="search">');
counter++;
}
});
$("#searchbutton").click(function () {
var dataToSend = null;
$.ajax({
data: dataToSend,
url: "FormHandler",
success: function (result) {},
beforeSend: function () {
dataToSend = $("#searchbox").val();
}
});
});
$("#searchboxdiv").on('click', "#searchbutton", function(){
var data = null;
});
});
I added the textbox in the dialog box dynamically and on click of button in dialog box, callback is not received
Your options:
Use event delegation. Bind the click to immediate static parent like this :
$("#searchboxdiv").on('click', "#searchbutton", function(){ });
Or, bind it to the document.
$(document).on('click', "#searchbutton", function(){ });
Or, move the existing click after counter++;, ie., inside $("#trail")'s click handler.
For more info, see on()
Use event delegation (for dynamically added #searchbutton)
$('#searchboxdiv').on('click',"#searchbutton",function(){
http://learn.jquery.com/events/event-delegation/

Categories