I have three content types. Building, Department and Person. I connect this contents whit entity reference base on Content types. The problem is that I have a lot of persons and a lot of departments and also multiple buildings. How can I limit selection in edit mode, that I can add persons in department only from particular building wher the department is placed? My first try was to add taxonomy term (building A) to person and department placed in building A and then try to filter this in view but without a success because for building B I will need to create new Content type and add different view for same content structure. I could create Content Type "Person building A" and then filter by content type but this does not seems like a good solution.

1 Answer 1


I did something like this recently myself.

Your Person content type should have two entity reference fields, one to a Building, and a second to a Department. A Department also has an entity reference to Building.

Use a hook_form_alter to target the Person form. In that function get a list of the Departments and their Building references, and attach it to the form along with a reference to a custom Javascript library. (Note that you'll have to use the proper machine name for your content types and fields.)

$departments = \Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['type' => 'department']);

$department_data = array_map(function($department){
    return $department->field_ref_building->target_id;
}, $departments);

$form['#attached']['drupalSettings']['dept_bldg_info'] = $department_data;

$form['#attached']['library'][] = 'my_module/my_module.library_name';

The library file will look something like this:

Drupal.behaviors.chartInfoHierarchicalSelect = {
  attach: function (context, settings) {
    // Apply to the HTML page context & the person forms.
    if (context.location || context.id == 'node-person-edit-form'|| context.id == 'node-person-form') {
      let building_inputs = jQuery('[name$="[field_ref_building]"]'),
        department_inputs = jQuery('[name="[field_ref_department]"]');

      building_inputs.each(function () {
        // Ensure initial load has proper limits.
        // Update on change.
        jQuery(this).change(function () {

      function updateDepartments(building_input) {
        var selected_building = building_input.val();

        department_inputs.each(function () {
          var opt_val = jQuery(this).val();
          if (opt_val != '_none' && drupalSettings.dept_bldg_info[opt_val] == selected_building) {
            jQuery(this).prop('disabled', false);
          else {
            jQuery(this).prop('disabled', true);
            jQuery(this).prop('selected', false);

Then when you select a building, you should see the appropriate departments get enabled/disabled.

  • Thank you for your answer. I have a problem passing the argument to contextual filter in edit mode. Can you hint me how can I do that? Feb 19, 2020 at 13:10
  • Sorry, I don't understand your question. Based on the edited question posed, you're mixing apples and oranges. "Contextual filters" is for Views, not editing a piece of content. Are you trying to limit the selections on a node edit form? For example, when you select the building, it limits the selection options for department, and when you select the department, it limits the selection options for person?
    – beltouche
    Feb 19, 2020 at 13:16
  • Maybe I understand your answer wrong. What I want to do is to limit the selections of persons that I can chose from in edit mode. I have like 20 buildings and every building will have like 20 department and every department will have 3 peoples. I first create Buildings then I create department and on the end person. I know that person will work in building A so I want to limit choice of department just for building A. Otherwise I will have like 400 options for choosing. So I added taxonomy term Builing A,B,C... So a could somehow filter choice but maybe this is wrong way to do it. Feb 20, 2020 at 5:31
  • Thank you it worked! Feb 24, 2020 at 7:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.