user546774
user546774

Reputation:

Using jQuery Ajax functions, sometimes my data is sent twice or three times

I try to do something and it works with few exceptions... I have a form which sends data throught $.ajax() but sometimes the form sends the data twice or three times...

The code is:

$('div#feedBackPresta-image, div#feedBackPresta-fb').click(function() {
    $('div#bgLayer').css({
        'height': bodyHeight,
        'display': 'block'
    });
    $('div#feedBack').css('display', 'block');
});
$('a#addFeedBack').click(function() {
    $('div#feedBacks').css('display', 'none');
    $('h3#clientsAboutUs').css('display', 'none');
    $('h3#addFeedBackAboutUs').css('display', 'inline-block');
    $('div.pages').css('display', 'none');
    $('div#feedBackForm').css('display', 'block');
    $('a#showFeedBacks').css('font-weight', 'normal');
    $('a#addFeedBack').css('font-weight', 'bold');
    $('input#submitFeedBack').attr('disabled', 'disabled');
    var clientName = $('input#clientName').val();
    var clientEmail = $('input#clientEmail').val();
    var clientWebsite = $('input#clientWebsite').val();
    var clientImage = $('input#clientImage').val();
    var clientFeedBack = $('textarea#clientFeedBack').val();
    var error = false;
    $('input#clientName, input#clientEmail, input#clientWebsite, input#clientImage, textarea#clientFeedBack').focusin(function() {
        $('input#clientName, input#clientEmail, input#clientWebsite, input#clientImage, textarea#clientFeedBack').keyup(function() {
            if($('input#clientName').val().length < 6) {
                $('input#clientName').css('border', '1px solid #ff0000');
                error = true;
            }
            else {
                $('input#clientName').css('border', '1px solid #BDC2C9');
                error = false;
            }
            if($('input#clientEmail').val().length < 10) {
                $('input#clientEmail').css('border', '1px solid #ff0000');
                error = true;
            }
            else {
                $('input#clientEmail').css('border', '1px solid #BDC2C9');
                error = false;
            }
            if($('textarea#clientFeedBack').val().length < 20) {
                $('textarea#clientFeedBack').css('border', '1px solid #ff0000');
                error = true;
            }
            else {
                $('textarea#clientFeedBack').css('border', '1px solid #BDC2C9');
                error = false;
            }
            if(error == false) {
                $('input#submitFeedBack').removeAttr('disabled');
            }
            else {
                $('input#submitFeedBack').attr('disabled', 'disabled');
            }
        });
    });
    $('input#submitFeedBack').click(function() {
        clientName = $('input#clientName').val();
        clientEmail = $('input#clientEmail').val();
        clientWebsite = $('input#clientWebsite').val();
        clientImage = $('input#clientImage').val();
        clientFeedBack = $('textarea#clientFeedBack').val();
        var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
        if(clientEmail != "" || clientEmail != undefined) {
            if(!emailReg.test(clientEmail)) {
                $('input#clientEmail').css('border', '1px solid #ff0000');
                error = true;
            } 
        }
        if(error == false) {
            $.ajax({
                type: 'POST',
                url: 'modules/feedBackPresta/ajax.php',
                data: {'type': 'add', 'clientName': clientName, 'clientEmail': clientEmail, 'clientFeedBack': clientFeedBack, 'clientWebsite': clientWebsite, 'clientImage': clientImage},
                success: function() {
                    $('input#submitFeedBack').attr('disabled', 'disabled');
                    $('input#clientName').val('').css('border', '1px solid #BDC2C9');
                    $('input#clientEmail').val('').css('border', '1px solid #BDC2C9');
                    $('input#clientWebsite').val('');
                    $('input#clientImage').val('');
                    $('textarea#clientFeedBack').val('').css('border', '1px solid #BDC2C9');
                    $('div#successAdd').append('<div class="feedBack-approve" style="text-align: center;"><p style="margin-top: 15px;">Successful!</p></div>');
                    $('div.feedBack-approve').fadeOut(2500);
                }
            });
        }
    });
});
$('a#showFeedBacks').click(function() {
    $('div#feedBackForm').css('display', 'none');
    $('h3#clientsAboutUs').css('display', 'inline-block');
    $('h3#addFeedBackAboutUs').css('display', 'none');
    $('div.pages').css('display', 'block');
    $('div#feedBacks').css('display', 'block');
    $('a#addFeedBack').css('font-weight', 'normal');
    $('a#showFeedBacks').css('font-weight', 'bold');
});
$('div#bgLayer, div#feedBackRight').click(function() {
    $('div#bgLayer').css('display', 'none');
    $('div#feedBack').css('display', 'none');
    $('div#feedBacks').css('display', 'block');
    $('div#feedBackForm').css('display', 'none');
    $('a#showFeedBacks').css('font-weight', 'bold');
    $('h3#clientsAboutUs').css('display', 'inline-block');
    $('h3#addFeedBackAboutUs').css('display', 'none');
    $('div.pages').css('display', 'block');
    $('a#addFeedBack').css('font-weight', 'normal');
    window.location.hash = '!';
});
$('a.anchors').click(function() {
    $('div#bgLayer').css('display', 'none');
    $('div#feedBack').css('display', 'none'); 
});

