Welcome Guest, Not a member yet? Register   Sign In
Database populated form fields (e.g. edit mode) and form validation
#1

[eluser]onblur[/eluser]
How are people managing the editing/updating of database records using CI form validation (v1.7) when validation fails?

The scenario is:
1. retrieve record from database for editing (ie. editing form is pre-populated with data)
2. submit edited record
3. controller does form validation - one or more validation rules are not met
4. reload form and display **submitted** data, and display validation errors

How are folks reloading the form with the submitted (edited) data?

I can reload the form with the original unedited data, but I want to display the edited data so the user can correct mistakes rather than edit all over again.
#2

[eluser]walrus_lt[/eluser]
...
#3

[eluser]majidmx[/eluser]
As far as I guess, you're replacing data to the default one which is loaded from database.
if you use set_value method you can easily repopulate the data :

controller :
Code:
function edit_news($news_id)
{
    $this->load->model('Model_news');
    
    $current_news    =    $this->Model_news->get_news($news_id);
    
    $data['default']['title']        =    $current_news->nw_title;
    $data['default']['body']        =    $current_news->nw_body;
    
    $this->load->view('news_edit_view' , $data);        
}

function update_news()
{        
    $this->load->library('form_validation');    
    $this->form_validation->set_rules('title', 'News Title', 'xss_clean|trim|required');        
    $this->form_validation->set_rules('body', 'News Body', 'xss_clean|trim|required');    
    if ($this->form_validation->run() == FALSE)
    {
        $this->load->view('news_edit_view');
    }else
    {
        // update the database
    }
}

and your view would look like this :
Code:
<input type="text" name="title" id="title" size="80" maxlength="255" value="<?PHP echo    set_value('title' , isset($default['title'])?$default['title']:'' );?>" />
<textarea name="body" id="body" rows="20" cols="60"><?PHP echo    set_value('body' , isset($default['body'])?$default['body']:'' );?></textarea>

note that, you don't need to fetch the record from database again in update_news

let me know if you can get it worked.
Cheers,
MajiD Fatemian
#4

[eluser]onblur[/eluser]
Thanks majidmx!

Your solution is working for me. I had checked a couple of similar posts suggesting the ternary operator but I couldn't get it to work in my specific situation. You reply clarified a couple of things and now have it working well.

Cheers!
#5

[eluser]majidmx[/eluser]
You're welcome.
Glad to hear you have it working properly now.

Take care,
#6

[eluser]huston[/eluser]
I am new to CodeIgniter and was frustrated by this same issue. I have been testing a different approach which seems to be working so far.

First I extended the CI_Form_validation class to setup the _field_data when the request is not a POST. Then I added a method, set_default_value, to set the default values for the fields in _field_data.

Code:
class MY_Form_validation extends CI_Form_validation {

    function CI_Form_validation($rules = array()) {
        parent::CI_Form_validation($rules);
    }

    function set_default_value($data, $value = null) {
        if (is_array($data)) {
            foreach ($this->_field_data as $field => $row) {        
                if ($row['is_array'] == TRUE) {
                    $this->_field_data[$field]['postdata'] = $this->_reduce_array($data, $row['keys']);
                } else {
                    if (isset($data[$field]) AND $data[$field] != "") {
                        $this->_field_data[$field]['postdata'] = $data[$field];
                    }
                }
            }
        } else {
            if (isset($this->_field_data[$data])) {
                $this->_field_data[$data]['postdata'] = $value;
            }
        }
    }

    function set_rules($field, $label = '', $rules = '')
    {
        if (count($_POST) != 0) {
            parent::set_rules($field, $label, $rules);
        } else {
            if (is_array($field)) {
                foreach ($field as $row) {
                    if ( ! isset($row['field'])) {
                        continue;
                    }

                    $this->set_rules($row['field']);
                }
                return;
            }

            if ( ! is_string($field)) {
                return;
            }

            $this->_field_data[$field] = array('postdata' => NULL);
        }
    }
}

Then I added a call to set_default_value to my controller to set the current value for a field.

Code:
$this->form_validation->set_default_value('email', '[email protected]');

Here is the example from the CI Form Validation documentation with this code added.

form.php:
Code:
class Form extends Controller {
    
    function index()
    {
        $this->load->helper(array('form', 'url'));
        
        $this->load->library('form_validation');
        
        $this->form_validation->set_rules('username', 'Username', 'trim|required|min_length[5]|max_length[12]|xss_clean');
        $this->form_validation->set_rules('password', 'Password', 'trim|required|matches[passconf]|md5');
        $this->form_validation->set_rules('passconf', 'Password Confirmation', 'trim|required');
        $this->form_validation->set_rules('email', 'Email', 'trim|required|valid_email');

        $this->form_validation->set_default_value('email', '[email protected]');

        if ($this->form_validation->run() == FALSE)
        {
            $this->load->view('myform');
        }
        else
        {
            $this->load->view('formsuccess');
        }
    }
}

And the code for the view remains unchanged from the CI documentation.

myform.php:
Code:
<html>
<head>
<title>My Form</title>
</head>
<body>

<?php echo validation_errors(); ?>

<?php echo form_open('form'); ?>

<h5>Username</h5>
&lt;input type="text" name="username" value="&lt;?php echo set_value('username'); ?&gt;" size="50" /&gt;

<h5>Password</h5>
&lt;input type="text" name="password" value="&lt;?php echo set_value('password'); ?&gt;" size="50" /&gt;

<h5>Password Confirm</h5>
&lt;input type="text" name="passconf" value="&lt;?php echo set_value('passconf'); ?&gt;" size="50" /&gt;

<h5>Email Address</h5>
&lt;input type="text" name="email" value="&lt;?php echo set_value('email'); ?&gt;" size="50" /&gt;

<div>&lt;input type="submit" value="Submit" /&gt;&lt;/div>

&lt;/form&gt;

&lt;/body&gt;
&lt;/html&gt;
#7

[eluser]majidmx[/eluser]
Hi Huston,
Glad to hear from you, you'll love CI.
That's exactly the way I used to do for the CI versions before 1.7
In 1.7 the validation class has changed a lot and I really prefer to use it in a way that I mentioned above.
I mean :
Quote:controller

Code:
$data['default']['title']        =    $current_news->nw_title;
Quote:view
Code:
&lt;input type="text" name="title" id="title" size="80" maxlength="255" value="&lt;?PHP echo    set_value('title' , isset($default['title'])?$default['title']:'' );?&gt;" /&gt;
#8

[eluser]huston[/eluser]
majidmx,

Thanks for your reply. I saw that technique but I am pretty lazy, I am planning on extending some of the form helpers so I don't need to use set_value at all from my view. The code is so repetitive that it seems like it could be easily managed by the framework.




Theme © iAndrew 2016 - Forum software by © MyBB