Thursday, May 19, 2011

CodeIgniter - form_validation Errors with array Field Names

ok, another problem with Code Igniter. When the field name is an array, and there is validation performed on the  post values, if one of the fields has an array, this array will be applied to all the form_error().

e.g. You are building a list of questions as a survey and have this validation.
$this->form_validation->set_rules(‘questions[]’, ’Question Text', ‘trim|required|xss_clean’);

And in your view, you have
foreach ($questions as $qn)
{
  ...
  echo form_input(array('name'=>'question_text[]'));
  echo form_error(‘questions[]’);
  ...
}

In this case, if one of the questions text is empty, the "required" error will be triggered. And since the validation object only have 1 error param (print_r($this->_field_data) to know what I'm talking about), this same error will be applied to all the form_error();

So this is what I did (reference to Code Igniter 2.x)

1. In system/libraries/Form_validation.php (or you can subclass it, though this method is quite long and may not be so straight forward)
Look for :
function _execute($row, $rules, $postdata = NULL, $cycles = 0)
 {
  // If the $_POST data is an array we will run a recursive call
  if (is_array($postdata))
  {
   foreach ($postdata as $key => $val)
   {
    $this->_execute($row, $rules, $val, $cycles);
    $cycles++;
   }

   return;
  } 

Insert this after:
if ( $row['is_array'] )
  {
   $this->_field_data[$row['field']]['error'][$cycles] = '';
  }

Then look for this:
$this->_field_data[$row['field']]['error'] = $message;

We need to comment that out and new logic to handle the error array, so replace that line with this:
//$this->_field_data[$row['field']]['error'] = $message;
if ( $row['is_array'] )
    {
     $this->_field_data[$row['field']]['error'][$cycles] = $message;
    } else 
    {
     $this->_field_data[$row['field']]['error'] = $message;
    }

Step 2. create a file in /application/libraries/MY_Form_validation.php
class MY_Form_validation extends CI_Form_validation
{
 function __construct($config = array())
 {
  parent::__construct($config);
 }
 function error($field = '', $prefix = '', $suffix = '')
 {
  if ( ! empty($this->_field_data[$field]) 
   && $this->_field_data[$field]['is_array'])
  {
   return ($prefix?$prefix:$this->_error_prefix)
   .array_shift($this->_field_data[$field]['error'])
   .($suffix?$suffix:$this->_error_suffix);
  }
  
  return parent::error($field, $prefix, $suffix);
 }
}

Done!

I'll explain.

Step 1 turns the validation object error parameter into an array, and insert the error message only when there is a validation error. Else it creates an empty error array element.

Step 2 is to display the error message if it exists. Basically it uses the same logic of popping out the first error message (which may be a blank) like when we do a set_value('question[]);

So that's it.

May have bugs, use at your own risk.

Thursday, April 21, 2011

CodeIgniter - PATHS

CodeIgniter as a few reserved words that points to your application path, but it's not clear where they point to. The following is for windows on my dev machine, but applies to linux as well.

FCPATH=C:\xampplite\htdocs\appname\
BASEPATH=C:\xampplite\htdocs\
appname/system/
APPPATH=C:\xampplite\htdocs\appname/system/application/

So to point to some .dat files in your libraries dir (QR code), the string would be APPPATH.'libraries/qrcode/data'.

Friday, January 28, 2011

Ephemeralization

http://en.wikipedia.org/wiki/Ephemeralization

Check list

"There should be checklist for every station/position." - Apogee (ex RSAF Colonel)

Story of climbing a mountain

Got this from a senior management.

When we climb up a mountain, as the road is treacherous we have to move in a single file. In this way, the view of the leader will always be different from the others. When the group starts off on flat ground, everyone will think the going is easy. However, the leader will know that the climb is starting and the going will be difficult, so he has to plan for it. His view of the situation is different from the group.

As the group climbs and near the pinnacle, the leader will know this, and will brief a sigh of relieve. But the people following him cannot see th pinnacle yet, and will still think that there's more to go.

Similarly, when the group is walking down the hill, the leader will need to prepare for the next mountain to climb.

The morale of the story is that as a leader, you have to look at different things, plan ahead, and sometimes it may not be a popular decision, but it has to be made, as you should have the best view.