skip to Main Content

Background

I have an email sign-up form on a website.

The form appears in two areas of each web page: the header and the footer

It’s the same exact form, just available on the top and bottom of the page for better UX and accessibility.

The form uses a jQuery/AJAX script to provide success and error responses to the user. (i.e., "Success! Your subscription is complete." and "Error. Please review and re-submit")

When the user submits the form, the user input is added to the database AND a notification email is sent to site admins.

If the header form is used, the email subject reads "Email Subscriber Added (Header Form)".

If the footer form is used, the subject reads "Email Subscriber Added (Footer Form)".

(This is just a simple technique to let admins gauge the usage of each form.)

Here’s what the PHP looks like:

if ( $form_selected == 'header' ) {
    
        $mail->Subject = 'Email Subscriber Added (Header Form)';
        $mail->Body = $message;

} elseif ( $form_selected == 'footer' ) {
    
        $mail->Subject = 'Email Subscriber Added (Footer Form)';
        $mail->Body = $message;

} else {

        $mail->Subject = 'Email Subscriber Added (form version unknown)';
        $mail->Body = $message; 

}

To this point, everything works fine.


The Problem

The problem is that, if the site user submits multiple email subscriptions in the same session, site admins get the else version in the PHP script above ("form version unknown"). This option should never be invoked during a normal session. But the page needs to be refreshed before the if and elseif options are considered again.


Question

Is there a way to solve this problem in the jQuery/AJAX script (see below)? I’m open to modifying the PHP, as well, if necessary.

$(function() {

  // set up event listener
  $('#header-form, #footer-form').submit(function(e) {
    // disable html submit button
    e.preventDefault();

    // get the submit button
    var submitButton = $('[type=submit]', this);

    // get the messages element
    var formResponses = $('#header-form-responses, #footer-form-responses', this);
    formResponses.text(" ");

    // serialize form data
    var formData = $(this).serialize();

    // disable submit button to prevent unnecessary submission
    submitButton.attr('disabled', 'disabled');

    // tell users that form is sending
    submitButton.text('Processing...');

    // submit form via AJAX
    $.ajax({
        type: 'POST',
        url: $(this).attr('action'),
        data: formData
      })

      .done(function(response) {
        // make sure formResponses element has 'success' class
        $(formResponses).removeClass('error');
        $(formResponses).addClass('success');

        // set message text
        $(formResponses).text('Your subscription is complete. Thank you!');

        // clear form
        $('input').val('');
      })

      .fail(function(data) {
        // make sure formResponses element has 'error' class
        $(formResponses).removeClass('success');
        $(formResponses).addClass('error');

        // set the message text
        $(formResponses).text('Input error. Please review and re-submit.');
      })

      .always(function(data) { // this will always fire even if the request fails
        submitButton.removeAttr('disabled');
        submitButton.text('Send');
      });

  });

});
<!-- simplified HTML -->

<form action="process_form.php" method="post" id="header-form">
  <input type="email" name="email_subscription">
  <input type="hidden" name="formtarget" value="header">
  <button type="submit" name="submit_subscription">Submit (Header)</button>
  <p id="header-form-responses"></p>
</form>

<form action="process_form.php" method="post" id="footer-form">
  <input type="email" name="email_subscription">
  <input type="hidden" name="formtarget" value="footer">
  <button type="submit" name="submit_subscription">Submit (Footer)</button>
  <p id="footer-form-responses"></p>
</form>

2

Answers


  1. If this contains the data which triggers those PHP if conditions:

    <input type="hidden" name="formtarget" value="header">
    

    Then this is explicitly clearing that data:

    // clear form
    $('input').val('');
    

    Instead, only clear the fields you want to clear:

    // clear form
    $('input[type="email"]').val('');
    
    Login or Signup to reply.
  2. Use $(‘input:not([type="hidden"])’).val(”) to exclude the hidden input from clearing. Your JS is clearing all inputs including your hidden inputs.

    $(function() {
    
      // set up event listener
      $('#header-form, #footer-form').submit(function(e) {
        // disable html submit button
        e.preventDefault();
    
        // get the submit button
        var submitButton = $('[type=submit]', this);
    
        // get the messages element
        var formResponses = $('#header-form-responses, #footer-form-responses', this);
        formResponses.text(" ");
    
        // serialize form data
        var formData = $(this).serialize();
    
        // disable submit button to prevent unnecessary submission
        submitButton.attr('disabled', 'disabled');
    
        // tell users that form is sending
        submitButton.text('Processing...');
    
        // submit form via AJAX
        $.ajax({
            type: 'POST',
            url: $(this).attr('action'),
            data: formData
          })
    
          .done(function(response) {
            // make sure formResponses element has 'success' class
            $(formResponses).removeClass('error');
            $(formResponses).addClass('success');
    
            // set message text
            $(formResponses).text('Your subscription is complete. Thank you!');
    
            // clear form except hidden inputs
            $('input:not([type="hidden"])').val('')
          })
    
          .fail(function(data) {
            // make sure formResponses element has 'error' class
            $(formResponses).removeClass('success');
            $(formResponses).addClass('error');
    
            // set the message text
            $(formResponses).text('Input error. Please review and re-submit.');
          })
    
          .always(function(data) { // this will always fire even if the request fails
            submitButton.removeAttr('disabled');
            submitButton.text('Send');
          });
    
      });
    
    });
    <!-- simplified HTML -->
    
    <form action="process_form.php" method="post" id="header-form">
      <input type="email" name="email_subscription">
      <input type="hidden" name="formtarget" value="header">
      <button type="submit" name="submit_subscription">Submit (Header)</button>
      <p id="header-form-responses"></p>
    </form>
    
    <form action="process_form.php" method="post" id="footer-form">
      <input type="email" name="email_subscription">
      <input type="hidden" name="formtarget" value="footer">
      <button type="submit" name="submit_subscription">Submit (Footer)</button>
      <p id="footer-form-responses"></p>
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search