32

I realise this request goes against the example provided in the CI documentation (which advises a separate 'success' page view), but I would like to reutilise a given form view after a form has been successfully submitted - displaying a success message then displaying a blank form. I've tried a few ways unsuccessfully to clear the validation set values (unsetting $_POST, setting rules / fields to an empty array and rerunning validation).

I could redirect to the same page, but then I'd have to set a session variable to display a success message - which is a messy approach.

Any ideas how to best achieve the above?

Muhammad Hassaan
  • 7,296
  • 6
  • 30
  • 50
BrynJ
  • 8,322
  • 14
  • 65
  • 89

8 Answers8

36

Redirect to itself. This way, no submissions have been run... This also gives you a way to show the flash_data.

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

    $this->form_validation->set_rules('firstname', 'First Name', 'required');
    $this->form_validation->set_rules('surname', 'Sur Name', 'required');

    if ($this->form_validation->run() === TRUE)
    {
                    // save data

        $this->session->set_flashdata('message', 'New Contact has been added');
        redirect(current_url());
    }

    $this->load->view('contacts/add', $this->data);
Teej
  • 12,764
  • 9
  • 72
  • 93
  • 1
    Absolutely the best way to handle this. – Zack May 11 '10 at 20:40
  • 3
    Been searching around for this and think it's the only way... though I hate storing success/error messages in the session. – Sherri Nov 19 '10 at 19:56
  • 1
    Thank you very much for this pearls of wisdom :) – Markon Feb 21 '11 at 10:27
  • 1
    The unfortunate thing about this solution is that if the redirect fails to render correctly, the flashdata will be lost. One would have to code a callback for the client to actively confirm the user received the flashdata, perhaps by a AJAX callback from a dialogue box that gets rendered, although that is limited to JS compatible clients. – deed02392 Dec 09 '12 at 19:53
12

Another solution, extend the library CI_Form_validation. The property $_field_data is protected, so we can acces it:

class MY_Form_validation extends CI_Form_validation {

    public function __construct()
    {
        parent::__construct();
    }

    public function clear_field_data() {

        $this->_field_data = array();
        return $this;
    }
}

And call the new method. This way, you can pass data without storing data in session.

    class Item extends Controller
    {
        function Item()
        {
            parent::Controller();
        }

        function add()
        {
            $this->load->library('form_validation');
            $this->form_validation->set_rules('name', 'name', 'required');

            $success = false;

            if ($this->form_validation->run())
            {
                $success = true;
                $this->form_validation->clear_field_data();
            }

            $this->load->view('item/add', array('success' => $success));
        }
    }
insertusernamehere
  • 23,204
  • 9
  • 87
  • 126
d5avard
  • 151
  • 1
  • 5
  • 2
    I think this one is much better than the chosen answer since it's working within the boundaries of CI. It's also very scalable in nature with the way it extends the Form_validation Library which is very OOP. – enchance Apr 01 '13 at 15:44
  • CI form validation constructor requires the rules array – pgee70 Aug 16 '17 at 12:57
7

Pass a TRUE/FALSE variable to your views that conditionally sets the values of the form.

The Controller

if($this->form_validation->run())
{
    $data['reset'] = TRUE;
}
else
{
    $data['reset'] = FALSE:
}

$this->load->view("form", $data);

The View:

<input type="text" name="email" value="<?php echo ($reset) ? "" : set_value('email'); ?>" />

<input type="text" name="first_name" value="<?php echo ($reset) ? "" : set_value('first_name'); ?>" />
bschaeffer
  • 2,824
  • 1
  • 29
  • 59
4

The set_value function fetches its value from the Form_validation object and not from the $_POST array. The Form_validation object stores its own copy of the posted values in a variable called $_field_data.

Its a hack, but you could clear this variable after handling a successful submission :

class Item extends Controller
{
    function Item()
    {
        parent::Controller();
        $this->load->model('item_model');
    }

    function add()
    {
        $this->load->library('form_validation');
        $this->form_validation->set_rules('name', 'name', 'required');

        $success = false;

        if ($this->form_validation->run())
        {
            $this->item_model->add_item($this->input->post('name'));
            $success = true;

            // Look away now. Hack coming up!
            // Clear the form validation field data
            $this->form_validation->_field_data = array();
        }

        $this->load->view('item/add', array('success' => $success));
    }
}
Stephen Curran
  • 7,433
  • 2
  • 31
  • 22
0

Hope this would be helpful. Finally I understand the whole concept of the extending the library. All you need to do is
Step 1: In this directory "application/libraries/" create a file named "MY_Form_validation.php" with the following php code

<?php if (!defined('BASEPATH')) exit('No direct script access allowed.');
class MY_Form_validation extends CI_Form_validation {

 public function MY_Form_validation() {
    parent::__construct();
  }

  public function unset_field_data()
    {    
        unset($this->_field_data);    
    }
}

Step 2: Then use the function "unset_field_data()" in you controller. for example below:

    if ($this->form_validation->run())
    {
        $this->item_model->add_item($this->input->post('name'));
        $success = true;

        $this->form_validation->unset_field_data();
    }
dt teja
  • 27
  • 1
  • 8
0

I've found that where:

  1. there's more than one CI view-partials which make up the page and their controller methods perform validation
  2. one of the validations failed and produced an error since the last page-refresh, say with an incorrectly formatted or typed input field value

it isn't enough to clear only the validation-rules array, you need to clear the validation-error array too.

To this end, I've added a method to system/libraries/Form_Validation.php, as follows:

public function clear_rules()
{
    $this->_error_array = array();
    $this->_field_data = array();
    return $this;
}

Returning $this is important if you want to chain your form-validation methods.

quinny
  • 656
  • 1
  • 7
  • 24
0

In newer version 3.X, to clear set_value , $_POST=array() and $this->_field_data = array(); in MY_Form_validation.php library. try

Clear form data after success codeigniter using php not jquery

Bhunesh Satpada
  • 770
  • 1
  • 6
  • 19
0

The answer from d5avard is wrong, the CI form validation should have the rules array parsed to it: If you don't do this you can use form validation with posted data, but not with over-ride data.

save this file as Libraries/MY_Form_validation.php

    /**
     * Class MY_Form_validation
     * @description extension of the CI_Form_validation
     * @property CI_DB_query_builder db database driver
     * @property CI_Benchmark benchmark
     * @property CI_Input input
     * @property CI_Output output
     */
    class MY_Form_validation extends CI_Form_validation
    {
        /**
         * MY_Form_validation constructor.
         * @param array $rules
         */
        function __construct($rules = array())
        {
            parent::__construct($rules);
            $this->_error_prefix        = '<div class=""><p>';
            $this->_error_suffix        = '</p></div>';
        }

        /**
         * Resets the form validation class for multiple runs.
         * @param array $rules
         */
        public function initialise($rules = array())
        {
            if (count($rules) == 0 )
            {
                require (APPPATH.'config'.DIRECTORY_SEPARATOR.'form_validation.php');
                $this->_config_rules = $config;
            }
            else
            {
                $this->_config_rules = $rules;
            }
            $this->_field_data          = array();
            $this->_error_array         = array();
            $this->_error_messages      = array();
            $this->_error_prefix        = '<div class=""><p>';
            $this->_error_suffix        = '</p></div>';
            $this->error_string         = '';
        }
    }
pgee70
  • 3,707
  • 4
  • 35
  • 41