We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Validators should add form input attributes automatically

If you add a validator to an input, Phalcon won't add relevant HTML attributes. Most validation can be done client-side without need to send the form to server. Of course, you can specify HTML attributes manually 2 ways but why can't it be done automatically? No need to repeat yourself (DRY).

Example form class:

class UserForm extends Form
{
    public function initialize()
    {
        //Prepare login field
        $login = new Text('login', array(
            'maxlength' => 25, //why do we need to write it manually?
            'required' => '' //Phalcon cannot make this attribute empty (not empty string)
        ));

        //If you add this validator, Phalcon should add relevant attributes automatically
        //In this case - maxlength or pattern
        $login->addValidator(new StringLength(array(
            'min' => 2,
            'max' => 25,
            'messageMinimum' => 'Message minimum',
            'messageMaximum' => 'Message maximum'
        )));
    }
}

Look at all built-in validators:

  1. Between - in case of number inputs - min/max attributes
  2. Confirmation - probably impossibe without JavaScript
  3. PresenceOf - add required attribute (in HTML5 it can be empty)
  4. Regex - probably pattern attribute
  5. StringLength - upper value - maxlength, lower - pattern if Regex not present

PS. I wonder whether it's really worth to use Form class. It's very uncomfortable. You can also write all HTML code manually and do simple validation in controller or model. In case of forms with dynamic fields (we don't know how much) we need additional loops etc. There is one advantage - using form.render() for <select> saves a bunch of Volt code with conditions.

Validation in controller or model?



8.6k

Hi,

well, I'm new to phalcon but atm I don't see much advantage: you can write methods to get different variations of the same form - e.g. renderGuestForm, renderPremiumMemberForm. This makes templates much more readable. But on the contrary you'll have to write some html code in the form class (e.g. the form tags). Either way, I think it's not worth using form class atm (or at least for my basic usecase).



26.3k

There are some situations where there is a need to use validators in the Form. Such situation is where your Form collects data that will be used to create records in more than one Model.

In other words when Form fields are not exactly the same as Model fields.

Let say you have two Models:

(1) Products with Product-ID and Product-Name

(2) Prices with Price-ID, Product-ID, Price, Creation-Date

Let say you need such models because you want to have a history how a product price changed over time.

Now let say you need a form to add a new product. Such form will have only two fields:

(1) Product name

(2) Product price

Base on these two fields of one form two models will be created.



2.6k

Imho setting form attributes from the validator beats the single responsibility principle. The validator should just do that,,, validate. Nothing more. This also means mixing logic with view stuff but the Form already blurs the line on that because you can set the attributes from the code.

To make the code DRY without breaking breaking SRP and crossing layers the options should have the same name. It the allows you to set the attributes like this:

$config = array(
    'minlength' => 2,
    'maxlength' => 25
);

$validatorConfig = \array_merge($config, array(
        'messageMinimum' => 'Message minimum', 
        'messageMaximum' => 'Message maximum'
));

Phalcon\Forms\Element::__construct("Label", $config);

$login->addValidator(new StringLength($validatorConfig));