Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Validation error_class not set on fields with errors?
  • I'm trying to validate a fieldset that I've created for a simple contact form (not using an ORM model). It looks like this...
    $form = \Fieldset::instance();
    $form->add('name', 'Name');
    $form->add('phone', 'Phone')->add_rule('required');;
    $form->add('email', 'Email')->add_rule('valid_email');
    $form->add('message', 'Message', array('type'=>'textarea'));
    $form->add('submit', '', array('type'=>'submit', 'value'=>'Send', 'class'=>'btn medium primary'));
    $this->view->set('form', $form->build(), false);
    
    The form comes up great, and I can list out the error messages by iterating through $form->validation()->errors(). However, I was expecting each field with an error to have the error_class specified in the form config. So, if for example the user types in an invalid email address, I would expect the form to come back with class="validation_error" in the table cells for the email field. Unfortunately, this doesn't happen. The class for the table cells stay empty. It seems like there's a problem in the Fieldset_Field class. Maybe at line 460? From what I can tell, this is where the logic for this is at, and the error() method is returning false even when there's actually an error for the field. Or maybe I'm wrong about how this should work?
  • The form HTML of a fieldset field is generated in the Fieldset_Field class, by the template() method. Looking through the code it does fetch the 'error_class' setting from the config if the field is in error, and inserts it in the template. If $this->error() returns false, perhaps there's something wrong with the way you validate, so that the fieldset is not aware of the validation? Your code example doesn't show any validation taking place...
  • Thanks! That definitely pointed me in the right direction. The problem was that I was generating the form using $form->build() before running the validation. So obviously it didn't know if there was an error or not at that point. It's a simple mistake, but here's the fix for anyone else running into this...
    public function action_index()
    {
     $form = \Fieldset::instance();
     $form->add('name', 'Name');
     $form->add('phone', 'Phone')->add_rule('required');;
     $form->add('email', 'Email')->add_rule('valid_email');
     $form->add('message', 'Message', array('type'=>'textarea'));
     $form->add('submit', '', array('type'=>'submit', 'value'=>'Send', 'class'=>'btn medium primary'));
    
    //DON'T BUILD THE FORM BEFORE RUNNING VALIDATION...
     //$this->view->set('form', $form->build(), false);
    
     if($form->validation()->run() == true)
     {
     }
    
    //BUILD IT AFTERWORDS INSTEAD...
     $this->view->set('form', $form->build(), false);
    }
    
  • This is indeed (almost) the normal flow of an action: - build the fieldset
    - check for input (you don't do this)
    - run the validation
    - if valid, process the data, and redirect away
    - pass the fieldset to the view, and return the view (you don't do this either) As to that last point: controller actions need to return either a Response object, or something that can be cast to string (which will be encapsulated by a Response object by the request). If you don't return anything, your logs will be full of warnings. (unless you use the template controller, which will create the Response object for you in it's after() method).
  • Sorry... I didn't mention I'm actually hiding even more code in the base controller, which is automagically loading the view into a template. So your last point should be taken care of. $this->view is created in the before() method of the base controller and eventually wrapped in a template and output in the after() method. As for checking for input: I'm not sure what you mean by that. Doesn't $form->validation()->run() return false if there's no input?
  • You don't need/want to run validation if there's no input:
    if (\Input::post())
    {
        if ($form->validation()->run())
        {
            // save the data and redirect away
        }
        else
        {
            // post validation actions if needed
        }
    }
    
    // load the form
    
    In your case probably not an issue, but if you have post validation code, you obviously want to run that only if there was something to validate, not at the initial load of the form.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion