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