Skip to content

Form validations

Form validation in Hyvä Checkout supports both client-side JavaScript validation for immediate user feedback and server-side Magewire validation for security. Client-side validation provides fast feedback to users, while server-side validation ensures data integrity. Both validation approaches can be used together for comprehensive form validation.

Client-side

Do not rely exclusively on client-side validation!

It is trivial to bypass browser-based form validation for experienced web developers. In-browser validation should be used only to give visitors fast feedback. Always use server-side validation as the primary way to check user input.

Client-side validation in Hyvä Checkout uses the Hyvä validation library to provide immediate feedback to users before form submission. Adding custom validation rules is pretty common. In Hyvä-Checkout, both client-side JavaScript validation can be used (via the Hyvä validation library), or server-side Magewire-based validation.

Setting JavaScript validation rules for a field is achieved through the utilization of the setValidationRule() method. This method accepts a rule name and optional parameters to configure the validation behavior.

// Results in: data-validate='{"maxlength": 10}'
$myField->setValidationRule('maxlength', 10);

// Results in: data-validate='{"required": true, "maxlength": 10}'
$myField->setValidationRule('required');

Custom validation rules

Custom validation rules in Hyvä Checkout enable developers to implement specialized field validation beyond the built-in rules. To define a custom JavaScript validation rule, apply it to the field as shown above. Subsequently, render a template on the checkout page to incorporate the custom rule.

Step 1: Set the rule on the field

You can specify validation rules during various stages, including utilizing a form modifier or incorporating them during form construction within the populate method. Apply the custom rule name to the field using the setValidationRule() method.

$myField->setValidationRule('example');

Step 2: Render the template for the rule

Custom validation rules in Hyvä Checkout should reside within their own dedicated PHTML file for maintainability. To ensure that custom validation rules reside within their own dedicated PHTML file, register the PHTML file within a container that automatically renders it on the page. This can be achieved by utilizing the hyva_checkout_index_index.xml layout file.

<referenceContainer name="before.body.end">
    <block name="my-js-validation-rule"
           template="My_Example::my-validation-rule.phtml"
    />
</referenceContainer>

Step 3: Declare the rule in the template

The custom validation rule must be written in JavaScript and registered with the Hyvä Advanced Form Validation library. The rule must be written and incorporated into the Advanced Form Validation.

This example demonstrates a custom validation rule that checks for prime numbers in German addresses:

<script>
    (() => {
        // Ensure Hyvä form validation library is available before registering the custom rule
        if (hyva && hyva.formValidation) {
            const isPrime = n => {
                // Numbers less than or equal to 1 are not prime
                if (n <= 1) return false;

                // Check for divisibility from 2 to square root of n
                for (let i = 2; i < Math.sqrt(n); i++) {
                    if (n % i === 0) return false;
                }

                return true;
            };

            /**
             * Custom validation rule: validates prime numbers for German addresses
             * @param {string} value - The field value being validated
             * @param {object} options - Validation options passed to the rule
             * @param {object} field - The field object being validated
             * @param {object} context - The form context containing all fields
             * @returns {boolean|string} - True if valid, error message string if invalid
             */
            hyva.formValidation.addRule('example', (value, options, field, context) => {
                const el = field.element;

                // Only validate if the rule is enabled and the field has a value
                if (options && el.value.length && context.fields.country_id) {
                    const country = context.fields.country_id.element.value;

                    // For German addresses, require prime numbers
                    if (country === 'DE' && !isPrime(parseInt(el.value))) {
                        return '<?= $escaper->escapeJs(__('Please enter a prime number.')) ?>';
                    }
                }

                // Return true if validation passes
                return true;
            });
        }
    })()
</script>