I'd like to display errors on my form, highlighting the fields which have errors, and displaying the error text next to the field. If there's no elegant way to display next to each field, above would be fine.
I've found examples from earlier versions, but the API has seemed to change and they do not work for 3.2.
It's just a project I'm learning Kohana with, so it's not critical. I just want to know the "kohana" way of handling this problem.
In my controller, I have this:
if (isset($_POST) && Valid::not_empty($_POST))
{
$post = Validation::factory($_POST)
->rule('zipcode', 'not_empty'));
if ($post->check()) {
$errors = $post->errors('zipcode');
}
}
$this->template->content = View::factory('myview', $data)
->bind('errors', $errors);
And here is my form in 'myview.php':
<?php echo Form::open(); ?>
<dl>
<dt><?php echo Form::label('zipcode', 'Zip Code') ?></dt>
<dd><?php echo Form::input('zipcode') ?></dd>
</dl>
<p><?php echo Form::submit(NULL, 'Get Records'); ?></p>
<?php echo Form::close(); ?>
I've taken the approach of extending the Form helper class to add an 'error' class name on the form fields, as well as showing the error message in the field label.
<?php defined('SYSPATH') or die('No direct script access.');
class Form extends Kohana_Form {
private static function attributes($name, & $attributes = NULL, $errors = NULL)
{
// Set the id attribute
if (!isset($attributes['id']))
{
$attributes['id'] = $name;
}
if ($errors !== NULL)
{
// Merge in external validation errors.
$errors = array_merge($errors, (isset($errors['_external']) ? $errors['_external'] : array()));
// Set the error classname
if (isset($errors[$name]))
{
$attributes['class'] = trim( (string) @$attributes['class'].' error-field');
}
}
}
public static function input($name, $value = NULL, array $attributes = NULL, array $errors = NULL)
{
static::attributes($name, $attributes, $errors);
return parent::input($name, $value, $attributes);
}
public static function select($name, array $options = NULL, $selected = NULL, array $attributes = NULL, array $errors = NULL)
{
static::attributes($name, $attributes, $errors);
return parent::select($name, $options, $selected, $attributes);
}
public static function password($name, $value = NULL, array $attributes = NULL, array $errors = NULL)
{
static::attributes($name, $attributes, $errors);
return parent::password($name, $value, $attributes);
}
public static function textarea($name, $body = '', array $attributes = NULL, $double_encode = TRUE, array $errors = NULL)
{
static::attributes($name, $attributes, $errors);
return parent::textarea($name, $body, $attributes, $double_encode);
}
public static function file($name, array $attributes = NULL, array $errors = NULL)
{
static::attributes($name, $attributes, $errors);
return parent::file($name, $attributes);
}
public static function label($input, $text = NULL, array $attributes = NULL, array $errors = NULL, $view = 'messages/label_error')
{
if ($errors !== NULL)
{
// Merge in external validation errors.
$errors = array_merge($errors, (isset($errors['_external']) ? $errors['_external'] : array()));
// Use the label_error view to append an error message to the label
if (isset($errors[$input]))
{
$text .= View::factory($view)->bind('error', $errors[$input]);
}
}
return parent::label($input, $text, $attributes);
}
}
You then pass in the $errors
array into the label and field helper methods:
<?php echo
Form::label('username', 'Username', NULL, $errors),
Form::input('username', $user->username, NULL, $errors);
?>
This idea was suggested on the Kohana forums but I've struggled to find the original thread. Anyway, I've found this approach works best for me.
[edit] View an example of this approach in action here: http://kohana3.badsyntax.co/contact (submit the form)