Created
April 3, 2017 23:32
-
-
Save acbramley/19e7c294a4dc85af217236a903497a91 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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