1
votes

So I have made a form with CodeIgniter and it does uses CodeIgniter's form validation class to validate input fields. I have a total of 6 input fields which all are required fields.

I would like to show the same error of "This field is required" even if there are multiple empty fields, but right now it will show the error message for each of the fields. So if I leave every field empty, it will echo the same message 6 times.

I won't paste any code here since I know how to use the actual validation class, just don't know how to implement it in a way as said above.

Thanks in advance!

E: Now comes another problem, it doesn't show any errors, in fact the whole method will fail right after it's checking if the "add_user" button is submitted. I'm 100% sure that the name of my submit button is "add_user".

Sorry about bad indenting, I'll never learn how to use StackOverflow's indenting.

Here's my controller for adding a user:

<?php

    class Users extends CI_Controller {


    public function add_user() 
    {   



        if($this->input->post('add_user'))
        {   

            $this->load->model('subject');

            $data['subjects'] = $this->subject->get_all_subjects();
            $data['schools'] = $this->subject->get_all_schools();


            $this->load->library('form_validation');

            $this->form_validation->set_rules('f_name', 'Etunimi', 'required');
            $this->form_validation->set_rules('l_name', 'Sukunimi', 'min_length[3]');
            $this->form_validation->set_rules('email', 'Sähköpostiosoite', 'matches[email_confirm]|is_unique[users.email]|valid_email');
            $this->form_validation->set_rules('email_confirm', 'Sähköpostiosoite', 'valid_email');
            $this->form_validation->set_rules('phone_number', 'Puhelinnumero', 'min_length[7]|max_length[10]');

            if($this->input->post('user_type') == "moderator")
            {   
                $this->load->library('form_validation');

                $this->form_validation->set_rules('school', 'Koulutalo', 'required');
                $this->form_validation->set_rules('subject', 'Laji', 'required');

            }

            $this->form_validation->set_message('required', 'Täyttämättömiä kenttiä');
            $this->form_validation->set_message('min_length', '%s - kentässä on liian vähän merkkejä');
            $this->form_validation->set_message('matches', 'Sähköpostit eivät täsmää');
            $this->form_validation->set_message('is_unique', '%s on jo rekisteröity');

            if($this->form_validation->run() == FALSE)
            {

            $this->output->set_content_type('application_json');
            $this->output->set_output(json_encode(array('result' => 0, 'error' => $this->form_validation->error_array() )));
                return false;

            }


            $first_part_username = substr($this->input->post('f_name'), 0, 2);
            $second_part_username = substr($this->input->post('l_name'), 0, 3);

            $first_part_username = strtolower($first_part_username);
            $second_part_username = strtolower($second_part_username);

            $this->load->helper('string');

            $random_number = random_string('numeric', 4);

            $username = $first_part_username . $second_part_username .$random_number;


                $password = random_string('alnum', 8);

                $this->load->model('user');

                $name = ucfirst($this->input->post('f_name')). " " .ucfirst($this->input->post('l_name'));

                $data = array (
                'name'      => $name,
                'email'     => $this->input->post('email'),
                'username'  => $username,
                'password'  => $this->phpass->hash($password),
                'user_type'     => $this->input->post('user_type'),
                'phone_number'  => $this->input->post('phone_number'),
                'subject_id'    => !($this->input->post('subject')) ? null : $this->input->post('subject'),
'school_id' => !($this->input->post('school')) ? null : $this->input->post('school')
                    );


            $this->user->add_user($data);
        $this->load->library('email');

            $config['mailtype'] = 'html';
            $this->email->initialize($config);

            $this->email->from('[email protected]', 'Your Name');
            $this->email->to($this->input->post('email'));  
            $this->email->subject('test test');
            $this->email->message('Test');

            if($this->email->send()) {

                $this->output->set_content_type('application_json');
            $this->output->set_output(json_encode(array('result'=>1, 'msg' => 'Uusi käyttäjä lisätty')));
            }
        }

            /* It will echo out this one which is viewable from developer tab right after the form is submitted */

            $this->output->set_content_type('application_json');
            $this->output->set_output(json_encode(array('result'=>1, 'msg' => 'Form not submitted')));
    }
}
?>

And the javascript:

