skip to Main Content

I have been developing a blogging application with CodeIgniter 3.1.8 and Twig. I am currently working on making a newsletter subscription system.

I have created a table named newsletter with 3 columns: id, email and subscription_date.

The newsletter subscription form:

<div id="messags" class="is-hidden h-text-center">
  <div class="success is-hidden alert-box alert-box--success">You have successfully subscribed to our newsletter</div>
  <div class="fail is-hidden alert-box alert-box--error">Sorry, the newsletter subscription filed</div>
</div>
<form name="newsletter" method="post" action="{{base_url}}newsletter/subscribe" id="newsletterForm" class="group" novalidate>
  <input type="email" value="{{set_value('email') | striptags}}" name="email" class="email" data-rule-required="true" placeholder="Your Email Address"> 
  <input type="submit" name="subscribe" value="subscribe">
</form>

The Newsletter_model model:

class Newsletter_model extends CI_Model {
    public function subscriber_exists() {   
        $query = $this->db->get_where('newsletter', ['email' => $this->input->post('email')]);
        return $query->num_rows() > 0;
    }

    public function add_subscriber() {
        $data = [
            'email' => $this->input->post('email'),
            'subscription_date' => date('Y-m-d H:i:s')
        ];
        return $this->db->insert('newsletter', $data);
    }
}

As you can see above, I use the subscriber_exists() to make sure there are no duplicate emails.

The Newsletter controller is quite simple:

class Newsletter extends CI_Controller {
  public function __construct(){
        parent::__construct();
    }

  public function subscribe(){
    $data['is_new_subscriber'] = true;
    if (!$this->Newsletter_model->subscriber_exists()) {
      $this->Newsletter_model->add_subscriber();
    } else {
      $data['is_new_subscriber'] = false;
    }
  } 
}

The problem

I use jQuery AJAX to submit the form and the script is unaware of the is_new_subscriber variable:

(function($) {

    // Add subscriber via AJAX
    $("#newsletterForm").validate({
        rules: {
            email: {
                email: true
            }
        },

        submitHandler: function(form) {
            var form = $("#newsletterForm"),
                $fields = form.find('input[type="email"]'),
                url = form.attr('action'),
                data = form.serialize();
            $.ajax({
                type: "POST",
                url: url,
                data: data,
                success: function() {
                    $('#messags').slideDown(250).delay(2500).slideUp(250);
                    if (is_new_subscriber == true) {
                        $fields.val('');
                        $('#messags .success').show();
                    } else {
                        $('#messags .fail').show();
                    }
                }
            });
        }
    });

})(jQuery);

UPDATE

Adding echo json_encode($data) to the subscribe() and changing the submitHandler to the below ddi not splve the issue:

submitHandler: function(form) {
  var form = $("#newsletterForm"),
  $fields = form.find('input[type="email"]'),
  url = form.attr('action'),
  data = form.serialize();
  $.ajax({
    dataType: "json",
    type: "post",
    url: url,
    data: data,
    success: function() {
      $('#messags').slideDown(250).delay(2500).slideUp(250);
      $fields.val('');
      if (data.is_new_subscriber == true) {
        $('#messags .success').show();
      } else {
        $('#messags .fail').show();
      }
    }
  });
}

How can I fix this issue?

2

Answers


  1. Chosen as BEST ANSWER

    Here is what worked for me:

    In the controller, I added echo json_encode($data):

    class Newsletter extends CI_Controller {
      
      public function __construct() {
            parent::__construct();
        }
    
      public function subscribe(){
        $data['is_new_subscriber'] = true;
        if (!$this->Newsletter_model->subscriber_exists()) {
          $this->Newsletter_model->add_subscriber();
        } else {
          $data['is_new_subscriber'] = false;
        }
        echo json_encode($data);
      }
    }
    

    The script:

    (function($) {
    
      // Add subscriber via AJAX
      $("#newsletterForm").validate({
        rules: {
          email: {
            email: true
          }
        },
    
        submitHandler: function(form) {
          var form = $("#newsletterForm"),
          $fields = form.find('input[type="email"]'),
          url = form.attr('action'),
          data = form.serialize();
          $.ajax({
            dataType: "json",
            type: "post",
            url: url,
            data: data,
            success: function(response) {
              $('#messags').slideDown(250).delay(2500).slideUp(250);
              $fields.val('');
              if (response.is_new_subscriber === true) {
                $('#messags .success').show();
                 $('#messags .notnew').hide();
              } else {
                $('#messags .notnew').show();
              }
            },
            error: function() {
              $('#messags .fail').show();
            }
          });
        }
      });
    
    })(jQuery);
    

    The HTML:

    <div id="messags" class="is-hidden h-text-center">
        <div class="success is-hidden alert-box alert-box--success">You have successfully subscribed to our newsletter</div>
        <div class="notnew is-hidden alert-box alert-box--info">You are already subscribed</div>
        <div class="fail is-hidden alert-box alert-box--error">Sorry, the newsletter subscription filed</div>
    </div>
    

  2. Your code doesn’t do anything with the $data variable, after you populate it. You could for example return it JSON-encoded.

      public function subscribe(){
        $data['is_new_subscriber'] = true;
        if (!$this->Newsletter_model->subscriber_exists()) {
          $this->Newsletter_model->add_subscriber();
        } else {
          $data['is_new_subscriber'] = false;
        }
        echo json_encode($data);
      }
    

    Then, in the success callback of your JS code you need to reference it:

    ...
                    success: function(data) {
                        $('#messags').slideDown(250).delay(2500).slideUp(250);
                        if (data.is_new_subscriber == true) {
                            $fields.val('');
                            $('#messags .success').show();
                        } else {
                            $('#messags .fail').show();
                        }
                    }
    ...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search