2

I am having strange behaviour when using jquery.on().

Basically, just trying to create a newsletter signup form (can be dynamically generated and not there on initial DOM load) and pass the details through in Ajax but it is not registering the first click on the submit button meaning that to successfully submit, the user has to click twice (only seeing the success message and 'subscribe' post on 2nd click).

The html:

<div class="newsletter-widget grid-item masonry-brick">
    <input name="Email" type="email" placeholder="Please enter your email" required />
    <input type="submit" value="Subscribe" class="newslettersubmit"/>

and the javascript (in document ready);

var newsletterFocus = $('.newsletter-widget').find('input[type=submit]');

$(document).on('submit', newsletterFocus, function (e) {
    e.preventDefault();
    var newsletterLinks = newsletterFocus;
    DD.newsletter.behavior(newsletterLinks);
});

and the functions within an object that are called;

DD.newsletter = {

behavior: function (item) {
    item.click(function (e) {
        e.preventDefault();
        var where = $('.newsletter-widget').find('input[type=submit]').parents('section').attr('id');
        var email = $(this).siblings('[name$=Email]'),
        emailVal = email.val();
        DD.newsletter.subscribe(email, emailVal, where);
    });
},

subscribe: function (self, email, where) {
    $.ajax({
        type: "POST",
        data: '{"email":"' + email + '", "method":"' + where + '"}',
        url: '/Subscriber/Subscribe',
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            self.val(response);
        },
        failure: function (msg) {
            self.val(msg);
        }
    });
},});

I've tried using 'click' as the action for on() but this registers an event on each click and i get thousands of forms submitted!

Any help appreciated!

4
  • Why don't you use the good ol' <form action='...' ? After all, that's what a form should look like.. Commented Nov 5, 2012 at 17:50
  • 2
    It looks like you aren't binding your click handler until you submit the form for the first time. So your subscribe function isn't called until the second click. Commented Nov 5, 2012 at 17:51
  • why not .on('submit','.newsletter-widget > input[type=submit]', function(){}); or even .on('submit','form',function(){});, after all, it's the form that gets submitted, is it not? Commented Nov 5, 2012 at 17:52
  • I have never used .on() with the sumbit action. Did you try $(document).on('click', newsletterFocus, function (e) { . . .});? Or $('.newsletter-widget').on('click', 'input[type=submit]', function (e) { . . .});? Commented Nov 5, 2012 at 17:53

3 Answers 3

2

Change the div container to a form element:

<form class="newsletter-widget grid-item masonry-brick">

You'll want to register the submit event to the form, not the input field. Here's a quick refactor of your form submission:

$(document).on('submit', '.newsletter-widget', function (e) {
  e.preventDefault();
  DD.newsletter.behavior(); //Submit the form via AJAX
});

If you wanted to hook this up to your behavior method, just unwrap the click:

behavior: function () {
  var where = $('.newsletter-widget').find('input[type=submit]').parents('section').attr('id');
  var email = $(this).siblings('[name$=Email]'),
  emailVal = email.val();
  DD.newsletter.subscribe(email, emailVal, where);
}
Sign up to request clarification or add additional context in comments.

2 Comments

This wouldn't solve the problem, since it's behavior that defines the click handler. It would still require two clicks to get to subscribe
I just refactored it so it doesn't need a click event binding.
1

The first click on the button will cause the behaviour click event handler to be bound to the button. Bind the behaviour directly instead of in the click event handler.

Replace this:

var newsletterFocus = $('.newsletter-widget').find('input[type=submit]');

$(document).on('submit', newsletterFocus, function (e) {
    e.preventDefault();
    var newsletterLinks = newsletterFocus;
    DD.newsletter.behavior(newsletterLinks);
});

with:

DD.newsletter.behavior($('.newsletter-widget input[type=submit]'));

1 Comment

this works but because we are loading the newsletter 'widget' in on subsequent pages using infinite scroll it doesnt work when it is not on the initial DOM load, hence using .on()
0

It should probably (I think) be something like this:

DD.newsletter = {

behavior: function (item) {
        var where = $(item).parents('section').attr('id');
        var email = $(item).siblings('[name$=Email]'),
        var emailVal = email.val();  // why were you declaring this without 'var'?
        DD.newsletter.subscribe(email, emailVal, where);
},

subscribe: function (self, email, where) {
    $.ajax({
        type: "POST",
        data: '{"email":"' + email + '", "method":"' + where + '"}',
        url: '/Subscriber/Subscribe',
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            self.val(response);
        },
        failure: function (msg) {
            self.val(msg);
        }
    });
},});

1 Comment

this is the one, thanks a lot! declaring the emailVal var without the var was also a typo so +1 for that notice too :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.