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

Forms - Appending messages to form element from controler

Hello!

I'm currently finishing up the login form for our application (forms never get boring). I made my form pretty much the standard way:

class LoginForm extends Form
{

    /**
     * Initializing login form
     * 
     * @author           Vorta
     * @version          1.0
     * @since            2.1.0
     * @package          USER
     */
    public function initialize ()
    {

        $email = new Email('email', [
            'class' => 'form-control input-md'
        ]);
        $email
            ->setLabel('Email:')
            ->addValidators([
                new PresenceOf([
                    'message' => 'You haven\'t input your email.',
                    'cancelOnFail' => TRUE
                ]),
                new EmailValidator([
                    'message' => 'The email you input is not valid.'
                ])
            ])
            ->setUserOption('type', 'input');

        $this->add($email);

        $password = new Password('password', [
            'class' => 'form-control input-md'
        ]);
        $password
            ->setLabel('Password:')
            ->addValidators([
                new PresenceOf([
                    'message' => 'Please input your password.'
                ])
            ])
            ->setUserOption('type', 'input')
            ->setDefault('');

        $this->add($password);
    }
}

Once a submission is made, if the form is valid, the credentials are sent to our Auth class. Should Auth return an error message, e.g. "Wrong password", I would like to append that message to the password element. Accessing element's appendMessage() method from controller seems to be impossible so I added the following function within the form:

public function appendMessageFor ($attribute, $message)
{
    $this->_elements[$attribute]->appendMessage($message);
}

It does append a message to the element, but it is never received by the form. If it happens that form is not valid, then I noticed that this line would add a message that would be displayed on the frontend:

$this->_messages[$attribute]->appendMessage($message);

If the form is valid, the line above wouldn't work as messages is NULL. How can one, if it's even possible, append an error message to a field from controller, even if validation tests succeeded?

$form->_messages is filled on isValid() call so adding messages to a field after calling isValid() will not be reflected in the form messages.

A workaround from controller could be

<?php

public function fooAction() {
    # Form validation
    # ...

    /** @var \Phalcon\Validation\Message\Group */
    $messages = $form->getMessagesFor('wrong_field');

    $messages->appendMessage(new  \Phalcon\Validation\Message(/* ... */) );
}


4.9k

Thank you for idea. This would, again, be available only if there were some error messages for that field.

The way we got this solved is actually by avoiding it. Since you don't really want to tell the user whether he gave a correct email to prevent hacking we are outputting login errors separately, as form level errors, instead of per-field errors. We're outputting it by filling a variable in view, which is an array of messages. Completely avoiding the Form element and its messages.