View source
<?php
namespace Drupal\map_widget\Plugin\Field\FieldWidget;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
class AssociativeArrayWidget extends WidgetBase {
public static function defaultSettings() {
$settings = parent::defaultSettings();
$settings['size'] = 60;
$settings['key_placeholder'] = '';
$settings['value_placeholder'] = '';
return $settings;
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$elements = [];
$elements['size'] = [
'#type' => 'number',
'#title' => $this
->t('Size of key and value input elements'),
'#default_value' => $this
->getSetting('size'),
'#required' => TRUE,
'#min' => 1,
];
$elements['key_placeholder'] = [
'#type' => 'textfield',
'#title' => $this
->t('Placeholder for the key form field'),
'#default_value' => $this
->getSetting('key_placeholder'),
];
$elements['value_placeholder'] = [
'#type' => 'textfield',
'#title' => $this
->t('Placeholder for the value form field'),
'#default_value' => $this
->getSetting('value_placeholder'),
];
return $elements;
}
public function settingsSummary() {
$summary = [];
$summary[] = $this
->t('Key & value input size: @size', [
'@size' => $this
->getSetting('size'),
]);
if (!empty($this
->getSetting('key_placeholder'))) {
$summary[] = $this
->t('Key placeholder: @placeholder', [
'@placeholder' => $this
->getSetting('key_placeholder'),
]);
}
if (!empty($this
->getSetting('value_placeholder'))) {
$summary[] = $this
->t('Value placeholder: @placeholder', [
'@placeholder' => $this
->getSetting('value_placeholder'),
]);
}
return $summary;
}
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$required = isset($element['#required']) ? $element['#required'] : FALSE;
$field_name = $this->fieldDefinition
->getName();
$element['#field_name'] = $field_name;
$value = $items
->isEmpty() ? [] : $items[$delta]->value;
$count = $this
->initCount($element, $delta, $value, $form_state);
$element['#theme_wrappers'] = [
'form_element',
];
$element['value'] = $this
->valueForm($value, $count, $required);
if (!$form_state
->isProgrammed()) {
$parents = isset($element['#parents']) ? $element['#parents'] : [];
$field_name = $items
->getName();
$id_prefix = implode('-', array_merge($parents, [
$field_name,
], [
$delta,
]));
$wrapper_id = Html::getUniqueId($id_prefix . '-map-assoc-more-wrapper');
$element['#prefix'] = '<div id="' . $wrapper_id . '">';
$element['#suffix'] = '</div>';
$element['add_more'] = [
'#type' => 'submit',
'#name' => strtr($id_prefix, '-', '_') . '_add_more',
'#value' => $this
->t('Add an entry'),
'#attributes' => [
'class' => [
'field-add-more-submit',
],
],
'#limit_validation_errors' => [
array_merge($parents, [
$field_name,
]),
],
'#submit' => [
[
get_class($this),
'addMorePairsSubmit',
],
],
'#ajax' => [
'callback' => [
get_class($this),
'addMorePairsAjax',
],
'wrapper' => $wrapper_id,
'effect' => 'fade',
],
];
}
return $element;
}
protected function valueForm(array $value, $count, $required) {
return [
'#type' => 'map_associative',
'#default_value' => $value,
'#key_placeholder' => $this
->getSetting('key_placeholder'),
'#value_placeholder' => $this
->getSetting('value_placeholder'),
'#size' => $this
->getSetting('size'),
'#count' => $count,
'#required' => $required,
];
}
public static function addMorePairsSubmit(array $form, FormStateInterface $form_state) {
$button = $form_state
->getTriggeringElement();
$element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
$field_name = $element['#field_name'];
$parents = $element['#field_parents'];
$delta = $element['#delta'];
$field_state = static::getWidgetState($parents, $field_name, $form_state);
$field_state['map_assoc_count'][$delta]++;
static::setWidgetState($parents, $field_name, $form_state, $field_state);
$form_state
->setRebuild();
}
public static function addMorePairsAjax(array $form, FormStateInterface $form_state) {
$button = $form_state
->getTriggeringElement();
$element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1));
$element['#prefix'] = '<div class="ajax-new-content">' . (isset($element['#prefix']) ? $element['#prefix'] : '');
$element['#suffix'] = (isset($element['#suffix']) ? $element['#suffix'] : '') . '</div>';
return $element;
}
protected function initCount(array $element, $delta, array $value, FormStateInterface $form_state) {
$field_name = $element['#field_name'];
$parents = $element['#field_parents'];
$field_state = static::getWidgetState($parents, $field_name, $form_state);
if (!isset($field_state['map_assoc_count'])) {
$field_state['map_assoc_count'] = [];
}
if (!isset($field_state['map_assoc_count'][$delta])) {
$count = count($value);
$field_state['map_assoc_count'][$delta] = $count ? $count : 1;
}
static::setWidgetState($parents, $field_name, $form_state, $field_state);
return $field_state['map_assoc_count'][$delta];
}
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
if (isset($values[0]['add_more'])) {
unset($values[0]['add_more']);
}
return $values;
}
}