Score:1

Disable certain rows of a Entity Reference Source view

in flag

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.

in flag
The more research I am doing, it sounds like possibly a custom field widget would be the way to go.
Score:0
in flag

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

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.