Conditionally Displaying or Hiding Form Fields
Hyvä Checkout form modifiers can show or hide fields dynamically based on the values of other fields. This capability enables conditional form logic such as hiding region fields for countries without regions, or displaying additional fields only when specific options are selected.
These examples demonstrate how to implement conditional field visibility using form modification hooks and field value inspection.
Removing Fields Based on Field Values
The most common conditional field scenario involves removing a field when another field contains a specific value. This example removes a custom field when the selected country is Germany.
<?php
namespace Hyva\Example\Model\FormModifier;
use Hyva\Checkout\Model\Form\EntityFormInterface;
use Hyva\Checkout\Model\Form\EntityFormModifierInterface;
class ConditionalFieldRemovalModifier implements EntityFormModifierInterface
{
public function apply(EntityFormInterface $form): EntityFormInterface
{
// Register callback to execute during form build
$form->registerModificationListener(
'init-my-form-field',
'form:build',
[$this, 'initMyFormField']
);
return $form;
}
public function initMyFormField(EntityFormInterface $form)
{
// Get the current country value from the form
$country = $form->getField('country_id')->getValue();
$myField = $form->getField('my_field');
// Remove custom field when country is Germany
if ($country === 'DE' && $myField) {
$form->removeField($myField);
}
}
}
This modifier registers a callback for the form:build hook. During form construction, the callback checks the country_id field value. If the country is Germany (DE) and the custom field exists, the modifier removes the field from the form.
The existence check (&& $myField) prevents errors when the field is not present in the form.
Adding Fields Conditionally
Form modifiers can also add fields dynamically when specific conditions are met. This approach is useful for fields that only apply in certain contexts.
This example demonstrates adding a text field conditionally:
public function initMyFormField(EntityFormInterface $form)
{
$country = $form->getField('country_id')->getValue();
// Only add the field for non-DE countries
if ($country !== 'DE') {
// Create a new text input field
$myField = $form->createField('my_field', 'text');
$myField->addData(['label' => 'Additional Information']);
// Add the field to the form
$form->addField($myField);
// Position the field relative to the country field
$form->getField('country_id')->assignRelative($myField);
}
}
The createField() method instantiates a new field with the specified identifier and input type. The addData() method sets field properties like the label. The assignRelative() method positions the new field relative to an existing field, maintaining logical field ordering.
Data Persistence for Dynamic Fields
Dynamically added fields do not automatically persist their values to the address entity. You must implement custom persistence logic for any fields added at runtime that need to save their values.
Creating Dynamic Select Fields
Select fields with options can also be added conditionally. This example creates a select field with predefined options.
public function initMyFormField(EntityFormInterface $form)
{
$country = $form->getField('country_id')->getValue();
if ($country === 'US') {
// Create a select field with options
$mySelect = $form->createField('my_select', 'select');
$mySelect->addData([
'label' => 'Delivery Preference',
'required' => 1,
'options' => [
'' => 'Please Choose',
'0' => 'Standard Delivery',
'1' => 'Priority Delivery'
]
]);
$form->addField($mySelect);
$form->getField('country_id')->assignRelative($mySelect);
}
}
The options array in addData() defines the select field's available choices. The array keys become option values, and the array values become the displayed text. Setting required to 1 makes the field mandatory.
Combining Multiple Conditions
More complex conditional logic can combine multiple field values to determine field visibility:
public function initMyFormField(EntityFormInterface $form)
{
$country = $form->getField('country_id')->getValue();
$postcode = $form->getField('postcode')->getValue();
// Show special field only for UK postcodes in specific range
if ($country === 'GB' && $postcode && str_starts_with($postcode, 'SW')) {
$specialField = $form->createField('london_zone', 'text');
$specialField->addData(['label' => 'London Zone']);
$form->addField($specialField);
$form->getField('postcode')->assignRelative($specialField);
}
}
This example checks both the country and postcode values before adding a field, demonstrating how multiple field values can influence conditional display logic.