$(document).ready(function() {

        $("#add_user_form").on('submit', function(e) {

            e.preventDefault();

                $("#loading_spinner").show();
                var from = $(this);

                $.ajax({

                    url: from.attr('action'),
                    type: from.attr('method'),
                    data: $(from).serialize(),
                    }).done(function(data) {



                    if(data.result == 0) {

                        $("#forgot-pass-success").hide();
                        $("#forgot-pass-error").show();
                        $("#forgot-pass-error").fadeIn(1000).html("<p>" + data.error + "</p>");

                      }

                    if(data.result == 1) {

                        $("#forgot-pass-error").hide();
                        $("#forgot-pass-success").show();
                        $("#forgot-pass-success").fadeIn(1000).html("<p>" + data.msg + "</p>");
                      }

                   $("#loading_spinner").hide(); 

                }, 'json');

            return false;

        });
});
2
You have to loop over the array sent from PHP in your javascript to display each error btw. I'm looking at your code still. - Skewled
$this->load->library('form_validation'); only has to be loaded once in that function to work for the entire function. So you can remove the duplicates. - Skewled
Done those.. Now it will echo out the "Form was not submitted" as JSON every time. So basically the AJAX part is working when it comes to getting those JSON's. - B_CooperA
Yes now change this $this->output->set_output(json_encode(array('result' => 0, 'error' => $this->form_validation->error_array() ))); TO $this->output->set_output(json_encode(array('result'=>1, 'msg' => $this->form_validation->error_array()))); so it matches your scheme - Skewled
You are correct about the JSON and the one added needed to change to msg so we could see it in your output. - Skewled

2 Answers

0
votes

Here is an example that returns the errors in a JSON string to process with jQuery, you have to load the form validation helper.

Load the library:

$this->load->library('form_validation');

        /* Outputto Json Format */
        $this->output->set_content_type('application_json');
        /* Validate Form Data */
        $this->form_validation->set_rules('login', 'Username', 'required|min_length[4]|max_length[16]|is_unique[user.login]');
        $this->form_validation->set_rules('email', 'Email', 'required|valid_email|is_unique[user.email]');
        $this->form_validation->set_rules('password', 'Password', 'required|min_lenght[6]|max_length[16]|matches[confirm_password]');
        /* Custom Messages */
        $this->form_validation->set_message('required', 'You must enter a %s.');
        $this->form_validation->set_message('is_unique', 'That %s is already in use, please try again.');
        $this->form_validation->set_message('valid_email', 'You must enter a vaild email address.');

        if($this->form_validation->run() == false)
        {
            $this->output->set_output(json_encode(['result' => 0, 'error' => $this->form_validation->error_array()]));
            return false;
        }

$login = $this->input->post('login');
        $email = $this->input->post('email');
        $password = $this->input->post('password');
        $confirm_password = $this->input->post('comfirm_password');

        $user_id = // DO YOUR QUERY HERE


        if($user_id)
        {
            $this->session->set_userdata(['user_id' => $user_id]);
            $this->output->set_output(json_encode(['result' => 1]));
            return false;
        }
        $this->output->set_output(json_encode(['result' => 0, 'error' => 'User not created.']));

EDIT: Sorry I'm using a custom library to extend the form_validation so I can create arrays to return. Just make sure you save this in your library files as my_form_validation.php

class MY_Form_validation extends CI_Form_validation
{
    // ------------------------------------------------------------------------

    public function __construct($config = array())
    {
        parent::__construct($config);
    }

    // ------------------------------------------------------------------------

    public function error_array()
    {
        if(count($this->_error_array > 0))
        {
            return $this->_error_array;
        }
    }

    // ------------------------------------------------------------------------
}

EDIT: Example of dealing with this data in jQuery

<!-- Javascript POST -->
<script type="text/javascript">
    $(function() {
        // You need to create a div called #register_form_error
        $("#register_form_error").hide();
        // Your register form would go here in place of #regiser_form
        $("#register_form").submit(function(evt) {
            evt.preventDefault();
            var url = $(this).attr('action');
            var postData = $(this).serialize();

            $.post(url, postData, function(o) { 
                if (o.result == 1) {
                    // If the registration was successful where to go.
                    window.location.href = '<?=site_url('where to go')?>';
                } else {
                    // This is where all of the form errors will be displayed
                    $("#register_form_error").show();
                    var output = '<ul>';
                    for (var key in o.error) {
                        var value = o.error[key];
                        output += '<li>' + value + '</li>';
                    }
                    output += '</ul>';
                    $("#register_form_error").html(output);
                }
            }, 'json');

        });

    });
</script>

Lastly:

if($this->input->post('add_user'))

Shoud be:

if($this->input->post('$_POST'))

That way you get the entire post array.

-1
votes

Off the top of my head, you could try using individual errors.

In your view:

<?php
    $form_errors = array(
        form_error('field_1'),
        form_error('field_2'),
        form_error('field_3'),
        form_error('field_4'),
        form_error('field_5'),
        form_error('field_6')
    );

    $error = FALSE;

    foreach ($form_errors as $form_error)
    {
        if ( ! empty($form_error))
            $error = TRUE;
    }

    if ($error)
        echo "All fields are required".
?>

So basically what you are doing here, is filling an array of individual form errors. form_error() returns an empty string if the field is filled in correctly according to the validation rule, otherwise it will be an error message.

To confirm that everything is filled in correctly, you are looking for an array of empty strings. If a field isn't filled in correctly, your array will contain an element which has an error message.