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 valueempty()- 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:
- Field values reflect the user's submitted data
- The form state is stable and ready for programmatic modification
- 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 changesform: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.