5

I have a taxonomy term reference field in a form. This field has many options and I'm using the term_reference_tree module to display them. I'm trying to add a filter to this form so it only displays certain options depending on some factors (the value of a different field).

The problem is editing this field's options. I can't find a way to programmatically alter a taxonomy term reference field's options when using the term reference tree widget. I've tried using hook_field_widget_properties_ENTITY_TYPE_alter but this doesn't allow me to alter the actual options.

Any suggestions would be very welcome. Thanks in advance.

3
  • I need to do this as well, so I started working on it. I figured out how to use hook_theme_registry_alter to override theme_term_tree_list, but it seems that the function we really need to override is term_reference_tree_process_checkbox_tree. It seems that hook_field_widget_WIDGET_TYPE_form_alter will allow us to do that, but I haven't figured out how yet, and do not have time to continue right now. Commented Jan 18, 2014 at 15:15
  • Er, form_alter is for the settings form, so a different technique is needed. Hopefully someone else will have the solution. Commented Jan 18, 2014 at 16:26
  • hook_field_widget_form_alter is called on the edit page; perhaps $element['theme_hook_suggestions'] might be the key? Commented Jan 18, 2014 at 17:27

2 Answers 2

2

This can be accomplished by modifying the #after_build item of your term_reference_tree field in hook_form_alter:

function MYMODULE_form_alter(&$form, &$form_state) {
  // You might want to do this only for certain forms,
  // or only for forms that have the field to be altered.
  $language = $form['my_taxonomy_field']['#language'];
  $form['my_taxonomy_field'][$language]['#after_build'][] = 'MYMODULE_branch_group_form_element_after_build';
}

function MYMODULE_branch_group_form_element_after_build($form_element, &$form_state) {
  MYMODULE_taxonomy_tree_form_element_alter($form_element[0]);
  return $form_element;
}

function MYMODULE_taxonomy_tree_form_element_alter(&$element) {
  foreach ($element as $tid => $data) {
    if (($tid[0] != '#') && is_numeric($tid)) {
      // MODIFY HERE:  If you do not want to show the term with
      // a specified tid, hide() it here.
      if ($tid == 60) {
        hide($element[$tid]);
      }
      else {
        // OPTIONAL: Alter the way each individual term is rendered.
        // See BONUS ANSWER, below.
        MYMODULE_taxonomy_tree_form_element_term_alter($element[$tid][$tid], $tid);
        // Recursively alter the children of the tree -- the item we
        // want to modify may be nested somewhere inside the tree.
        if (array_key_exists($tid . '-children', $element[$tid])) {
          MYMODULE_taxonomy_tree_form_element_alter($element[$tid][$tid . '-children']);
        }
      }
    }
  }
}

BONUS ANSWER: In addition to filtering out items, I also wished to add a rendered icon with each taxonomy term in the tree. In order to allow the specific fields of the taxonomy vocabulary to be selected and ordered, and the rendering mode (i.e. thumbnail size) of the image field to be selected through the admin user interface, I used the entity_view_mode module to define a new view mode for my taxonomies.

/**
 * Alter the data built by term_reference_tree.widget.inc.
 * @see: _term_reference_tree_build_item()
 */
function MYMODULE_taxonomy_tree_form_element_term_alter(&$element, $tid) {
  $term = taxonomy_term_load($tid);
  // In order for this to work, you will need to install the
  // entity_view_mode module, and make a 'term_with_icon'
  // view mode for your taxonomy vocabulary.
  $term_render_array = taxonomy_term_view($term, 'term_with_icon');
  $element['#title'] = drupal_render($term_render_array);
}
1
  • Thank you for your answers greg_1_anderson! In the end I went with a quick Javascript solution to hide the elements I didn't need - as a quick fix. However you solution looks like it would do the job in a better way.
    – saemchou
    Commented Feb 24, 2014 at 11:13
1

I haven't done this with any of the taxonomy widgets, but the approach I have used is:

  • Clone the widget into my own custom module.
  • Customize the cloned widget
  • Add it as a new widget type via hook_field_widget_info(), setting the 'field types' = array(...) to the type I cloned from.

This should then appear as a new widget. The same approach works for hook_field_formatter_info().

2
  • I considered this, but it seemed like too much code to duplicate to just alter some data. However, seems like this might be a lot easier than figuring out how to make the alter code work! Commented Jan 18, 2014 at 18:33
  • @greg_1_anderson Yeah, it is a little overkill, but at the time I couldn't figure out a better way to handle it (I can't remember exactly what project I did it on, though). If I were tackling this, I think I would try to adapt the entity-reference from a views list widget to use taxonomies instead. That way, you could manage the filtering with a View instead of hardcoding it.
    – mpdonadio
    Commented Jan 18, 2014 at 21:13

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.