So if anybody can help me with this code I'll be very grateful...

Best regards, George!

Upvotes: 1

Views: 720

Answers (5)

jbabey
jbabey

Reputation: 46647

You are binding your click handler that has the ajax in it

$('input#submitFeedBack').click(function() {
    ...
});

Inside of your other click handler

$('a#addFeedBack').click(function() {
    ...
});

Every time #addFeedBack is clicked, another click handler is attached to #submitFeedBack.

Upvotes: 0

nnnnnn
nnnnnn

Reputation: 150010

You are setting up event handlers from within other event handlers, as shown in the following abbreviation of your code:

$('a#addFeedBack').click(function() {
    ...
    $('input#clientName, input#clientEmail, input#clientWebsite, input#clientImage, textarea#clientFeedBack').focusin(function() {
        $('input#clientName, input#clientEmail, input#clientWebsite, input#clientImage, textarea#clientFeedBack').keyup(function() {
            ...
        });
    });
    $('input#submitFeedBack').click(function() {
        ...
        if(error == false) {
            $.ajax({
              ...
            });
        }
    });
});

That means that every time you click on "#addFeedback" it adds another .click handler to the "#submitFeeback" button and another .focusin handler to the inputs and textarea, and every time you actually do focus in on those input fields it adds another .keyup handler (multiplied by the existing number of focus handlers).

These duplicate event handlers will all run when their event occurs and thus your $.ajax() call will be made multiple times.

Remove the nested event bindings (do them all at the same level so that you bind to each event only once).

Upvotes: 1

blackbourna
blackbourna

Reputation: 1233

Form submission via the .submit() event rather than a .click() event in jQuery may help avoid this. Your code should be roughly the same, just add return false to the bottom of the .click() method and rename it .submit()

Upvotes: 0

Greg Pettit
Greg Pettit

Reputation: 10830

That's a lot of code to sift through, so I have to admit I'm going to make a guess here:

If it's submitting multiple times, it's because you are binding the click handler multiple times. This is a danger sometimes when using the .click() method for binding. Try investigate using the .on() function for event binding, using the delegate syntax to delegate listening to the closest ancestor (could be a parent, but could be even higher).

You will be able to organize your events better, and you won't need to attempt to re-bind clicks from elsewhere.

[bonus]

Not directly answering your question, but some general advice: there has GOT to be a way to make all those visual changes more efficiently. Grouping certain elements together and then hiding only the parent... using .toggleClass() where appropriate... and even in general adding or removing classes instead of modifying styles directly. There also seems to be a lot of room for caching jQuery objects, sometimes because they are used multiple times, and sometimes just to make the code more readable.

I also worry that it's so ID-heavy. It might be the right approach for this task, who knows. But in general if you can re-use classes, and then also use DOM traversal (instead of hiding "#someID" which is always a child element, you might hide using $(this).find('.someClass') so that the same code could work over repeated patterns.

Upvotes: 0

Jacob
Jacob

Reputation: 78850

Every time the a#addFeedBack click event is handled, you're attaching a new click handler to input#submitFeedBack that submits the form. You should only attach the click handler to input#submitFeedBack once.

Upvotes: 3

Related Questions