The Loki Components core package offers server-side validation. This is further extended by the Loki Field Components package with client-side validation.
The goal of Loki Field Components is to standardize the way that Loki Components are working as fields. For instance, Loki Field Components are easily created via ready-made PHTML templates. Each Field Component extends from the LokiComponentType object literal and inherits a value (which can be anything).
All field templates make sure that an AJAX push of the Alpine.js property value occurs via the submit() method (and not directly via post()) and within that submit() method validation is triggered: Validation happens by going through a list of validationActions, one of them being a callback to LokiComponentValidator.validate(this) (explained below).
On top of this, each Field Component has a property validators which contains a flat array of validator names as declared through the etc/loki_components.xml file. These validator entries are used by LokiComponentValidator as well.
LokiComponentValidatorA Loki Component will only be validated client-side (by the LokiComponentValidator defined in Loki_FieldComponents::script/validator.phtml) if the flag skipValidation is set to true.
Next, if the Alpine.js component contains a validate() method, it will be called to validate the component. In most cases, such a method does not exist and the validator will proceed with other means to validate the component. This assumes that the valid property is set to either true or false. It also assumes that the validator property contains a list of validators. This list is looped through and every validator is called, until one validator fails or until all validators succeed.
If you want to validate a component manually, you can use a snippet like the following:
LokiComponentValidator.validate(Alpine.store('LokiCheckout').get(componentId));
LokiComponentValidator objectThe LokiComponentValidator object is declared globally and contains a list of validators (by default, only required) and a validate(component) method. Its goal is to serve as a registry of validators and to be a service for validation.
Adding a new validator (for instance badWords) is done by simply adding a new entry to this list of validators:
<script>
LokiComponentValidator.validators.badWords = function (component) {
if (component.value.includes('fart')) {
component.addLocalError('<?= $escaper->escapeHtml(__('Go wash your mouth')); ?>');
return false;
}
return true;
}
</script>
The goal is to first write a PHP-based Validator - to guarantee validation occurs at all times, even when JavaScript is disabled by bastards - and then to replicate the PHP-behaviour in JavaScript.