datafield-1.x-dev/src/Plugin/DataField/FieldWidget/JsonMapWidget.php
src/Plugin/DataField/FieldWidget/JsonMapWidget.php
<?php
namespace Drupal\datafield\Plugin\DataField\FieldWidget;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\datafield\Plugin\DataFieldWidgetInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation of the 'json_textarea' widget.
*/
#[FieldWidget(
id: 'json_map',
label: new TranslatableMarkup('Json map'),
field_types: ['json'],
)]
class JsonMapWidget implements DataFieldWidgetInterface, ContainerFactoryPluginInterface {
use StringTranslationTrait;
/**
* Constructs a EntityReferenceAutocompleteWidget object.
*
* @param string $plugin_id
* The plugin_id for the formatter.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param mixed $field_definition
* The definition of the field to which the formatter is associated.
* @param \Drupal\Core\Render\RendererInterface $renderer
* Renderer service.
*/
public function __construct($plugin_id, $plugin_definition, $field_definition, protected RendererInterface $renderer) {
unset($plugin_id, $plugin_definition, $field_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $configuration, $plugin_id, $plugin_definition) {
return new static(
$plugin_id,
$plugin_definition,
$configuration,
$container->get('renderer'),
);
}
/**
* {@inheritdoc}
*/
public function getFormElement(&$element, $item = NULL, $setting = []) {
$rows = $element["#widget_settings"]['rows'] ?? self::defaultSettings()['rows'];
$cols = $element["#widget_settings"]['cols'] ?? self::defaultSettings()['cols'];
$header = array_fill(0, $cols, $this->t('Value'));
$header[0] = $this->t('Key');
$id = $element["#id"] . '--description';
$container = [
'#type' => 'container',
'#attributes' => [
'class' => [
'json-table-wrapper',
],
],
'btn' => [
'#markup' => Markup::create(
'<button type="button" class="button button-action button--primary btn btn-primary add-row">' . $this->t('Add row') . '</button>
<button type="button" class="button button-action button--primary btn btn-primary add-col">' . $this->t('Add column') . '</button>
<button type="button" class="button button--danger btn btn-danger remove-row">' . $this->t('Remove row') . '</button>
<button type="button" class="button button--danger btn btn-danger remove-col">' . $this->t('Remove column') . '</button>'),
],
'table' => [
'#type' => 'table',
'#header' => $header,
'#attributes' => [
'id' => $id,
'class' => [
'json-table',
],
],
],
];
$valuesRow = $element["#default_value"];
if (empty($valuesRow)) {
$inputRow = Markup::create('<input class="form-control form-text form-element"/>');
$rowDefault = [$inputRow];
if (count($header) > 1) {
foreach (range(1, count($header) - 1) as $col) {
$rowDefault[] = Markup::create('<input class="paste form-control form-text form-element"/>');
}
}
$container['table']['#rows'] = [$rowDefault];
}
else {
$data = json_decode($valuesRow);
foreach ($data as $x => $row) {
array_unshift($row, $x);
foreach ($row as $y => $col) {
$type = is_numeric($col) ? 'number' : 'textfield';
$container['table'][$x][$y] = [
'#type' => $type,
'#title' => '',
'#title_display' => 'invisible',
'#value' => $col,
'#attributes' => [
'class' => ['form-control', 'form-text', 'form-element'],
],
];
}
}
}
$render = $this->renderer->render($container);
$element['#attached']['library'] = ['datafield/json_table'];
$element["#type"] = 'textarea';
$element['#description'] = Markup::create($render);
$element['#attributes'] = [
'data-rows' => $rows,
'data-cols' => $cols,
'data-id' => $element["#id"] . '--description',
'class' => ['json-table', 'js-hide'],
];
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
$options['placeholder'] = t('Please type');
$options['cols'] = 2;
$options['rows'] = 1;
return $options;
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$widget_settings = $form['#settings'];
return [
'cols' => [
'#type' => 'number',
'#title' => $this->t('Columns default'),
'#default_value' => $widget_settings['cols'] ?? self::defaultSettings()['cols'],
'#min' => 1,
'#description' => $this->t('Set 1st column will be key'),
],
'rows' => [
'#type' => 'number',
'#title' => $this->t('Rows default'),
'#default_value' => $widget_settings['rows'] ?? self::defaultSettings()['rows'],
'#min' => 1,
'#description' => $this->t('How many rows high the textarea should be.'),
],
];
}
}
