23
Mar.2018
Drupal 10: A custom validator for checking the field depending on the value of another field
In one project I use two independent date fields "Start Date" field_start_date
and "End Date" field_end_date
(with a Calendar). Both fields are optional. But if "End Date" is selected, I need to check "Start Date", so the first field shouldn't be empty and "End Date" should be greater or equal.
This code shows how I implemented the solution, which checks a few fields in the same time.
File
[MODULE_NAME]/[MODULE_NAME].module
<?php use Drupal\Core\Entity\EntityTypeInterface; /** * Implements hook_entity_bundle_field_info_alter(). */ function [MODULE_NAME]_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) { if (!empty($fields['field_end_date'])) { $fields['field_end_date']->addConstraint('StartEndDateChecking'); } }
File
[MODULE_NAME]/src/Plugin/Validation/Constraint/StartEndDateCheckingConstraint.php
<?php namespace Drupal\[MODULE_NAME]\Plugin\Validation\Constraint; use Symfony\Component\Validator\Constraint; /** * Checks if "End Date" not empty. * * "Start Date" must be not empty * and "End Date" must be greater then "Start Date". * * @Constraint( * id = "StartEndDateChecking", * label = @Translation("Start/End Date checking", context = "Validation") * ) */ class StartEndDateCheckingConstraint extends Constraint { public $message = '"End Date" may not be less than "Start Date".'; }
File
[MODULE_NAME]/src/Plugin/Validation/Constraint/StartEndDateCheckingConstraintValidator.php
<?php namespace Drupal\[MODULE_NAME]\Plugin\Validation\Constraint; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Drupal\Core\Datetime\DrupalDateTime; /** * Validates start/end date. */ class StartEndDateCheckingConstraintValidator extends ConstraintValidator { /** * {@inheritdoc} */ public function validate($entity, Constraint $constraint) { $entity = $entity->getEntity(); $start_date = $entity->get('field_start_date')->getString(); $end_date = $entity->get('field_end_date')->getString(); if ($end_date == '') { return; } $tz = drupal_get_user_timezone(); $start_date = new DrupalDateTime($start_date, $tz); $end_date = new DrupalDateTime($end_date, $tz); if ($start_date > $end_date) { $this->context->addViolation($constraint->message); } } }
Comments