1

I have a field that is an entity reference on a piece of content. I created a view that is an Entity Reference Source and set the reference type on the field to that view. When editing the content, I see my list of checkboxes using that Entity Reference Source view.

The data in the list are tournaments. Once a tournament is completed, I do not want the user to be able to uncheck that tournament when editing the content. They can only toggle "upcoming" tournaments.

I have tried doing a form alter, but each option in $form['field_tournament']['widget']['#options'] appears to be a Drupal\Core\Field\FieldFilteredMarkup so I cant actually disable the row since its just HTML markup which only includes the label, not the checkbox.

function MYMODULE_form_group_league_edit_form_alter(&$form, FormStateInterface $form_state) {
  foreach ($form['field_tournaments']['widget']['#options'] as $key => $option) {
    // disable here if the tournament is set to completed.
  }
}

I understand in the view, I can set to only show "upcoming" tournaments, but I want the ability for them to see which ones have been completed while editing.

1
  • The more research I am doing, it sounds like possibly a custom field widget would be the way to go.
    – Ronnie
    Jan 13 at 21:59
0

So I figured it out using a custom widget and the Form Options Attributes module, although now that I think of it I could have probably achieved the same thing in the form alter since I am just loading the term via the key which I had access to before. Anyway, I searched the code base of how the Check boxes/radio widget was built and copied that and modified the code to add a disabled attribute to the option.

<?php

namespace Drupal\pick_dynasty_golf\Plugin\Field\FieldWidget;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldWidget\OptionsButtonsWidget;
use Drupal\Core\Form\FormStateInterface;

/**
 * Defines the 'pick_dynasty_golf_tournament_selection' field widget.
 *
 * @FieldWidget(
 *   id = "pick_dynasty_golf_tournament_selection",
 *   label = @Translation("Tournament Selection"),
 *   field_types = {
 *     "boolean",
 *     "entity_reference",
 *     "list_integer",
 *     "list_float",
 *     "list_string",
 *   },
 *   multiple_values = TRUE
 * )
 */
class TournamentSelectionWidget extends OptionsButtonsWidget {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element = parent::formElement($items, $delta, $element, $form, $form_state);
    // Get all options.
    $options = $this->getOptions($items->getEntity());
    // Get already selected options.
    $selected = $this->getSelectedOptions($items);
    $tids = [];
    // Use the key from the $options to get term IDs (the tournaments).
    foreach ($options as $tid => $option) {
      $tids[] = $tid;
    }
    // Load all the tournaments.
    $term_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
    $terms = $term_storage->loadMultiple($tids);
    $disabled = [];
    // Loop through them and disable any tournament with a status of 'post'
    foreach ($terms as $term) {
      $status = $term->get('field_tournament_status')->value;
      if ($status == 'post') {
        $disabled[$term->id()] = [
          'disabled' => TRUE,
        ];
      }
    }

    $element += [
      '#type' => 'checkboxes',
      '#default_value' => $selected,
      '#options' => $options,
      '#options_attributes' => $disabled, // This is from the Form Options Attributes module.
    ];

    return $element;
  }

}

One BIG issue I did not consider was if the field is disabled (even if previously selected) it does not get submitted so I lose the value. readonly on check boxes is not an option. I basically have to disable it in JS unfortunately and write a custom validator on the backend that checks that no disabled items were added/removed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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