Skip to content

Setting Field Values Programmatically

Hyvä Checkout form modifiers can programmatically set or clear field values in response to form events. This capability enables use cases such as clearing dependent fields when a parent field changes, or automatically populating fields based on business logic.

This page explains how to update field values using form modification hooks and describes the critical timing constraints for value updates.

Methods for Setting Field Values

The EntityFieldInterface provides two methods for manipulating field values:

  • setValue($value) - Sets the field to a specific value
  • empty() - Clears the field value

These methods work within form modification callbacks to update field state programmatically.

Required Hook: form:*:updated Events

Field value updates only take effect when performed in form:*:updated modification hooks. Attempting to set field values in other hooks (like form:build) has no effect on the field's actual value.

Critical Timing Constraint

Setting field values only works in form:*:updated hooks. Value changes in other hooks are ignored. Use form:billing:updated for billing address fields or form:shipping:updated for shipping address fields.

The form:*:updated hooks execute after form data has been submitted and validated, making them the appropriate time to programmatically adjust values based on submitted data.

Complete Example: Conditional Field Clearing

This example demonstrates clearing a field value when a condition is not met. The modifier uses the form:billing:updated hook to clear fields when a country-specific feature is unavailable.

<?php

namespace Hyva\Example\Model\FormModifier;

use Hyva\Checkout\Model\Form\EntityFormInterface;
use Hyva\Checkout\Model\Form\EntityFormModifierInterface;

class ConditionalFieldValueModifier implements EntityFormModifierInterface
{
    public function apply(EntityFormInterface $form): EntityFormInterface
    {
        // Register callback for the billing address updated event
        $form->registerModificationListener(
            'empty-value-if-field-disabled',
            'form:billing:updated',
            [$this, 'emptyMyField']
        );

        return $form;
    }

    public function emptyMyField(EntityFormInterface $form)
    {
        // Get the current country value
        $country = $form->getField('country_id')->getValue();

        // Clear fields if example feature is not available for this country
        if (!$this->isExampleAvailable($country)) {
            // Clear the custom field
            $form->getField('my_field')->empty();

            // Set another field to a specific value
            $form->getField('other_field')->setValue('nope');
        }
    }

    private function isExampleAvailable(string $country): bool
    {
        // Business logic to determine feature availability
        return in_array($country, ['US', 'CA', 'GB']);
    }
}

This modifier registers a callback for form:billing:updated. When the billing address form is updated, the callback checks the selected country. If the country does not support the example feature, the modifier clears my_field using empty() and sets other_field to a specific value using setValue().

Understanding the Updated Hook Timing

The form:*:updated hooks execute during form processing after user input has been received and validated. This timing is essential because:

  1. Field values reflect the user's submitted data
  2. The form state is stable and ready for programmatic modification
  3. Changes made in these hooks persist through the form submission process

Conversely, hooks like form:build execute during initial form construction before user input is available, making them unsuitable for value manipulation.

Limitations: Preceding Request Value Updates

The form:*:updated hooks do not execute during the initial page load (the "preceding request" in Magewire terminology). These hooks only execute in response to form submissions.

Cannot Set Values on Initial Load

It is not currently possible to reliably set field values during the initial form render using form modification hooks. The form:*:updated hooks only execute after form submission, not during initial page load.

If you need to enforce specific field values during the initial checkout page load, you must use mechanisms outside the Hyvä Checkout form API:

  • Magento plugins - Intercept address loading methods to modify data before it reaches the form
  • Event observers - Listen to address-related events to modify values
  • Customer data providers - Customize the data source that feeds the form's initial values

These approaches work at the Magento data layer rather than the Hyvä Checkout form layer, allowing you to influence initial values before the form is constructed.

Choosing the Correct Updated Hook

Hyvä Checkout provides separate update hooks for different form types:

  • form:billing:updated - Use for billing address field value changes
  • form:shipping:updated - Use for shipping address field value changes

Ensure you register your callback with the appropriate hook for the address type you are modifying.

Example: Setting Value Based on Multiple Fields

This example demonstrates setting a field value based on multiple field values:

public function updateCalculatedField(EntityFormInterface $form)
{
    $country = $form->getField('country_id')->getValue();
    $region = $form->getField('region_id')->getValue();
    $postcode = $form->getField('postcode')->getValue();

    // Calculate shipping zone based on location
    $zone = $this->calculateShippingZone($country, $region, $postcode);

    // Set the calculated zone in a custom field
    if ($zoneField = $form->getField('shipping_zone')) {
        $zoneField->setValue($zone);
    }
}

This callback reads multiple field values, performs a calculation, and sets the result in another field. The existence check (if ($zoneField = ...)) prevents errors when the field is not present.