1

I've made a simple lightbox implementation in my code. By Clicking on #makePayment link a lightbox is opened, and within that lightbox there is a form. When user clicks on #paymentDetailsConfrimLB to submit the form, I've just displayed an alert.

Before I explain the problem, please have a look at the code I've written:

       $("#makePayment").click(function() { 
            $("body").addClass("modalPrint");
            var lb = new LightBox("paymentDetailsLB", "675", "500");
            lb.htmlObjRef.style.height = "auto";
            lb.show();
            $("#paymentDetailsCloseLB, .hideBox").click(function() {
                $("body").removeClass("modalPrint");
                lb.hide();
            });//paymentDetailsCloseLB
            $("#paymentDetailsConfrimLB").click(function( event ) {
               alert('form submission happened.');
               event.preventDefault();
               return false;
            });//paymentDetailsConfrimLB
          return false;
        });//makePayment

Problem is, when I first load the page, and open the lightbox, and click the submit button, the alert is shown once (as it should), but if I close the lightbox, re-open it, and then submit the form, it is submitted twice and alert is shown twice. Similarly if I again close and re-open the lightbox, upon form submission the alert shows up 3 times, and it goes on like this.

Any idea on how I can resolve this?

anwartheravian
  • 1,071
  • 2
  • 11
  • 30

4 Answers4

4

Other than Kavin's approach, another solution also worked for me. I just added this line immediately after the event.preventDefault() method:

  event.stopImmediatePropagation()

And it resolved the issue.

anwartheravian
  • 1,071
  • 2
  • 11
  • 30
  • 1
    This worked because you were binding multiple handlers. This will prevent the event from bubbling. Take a look at http://jqfundamentals.com/chapter/events for more info on event bubbling. – Kevin Apr 07 '16 at 23:04
1

You're setting click callback every time you open lightbox. Try to move click callbacks out of #makePayment:

$("#makePayment").click(function() { 
    $("body").addClass("modalPrint");
    var lb = new LightBox("paymentDetailsLB", "675", "500");
    lb.htmlObjRef.style.height = "auto";
    lb.show();          
    return false;
 });//makePayment
 $("#paymentDetailsCloseLB, .hideBox").click(function() {
     $("body").removeClass("modalPrint");
     lb.hide();
 });//paymentDetailsCloseLB
 $("#paymentDetailsConfrimLB").click(function( event ) {
     alert('form submission happened.');
     event.preventDefault();
     return false;
 });//paymentDetailsConfrimLB
Ledzz
  • 1,266
  • 1
  • 12
  • 14
0

The problem is:

            $("#paymentDetailsConfrimLB").click(function( event ) {
               alert('form submission happened.');
               event.preventDefault();
               return false;
            });//paymentDetailsConfrimLB

it adds to the click queue, so to speak. So if you add multiple click events to something, all of them get added and all of them run by default. You don't notice it because all your other functions don't matter about being run multiple times.

A way to solve this is to put a check within the function.

        $("#paymentDetailsCloseLB, .hideBox").click(function() {
            $("body").removeClass("modalPrint");
            lb.hide();

        });//paymentDetailsCloseLB
         pDCLB=$("#paymentDetailsConfrimLB");
         if(!pDCLB.attr('alertc')); //check if the attribute exists, if not, we've never been here before.
             pDCLB.attr('alertc',1); //adds the attribute so we can check it later.
             $("#paymentDetailsConfrimLB").click(function( event ) {
                alert('form submission happened.');
                event.preventDefault();
                return false;
              });//paymentDetailsConfrimLB
          }
Greg Borbonus
  • 1,384
  • 8
  • 16
  • Great answer Greg, but the problem with this approach is that let's say user incorrectly filled some value, submits the form, there is some validation error shown up, he/she corrects that and resubmits, the re-submission won't happen, because the flag is set to true. Correct me if I'm wrong. – anwartheravian Apr 07 '16 at 22:35
  • No, it leaves the click event from the first assignment. So the form will submit and the validation will still occur – Greg Borbonus Apr 07 '16 at 22:53
  • Great then... I guess that's the beauty of stackoverflow, I was struggling with this issue for last 3 days, and within half an hour of posting it here, I found 3 entirely different but perfectly working approaches to resolve the issue... – anwartheravian Apr 07 '16 at 22:56
0

You're binding a new handlers every time the submit button is clicked. You only need to define a handler once, and it will be executed whenever that action occurs. Otherwise, each handler you bind will execute.

If you absolutely needed to bind the handlers the way you are, then you could also use .one, which will only bind the handler the first time for each element.

jQuery .one() documentation

Attach a handler to an event for the elements. The handler is executed at most once per element per event type.

Try something like this.

$(document).on('click', '#makePayment', function() {
  $("body").addClass("modalPrint");
  var lb = new LightBox("paymentDetailsLB", "675", "500");
  lb.htmlObjRef.style.height = "auto";
  lb.show();
  return false;
}).on('click', '#paymentDetailsCloseLB, .hideBox', function() {
  $("body").removeClass("modalPrint");
  lb.hide()
}).on('click', '#paymentDetailsConfrimLB', function() {
  alert('form submission happened.');
  event.preventDefault();
  return false;
});
Kevin
  • 2,752
  • 1
  • 24
  • 46
  • It worked even without using one. Can you please tell why you are using `dot` to combine all event listeners, because when I make separate event listeners like Ledzz suggested, it doesn't work. – anwartheravian Apr 07 '16 at 22:52
  • It could be for multiple reasons. In my example we're binding handlers to the document so it will work with dynamic elements. Ledzz answer does the same thing, but the handlers are being bound to the elements, meaning they have to exist when the code is ran. Take a look at the jQuery `.on` docs...http://api.jquery.com/on/. In jQuery you can chain functions together, since each function returns the jQuery object you can continue executing actions on it. Look at this example of chaining... http://stackoverflow.com/questions/7475336/how-does-jquery-chaining-work – Kevin Apr 07 '16 at 22:59