Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save acbramley/19e7c294a4dc85af217236a903497a91 to your computer and use it in GitHub Desktop.
Save acbramley/19e7c294a4dc85af217236a903497a91 to your computer and use it in GitHub Desktop.
<?php
namespace Drupal\tfnsw_corp_asa_standard\Plugin\Field\FieldWidget;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\Plugin\Field\FieldWidget\EntityReferenceAutocompleteWidget;
use Drupal\Core\Form\FormStateInterface;
/**
* Widget that uses autocomplete.
*
* @FieldWidget(
* id = "entity_reference_field",
* label = @Translation("Autocomplete with field dropdown"),
* description = @Translation("An autocomplete text field with field dropdown."),
* field_types = {
* "entity_reference_field"
* }
* )
*/
class EntityReferenceAutocompleteWithFieldSelect extends EntityReferenceAutocompleteWidget {
const ALLOWED_FIELDS = [
'field_date_released',
'field_date_published',
];
const PARAGRAPH_BUNDLE = 'asa_standard_dates';
const PARAGRAPH_FIELD = 'field_dates';
const AJAX_WRAPPER_ID = 'entity_reference_field';
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$wrapper_id = sprintf('%s-%s-%s', self::AJAX_WRAPPER_ID, $this->fieldDefinition->getName(), $delta);
$element += parent::formElement($items, $delta, $element, $form, $form_state);
$element += [
'#theme_wrappers' => ['container'],
];
$element['#attributes'] = ['class' => ['form--inline', 'clearfix']];
$element['target_id']['#weight'] = 0;
$element['target_id']['#ajax'] = [
'callback' => [get_class($this), 'autocompleteAjax'],
'wrapper' => $wrapper_id,
'progress' => [
'type' => 'throbber',
],
'event' => 'autocompleteclose',
];
$options = [];
// Workaround for now to avoid errors with select options not existing.
foreach (self::ALLOWED_FIELDS as $field) {
$options[$field] = t('Please choose a reference first');
}
$entity_id = NULL;
if ($items[$delta]->target_id) {
$entity_id = $items[$delta]->target_id;
}
elseif ($form_state->getValue($this->fieldDefinition->getName())) {
$entity_id = $form_state->getValue($this->fieldDefinition->getName())[$delta]['target_id'];
}
if ($entity_id) {
$options = array_merge($options, self::getDateOptions($this->getFieldSetting('target_type'), $entity_id));
}
$element['field_name'] = [
'#prefix' => '<div id="' . $wrapper_id . '">',
'#suffix' => '</div>',
'#type' => 'select',
'#title' => t('Field name (value @delta)', ['@delta' => $delta + 1]),
'#title_display' => 'invisible',
'#options' => $options,
'#weight' => 1,
'#default_value' => isset($items[$delta]->field_name) ? $items[$delta]->field_name : '',
];
return $element;
}
/**
* Autocomplete ajax functionality to display the date values of the entity.
*
* @param array $form
* The complete form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return array
* The altered form array.
*/
public function autocompleteAjax(array &$form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
// Go one level up in the form, to the widgets container.
$element = NestedArray::getValue($form, array_slice($triggering_element['#array_parents'], 0, -1));
return $element['field_name'];
}
/**
* Gets an array of date options, keyed by field name.
*
* @param string $entity_type
* The entity type.
* @param int $entity_id
* The entity id.
*
* @return array
* An array of options.
*/
private static function getDateOptions($entity_type, $entity_id) {
$items = [];
$entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity_id);
if (!$entity) {
return $items;
}
/** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */
$date_formatter = \Drupal::service('date.formatter');
$date_entities = $entity->{self::PARAGRAPH_FIELD}->referencedEntities();
$date_entity = reset($date_entities);
$field_name_labels = self::getFieldLabels();
// Render the date values.
foreach ($field_name_labels as $field_name => $label) {
$date = $date_entity->{$field_name}->date;
$options = [
'@label' => $label,
'@value' => $date ? $date_formatter->format($date->format('U'), 'short_date_only') : 'Not set',
];
$items[$field_name] = t('Date @label: @value', $options);
}
return $items;
}
/**
* Return an array keyed by field name with values for the labels in config.
*
* @return array
* The field names and labels.
*/
private static function getFieldLabels() {
/** @var \Drupal\Core\Entity\EntityFieldManagerInterface $field_manager */
$field_manager = \Drupal::service('entity_field.manager');
$fields = $field_manager->getFieldDefinitions('paragraph', self::PARAGRAPH_BUNDLE);
$field_labels = [];
foreach (self::ALLOWED_FIELDS as $field_name) {
if (isset($fields[$field_name])) {
$field_labels[$field_name] = $fields[$field_name]->getLabel();
}
}
return $field_labels;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment