Skip to content

Magewire forms

Forms are one of the most important types of interaction on websites. Magewire includes robust support for form validation.

With form components, input element values are mapped to Magewire component properties.

User input needs to be validated.
Not having to duplicate validation rules on the front end using JavaScript and in the backend using PHP is a big value proposition of Magewire.
With Magewire, the validation rules can be declared only once in the PHP Magewire component, and they still are applied on the front end in an interactive manner.

Under the hood, Magewire uses the rakit/validation library to apply validation rules to properties.
This section of the docs will give you enough information to get started.

The form component base class

Magewire form components extend from \Magewirephp\Magewire\Component\Form instead of the regular \Magewirephp\Magewire\Component.

This parent class provides the ability to declare validation rules for properties.

Declaring validation rules

Validation rules are declared on the component using a protected array property $rules.
The protected $rules array is a map of property names to validation-rules.

class MyComponent extends \Magewirephp\Magewire\Component\Form
{
    /* public component properties */
    public $email;
    public $userName;
    public $vatId;

    /* protected property validation rule map */
    protected $rules = [
        'email'    => 'required|email',
        'userName' => 'required|min:4',
        'vatId'    => 'required|regex:/^(?:NL)?[a-z0-9]{9}B[a-z0-9]{2}$/i',
    ];
}

You can find a list of all rules in the rakit/validation readme file.

Triggering property validation

Just declaring validation rules is not enough. The validate() method needs to be called to trigger the validation.

When to do that depends on the use case.

If properties should be validated immediately after they change, it would be appropriate to call validate() in one of the updated lifecycle hook methods.

For example:

public function updated($value, $prop)
{
    $this->validate();
    return $value;
}

If the validation should happen when a form is submitted, the validation can be applied in a custom save method of the component.

public function save()
{
    $this->validate();

    $this->repository->save($this);
}
Under the hood

If a rule does not pass, the validate() method will throw a Magewirephp\Magewire\Exception\AcceptableException exception.

These exceptions are special in that they do not break the component lifecycle. However they will abort the method that triggered validate().

Showing failure messages

Failure messages are not shown automatically.
The code to display messages has to be added to templates in the location where they should be shown.

Regarding user experience, the current best practice is to display validation error messages next to the input element.

<form>
    <input type="text" wire:model="name"
        <?php if ($magewire->hasError('name')): ?>
        aria-invalid="true" aria-errormessage="name-error"
        <?php endif ?>
    >

    <?php if ($magewire->hasError('name')): ?>
    <span class="text-red-800" id="name-error">
        <?= $escaper->escapeHtml($magewire->getError('name')) ?>
    </span>
    <?php endif ?>
</form>

If you need to display all messages combined in one location, the $magewire->getErrors() method will return all failure messages as an array.

Custom failure messages

Each rule comes with a default validation failure message.
The default message can be customized by providing an alternative in the protected array property $messages.

This $messages array maps the attribute name and rule-ID to an array message.

For example, to specify a custom message if no value is provided for the required attribute email, the array key would be email:required.

To create more meaningful error messages, the current property value can be included by using the placeholder :value. It will be replaced with the current invalid value. In the same way, the placeholder :attribute will be replaced with the property name.

protected $rules = [
    'vatId'    => 'required|regex:/^[a-z0-9]+$/i',
];

protected $messages = [
    'vatId:required' => (string) __('Please specify a valid EU VAT ID to proceed'),
    'vatId:regex' => (string) __('":value" is not a valid EU VAT ID'),
];

You can use the regular Magento translation function __() to localize error messages, as shown in the example above.