CodeIgniter - проверка формы регистрации AJAX - PullRequest
0 голосов
/ 26 апреля 2019

Я создаю небольшое веб-приложение с CodeIgniter и Bootstrap для своего школьного проекта, и в настоящее время я пытаюсь настроить проверку формы с помощью AJAX. Я подозреваю, что проблема в контроллере, но я просто не могу понять, что именно. Все работает правильно, когда я ввожу правильные данные, но когда при проверке возникают ошибки или все поля остаются пустыми, я перенаправляюсь на 'http://[::1]/appname/index.php/users/signup' и вижу следующее сообщение:

{"title":"Sign up","messages":{"csrf_test_name":"","name":"

The Name field is required.<\/p>","email":"

The Email field is required.<\/p>","password":"

The Create password field is required.<\/p>","password2":""}}

Также обратите внимание, что я загрузил библиотеку 'form_validation' и помощника 'form' в файле 'autoload.php'. Заранее спасибо!

Итак, вот мой вид формы регистрации (без верхнего и нижнего колонтитула, они шаблонные):

<div class="container">
<br>
    <div class="text-center">
        <h1 class="display-4">Create Account</h1>
    </div>
<br>
<div class="row justify-content-md-center">

<div class="col-6 card bg-light">
<article class="card-body mx-auto">

<?php echo form_open('users/signup', array('id'=>'signup_form')); ?>
    <div class="form-group input-group">
        <div class="input-group-prepend">
            <span class="input-group-text"> <i class="fa fa-user"></i> </span>
         </div>
        <input class="form-control" name="name" placeholder="Name" type="text">
    </div> <!-- form-group// -->
    <div class="form-group input-group">
        <div class="input-group-prepend">
            <span class="input-group-text"> <i class="fa fa-envelope"></i> </span>
         </div>
        <input class="form-control" name="email" placeholder="Email" type="email">
    </div> <!-- form-group// -->
    <div class="form-group input-group">
        <div class="input-group-prepend">
            <span class="input-group-text"> <i class="fa fa-lock"></i> </span>
        </div>
        <input class="form-control" name="password" placeholder="Create password" type="password">
    </div> <!-- form-group// -->
    <div class="form-group input-group">
        <div class="input-group-prepend">
            <span class="input-group-text"> <i class="fa fa-lock"></i> </span>
        </div>
        <input class="form-control" name="password2" placeholder="Repeat password" type="password">
    </div> <!-- form-group// -->
    <div class="form-group">
        <button type="submit" class="btn btn-primary btn-block"> Create Account  </button>
    </div> <!-- form-group// -->
    <p class="text-center">Have an account? <a href="login">Log In</a> </p>
<?php echo form_close(); ?>
</article>
</div> <!-- card.// -->

</div>
</div>

Это скрипт AJAX:

<script type="text/javascript">
var sUrequest;
$("#signup_form").submit(function(e){
    e.preventDefault();
    if(sUrequest){
        sUrequest.abort();
    }
    var inputs=$(this).find("input, select, button, textarea"),
    serializedData=$(this).serialize(),
    postURL=$(this).attr("action");
    inputs.prop("disabled",true);
    sUrequest=$.ajax({
        url:postURL,
        type:"post",
        data:serializedData,
    });
    sUrequest.done(function(response,statusText,jqXHR){
        $.each(response.messages, function(key, value) {
            var element = $('#' + key);

            element.closest('div.form-group input-group')
            .removeClass('has-error')
            .addClass(value.length > 0 ? 'has-error' : 'has-success')
            .find('.text-danger')
            .remove();

            element.after(value);
        });
    });
    sUrequest.fail(function(jqXHR,statusText,thrownError){
        console.log("jq:"+jqXHR+" st:"+statusText+" te:"+thrownError);
    });
    sUrequest.always(function(){
        inputs.prop("disabled",false);
    });
});

</script>

Вот контроллер пользователя:

<?php
  class Users extends CI_Controller {
    # Register new user
    public function signup() {
      $data['title'] = 'Sign up';

      array('success' => FALSE, 'messages' => array());

      $this->form_validation->set_error_delimiters('<p class="text-danger">', '</p>');
      $this->form_validation->set_rules('name', 'Name', 'required');
      $this->form_validation->set_rules('email', 'Email', 'required|callback_check_email_exists');
      $this->form_validation->set_rules('password', 'Create password', 'required');
      $this->form_validation->set_rules('password2', 'Repeat password', 'matches[password]');

      if($this->form_validation->run() === FALSE) {
        // I am not sure if I need this commented part, since AJAX is supposed to perform all the actions without reloading the page.
        // $this->load->view('templates/header');
        // $this->load->view('pages/signup', $data);
        // $this->load->view('templates/footer');
        foreach ($_POST as $key => $value) {
          $data['messages'][$key] = form_error($key);
        }
      }
      else {
        #Encrypting password
        $hashed_password = password_hash($this->input->post('password'),PASSWORD_DEFAULT);

        $this->user_model->signup($hashed_password);

        #Setting a flash message
        $this->session->set_flashdata('user_registered', 'You were successfully registered! You can now log in.');
        redirect('../home');
      }
      echo json_encode($data);
    }

    # Check if the email is already taken.
    public function check_email_exists($email) {
      $this->form_validation->set_message('check_email_exists', 'There is a user registered with this email');
      if ($this->user_model->check_email_exists($email)) {
        return TRUE;
      } else {
        return FALSE;
      }
    }
  }

А это моя модель пользователя:

<?php
  class User_model extends CI_Model {
    # Sign up user
    public function signup($hashed_password) {
      # User data array
      $data = array (
        'name' => $this->input->post('name'),
        'email' => $this->input->post('email'),
        'password' => $hashed_password
      );

      # Insert user in the database
      return $this->db->insert('users', $data);
    }

    # Check if email is already taken
    public function check_email_exists($email) {
      $query = $this->db->get_where('users', array('email' => $email));
      if (empty($query->row_array())) {
        return TRUE;
      } else {
        return FALSE;
      }
    }
  }

Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 26 апреля 2019

Просто повторяя json_encode($data) в вашем контроллере, вы не сигнализируете клиентской части, что ответ должен рассматриваться как ответ XHR.На данный момент то, что вы делаете, эквивалентно загрузке представления для отображения данных.

Мы будем использовать класс output (который автоматически загружается) для возврата ответа через Ajax.Измените echo json_encode($data) на:

$this->output
->set_header('HTTP/1.1 200 Ok)
->set_status_header(200)
->set_content_type('application/json')
->set_output(json_encode($data));

Это именно то, что вам нужно.Обратите внимание, что вы объединяете несколько методов, поэтому нет необходимости завершать каждый из них ; ... только последним.

После ->set_output контроллер завершает работу, поэтому после этого ничего не будет выполнено

0 голосов
/ 26 апреля 2019

ОБНОВЛЕНИЕ: Я думаю, что главная проблема, с которой вы столкнулись, заключается в том, что вы не оборачиваете свой jquery в готовый документ!

JQUERY:

$(document).ready(function () {
    var sUrequest;
    $("#signup_form").submit(function (e) {
        e.preventDefault();
        if (sUrequest) {
            sUrequest.abort();
        }
        var inputs = $(this).find("input, select, button, textarea"),
                serializedData = $(this).serialize(),
                postURL = $(this).attr("action");
        inputs.prop("disabled", true);
        sUrequest = $.ajax({
            url: postURL,
            type: "post",
            data: serializedData,
            dataType: 'json'
        });
        sUrequest.done(function (response, statusText, jqXHR) {
            if (response.status == 'error') {
                $.each(response.messages, function (key, value) {
                    var element = $('[name=' + key + ']');
                    element.closest('div.form-group input-group')
                            .removeClass('has-error')
                            .addClass(value.length > 0 ? 'has-error' : 'has-success')
                            .find('.text-danger')
                            .remove();

                    element.after(value);
                });
            } else {
                window.location.href = response.url;
            }
        });
        sUrequest.fail(function (jqXHR, statusText, thrownError) {
            console.log("jq:" + jqXHR + " st:" + statusText + " te:" + thrownError);
        });
        sUrequest.always(function () {
            inputs.prop("disabled", false);
        });
    });
});

Примечание: я такжевзял на себя смелость исправить ваши сообщения об ошибках, потому что ваши поля не имеют идентификаторов.

PHP:

function signup() {
    $data = array();

    $this->form_validation->set_error_delimiters('<p class="text-danger">', '</p>');
    $this->form_validation->set_rules('name', 'Name', 'required');
    $this->form_validation->set_rules('email', 'Email', 'required|callback_check_email_exists');
    $this->form_validation->set_rules('password', 'Create password', 'required');
    $this->form_validation->set_rules('password2', 'Repeat password', 'matches[password]');

    if (!$this->form_validation->run()) {
        $data['status'] = 'error';
        foreach ($_POST as $key => $value) {
            $data['messages'][$key] = form_error($key);
        }
    } else {
        $hashed_password = password_hash($this->input->post('password'), PASSWORD_DEFAULT);

        $this->user_model->signup($hashed_password);

        $this->session->set_flashdata('user_registered', 'You were successfully registered! You can now log in.');
        $data['status'] = 'success';
        $data['url'] = base_url() . 'home';
    }
    echo json_encode($data);
    exit;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...