How do I add conditional validation? I have field collection. The problem is that one field is depended on select list.

When I choose type "job" from select list then company field should be required for that collection. Otherwise company field should be completely omitted in validation. 



Update:

I tried to add my own constraint validator but with no effect and I don't have errors on that.

function job_market_user_entity_bundle_field_info_alter(
  &amp;$fields,
  \Drupal\Core\Entity\EntityTypeInterface $entity_type,
  $bundle
) {
  if ($entity_type-&gt;id() == 'field_collection_item') {
    /* @var Drupal\field\Entity\FieldConfig $company_field */
    if ($bundle === 'field_jmu_working_experience') {
      $company_field = $fields['field_jmu_company'];
      if ($company_field) {
        $company_field-&gt;addConstraint('JobTypeConstraint');
      }
    }
  }
}


Constraint

namespace Drupal\job_market_user\Plugin\Validation\Constraint;

use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintBase;
use Drupal\Core\Validation\Annotation\Constraint;
/**
 * @Constraint(
 *   id = "JobTypeConstraint",
 *   label = @Translation("Job Type", context = "Validation"),
 * )
 */
class JobTypeConstraint extends CompositeConstraintBase {

  /**
   * @var string
   */
  public $message = 'Company field is required for Job working experience';

  /**
   * {@inheritdoc}
   */
  public function coversFields() {
    return ['field_jmu_type', 'field_jmu_company'];
  }
}


Validator (I added violation just to check if it's invoked - no effect yet)

namespace Drupal\job_market_user\Plugin\Validation\Constraint;

use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
 *
 * Supports validating company depended on job type
 */
class JobTypeConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {

  /**
   * Validator 2.5 and upwards compatible execution context.
   *
   * @var \Symfony\Component\Validator\Context\ExecutionContextInterface
   */
  protected $context;

  /**
   * {@inheritdoc}
   */
  public function validate($entity, Constraint $constraint) {
    $this-&gt;context-&gt;buildViolation($constraint-&gt;message)
      -&gt;atPath('field_jmu_company')
      -&gt;addViolation();
    return;
  }

  /**
   * Instantiates a new instance of this class.
   *
   * This is a factory method that returns a new instance of this class. The
   * factory should pass any needed dependencies into the constructor of this
   * class, but not the container itself. Every call to this method must return
   * a new instance of this class; that is, it may not implement a singleton.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The service container this instance should use.
   *
   * @return static
   */
  public static function create(ContainerInterface $container) {
    return new static($container-&gt;get('entity_type.manager')-&gt;getStorage('user'));
  }
}
You can use the States API to make a field visually required, visible/hidden and so on.

One simple example from https://randyfay.com/states

  $form['tests_taken'] = array(
    '#type' =&gt; 'checkboxes',
    '#options' =&gt; drupal_map_assoc(array(t('SAT'), t('ACT'))),
    '#title' =&gt; t('What standardized tests did you take?'),
    '#states' =&gt; array(
      'visible' =&gt; array(   // action to take.
        ':input[name=student_type]' =&gt; array('value' =&gt; t('High School')),
      ),
    ),
  );


There are UI modules to configure this, like https://www.drupal.org/project/conditional_fields, but I think none is ported to D8 yet. So you have to form alter it in.

Also, keep in mind that this is UI only. You still need to implement corresponding server-side validation.