Validate an Afform field in an extension
The challenge¶
In our extension we want to validate a field from a form created with FormBuilder.
The example¶
As an example we will look at the Simple Orders extension. In this extension we have a form to add a new item which was built with FormBuilder.
On the form for a new item there are 3 fields: 1. name 2. description 3. type (options, initially with values digital and physical)

We want to add validation that the name that is entered in the form does not already exists for another item.
The solution¶
We will add a listener for the hook civi.afform.validate and add a static method to perform the validation.
Add the validation method¶
We will add the listener and the validation method onAfformValidate to the HookHandler class (there are already other listeners in there too).
namespace Civi\Simpleorders;
use Civi\Afform\Event\AfformValidateEvent;
use Civi\Core\Event\GenericHookEvent;
use Civi\Core\Event\PostEvent;
use Civi\Core\Service\AutoSubscriber;
use CRM_Core_Session;
use CRM_Simpleorders_ExtensionUtil as E;
/**
* Class to handle the hooks for the simple orders extension
*
* @author Erik Hommel (CiviCooP) <erik.hommel@civicoop.org>
* @license AGPL-3.0
*/
class HookHandler extends AutoSubscriber {
public static function getSubscribedEvents(): array {
return [
'civi.afform.validate' => ['onAfformValidate'],
'hook_civicrm_buildForm' => ['onBuildForm'],
'hook_civicrm_postCommit' => ['onPostCommit'],
'hook_civicrm_searchColumns' => ['onSearchColumns'],
'hook_civicrm_tabset' => ['onTabset'],
'hook_civicrm_validateForm' => ['onValidateForm'],
];
}
/**
* @param AfformValidateEvent $event
* @return void
*/
public static function onAfformValidate(AfformValidateEvent $event): void {
$values = $event->getSubmittedValues();
if ($values['SoItem1']) {
foreach ($values['SoItem1'][0]['fields'] as $fieldName => $fieldValue) {
if ($fieldName == 'name' && \CRM_Simpleorders_BAO_SoItem::isExistingName($fieldValue)) {
$event->setError(E::ts('Item name already exists in the database'));
}
}
}
}
The result¶
