Developer documentation

Last updated on
6 April 2021

Useful terms and a walkthrough of how the Conditional Fields module operates.

Terms

dependency
A relationship between exactly two fields: a dependent field, and a dependee field; plus some settings for that relationship.
dependee
A field that affects another.
The "controlling", "parent", or "triggering" field in a dependency.
dependent
A field that is affected by another.
The "target", or "child" field in a dependency.
Form API #states
Form API's states component
A part of Drupal's Form API, which contains a back-end (i.e.: PHP) and front-end (i.e.: JavaScript) component.
The Conditional fields module provides a UI for the Form API's states component on Entity forms; it also adds some functionality not present in the core Form API's states component.
The Form API's state component should not be confused with Drupal 8's State API, which stores configuration data that should not be migrated between sites.
JS effect
jQuery effect
special effect
A jQuery animation technique.

Walkthrough of how this module operates

  1. hook_element_info_alter() alters all form and render elements, instructing the Render API to call conditional_fields_element_after_build() after each one of them is built.
  2. conditional_fields_element_after_build() runs on the element. If the element has a title, parents, and is part of an entity form, then it loads an array of information about fields that depend on the current element using conditional_fields_load_dependencies(). If it finds any, it calls conditional_fields_attach_dependency() on each one of them.
    1. conditional_fields_load_dependencies() returns an array of entity types containing an array of bundles containing an associative array that consists of:
      • dependees: an array of field names that control another field, which contain an array of dependency UUIDs, containing an associative array that consists of:
        • dependent: the name of the field that is controlled by this one, and,
        • options: settings for this dependency.
      • dependents: an array of field names that are controlled by another field, which contain an array of dependency UUIDs, containing an associative array that consists of:
        • dependee: the name of the field that controls this one, and,
        • options: settings for this dependency.
  3. conditional_fields_attach_dependency() calculates parents and adds a #conditional_fields property to the root form element. This property contains information about the dependencies seen from the perspective of the dependees. It uses _conditional_fields_element_add_property() to add the callback conditional_fields_form_after_build to the form, to be run after it has been built.
  4. The conditional_fields_form_after_build() callback (in conditional_fields.api.inc) loops through the dependencies in the #conditional_fields property in the root form element. For each dependency:
    1. For each dependency, it looks at the dependee (controlling field), and:
      1. Stores the dependee's jQuery selector with conditional_fields_get_selector()
      2. Gets a list of states with conditional_fields_get_state():
        1. Matching state objects are loaded with the plugin.manager.conditional_fields_handlers service, and ConditionalFieldsHandlersPluginInterface::statesHandler() is called on them.
    2. If that dependency can be evaluated on the server-side, it calls _conditional_fields_element_add_property() to add conditional_fields_dependent_validate() as an #element_validate callback on the dependee (controlling) field.
    3. It calls conditional_fields_add_state_to_group() to set the Form API #states array for the elements in that dependency.
    4. If a JS effect is specified, its specification and settings are compiled so they can be added to the drupalSettings attached to the form at the end of conditional_fields_form_after_build().
    5. If any states have complex conditions (i.e.: conjuncted with "AND", "OR", or "XOR"), then those are added to the elements' #states array.
    6. The conditional fields library is added to the page, effect settings are attached to the form, the validation callback conditional_fields_form_validate() is added to the root form element, and validation is set to occur any time the form is rendered to avoid stale data after a failed submission.
  5. The page gets delivered to the browser; jquery, ckeditor, and the drupal.states libraries are loaded
  6. The js/conditional_fields.js file runs:
    1. A fix ensures that Form API #states work for multi-select fields.
    2. A fix ensures that Form API #states work for auto-complete field selections.
    3. The file registers event handlers for a number of new #states events defined by the conditional_fields module to support JS effects.
    4. In the attach Drupal behavior for the conditional fields module, the new state change behaviors are triggered when #states events have JS effects.
    5. A fix ensures that CKEditor textareas trigger update state events.
    6. A fix ensures that autocomplete selections trigger keyup state events.
    7. A fix ensures that regexes can be used in #states event specifications.
  7. The form is submitted.
  8. conditional_fields_dependent_validate() is called-back for each dependee (controlling) field:
    1. It checks if any of its dependencies were triggered. If so:
      1. It checks the 'visible' state.
      2. It checks the 'required' state; and if a required dependent field was not filled in, it throws a form error.
      3. If any form errors were generated, then, it:
        1. Marks submitted values for removal.
        2. If the dependency options state that the field should be reset to its default values, it resets them
        3. Removes any other validation errors for the current field.
        4. Keeps track of the untriggered dependents in the conditional_fields_untriggered_dependents form state value.
  9. conditional_fields_form_validate() is called-back. If it finds any untriggered dependents in the conditional_fields_untriggered_dependents form state value, it:
    1. Loops through the untriggered dependents. For each one, it:
      1. Tries to find the erroneous values with conditional_fields_form_field_get_values()
      2. Outputs the untriggered dependent errors into the form state so they can be displayed
    2. Filters out errors for dependent fields that would be invisible / invalid based on the current state of the dependee fields.

For more information about working with Conditional Fields as a developer, please see:

Help improve this page

Page status: No known problems

You can: