ultimate_table_field-1.0.0-alpha5/src/Form/ModalForm.php
src/Form/ModalForm.php
<?php
namespace Drupal\ultimate_table_field\Form;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseDialogCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Modal form.
*/
class ModalForm extends FormBase {
/**
* Item data form ajax wrapper.
*/
const ITEM_DATA_FORM_AJAX_WRAPPER = 'table-item-data-form';
/**
* Modal form wrapper css ID.
*/
const MODAL_FORM_WRAPPER_CSS_ID = '#ultimate-table-data-dialog-wrapper';
/**
* Current cell items data.
*
* @var array
*/
protected $itemsData;
/**
* Row index.
*
* @var null|string|numeric
*/
protected $rowIndex;
/**
* Operation type.
*
* @var null|string
*/
protected $operation;
/**
* Column index.
*
* @var null|string|numeric
*/
protected $columnIndex;
/**
* Cell item index.
*
* @var null|string|numeric
*/
protected $cellItemIndex;
/**
* Request stack service.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* Ajax wrapper id.
*
* @var string
*/
protected $id;
/**
* Ultimate table cell field manager plugin.
*
* @var \Drupal\ultimate_table_field\UltimateTableCellFieldManager
*/
protected $ultimateTableCellFieldManager;
/**
* {@inheritDoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->requestStack = $container->get('request_stack');
$instance->ultimateTableCellFieldManager = $container->get('plugin.manager.ultimate_table_cell_field');
return $instance;
}
/**
* {@inheritDoc}
*/
public function getFormId() {
return 'ultimate_table_modal_form';
}
/**
* {@inheritDoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$request = $this->requestStack->getCurrentRequest();
$items_data = $request->query->get('items_data');
/** @var array $allowed_types */
$allowed_types = Json::decode($request->query->get('allowed_types') ?? '[]');
$this->itemsData = [];
if ($items_data) {
$this->itemsData = Json::decode($items_data);
}
$this->operation = $request->query->get('op') ?? '';
$this->rowIndex = $request->query->get('row_index') ?? '';
$this->columnIndex = $request->query->get('column_index') ?? '';
$this->cellItemIndex = $request->query->get('item_index') ?? '';
$this->id = $request->query->get('wrapper_id') ?? '';
$values = $this->operation !== 'add' ? $this->itemsData[$this->cellItemIndex] : [];
$storage = $form_state->getStorage();
$plugin_id = $storage['plugin_id'] ?? NULL;
$plugin_id = empty($plugin_id) && isset($values['type']) ? $values['type'] : $plugin_id;
$form['#prefix'] = '<div id="' . self::ITEM_DATA_FORM_AJAX_WRAPPER . '">';
$form['#suffix'] = '</div>';
$options = [];
$form['update'] = [
'#type' => 'submit',
'#value' => $this->t('Update'),
'#name' => 'update_modal',
'#attributes' => [
'class' => [
'use-ajax',
'js-hide',
],
],
'#ajax' => [
'wrapper' => self::ITEM_DATA_FORM_AJAX_WRAPPER,
'callback' => [$this, 'updateModalForm'],
'event' => 'click',
],
];
$form['data_type'] = [
'#type' => 'select',
'#title' => $this->t('Type'),
'#empty_option' => $this->t('- Select -'),
'#required' => TRUE,
'#default_value' => $values['type'] ?? '',
'#ajax' => [
'wrapper' => self::ITEM_DATA_FORM_AJAX_WRAPPER,
'callback' => [$this, 'triggerUpdateClick'],
],
];
if (!empty($plugin_id)) {
$table_cell_field = $this->ultimateTableCellFieldManager->createInstance($plugin_id);
$form[$plugin_id] = $table_cell_field->buildCellField($values[$plugin_id] ?? NULL);
}
$definitions = $this->ultimateTableCellFieldManager->getDefinitions();
foreach ($definitions as $definition) {
if (method_exists($definition['class'], 'buildCellField')) {
if (empty($allowed_types) || in_array($definition['id'], $allowed_types)) {
$options[$definition['id']] = $definition['label'] ?? $definition['id'];
}
}
}
$form['data_type']['#options'] = $options;
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Save'),
'#button_type' => 'primary',
'#attributes' => [
'class' => [
'use-ajax',
],
],
'#ajax' => [
'callback' => [$this, 'submitModalFormAjax'],
'event' => 'click',
],
];
return $form;
}
/**
* {@inheritDoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$triggering_element = $form_state->getTriggeringElement();
$name = $triggering_element['#name'] ?? NULL;
$errors = $form_state->getErrors();
if ($name === 'update_modal' && !empty($errors)) {
$form_state->clearErrors();
$errors = array_intersect_key($errors, array_flip(['data_type']));
foreach ($errors as $key => $message) {
$form_state->setErrorByName($key, $message);
}
}
}
/**
* {@inheritDoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$triggering_element = $form_state->getTriggeringElement();
if ($triggering_element['#name'] === 'update_modal') {
$storage = $form_state->getStorage();
$storage['plugin_id'] = $form_state->getValue('data_type');
$form_state->setStorage($storage);
$form_state->setRebuild();
}
}
/**
* Update modal form callback.
*/
public function updateModalForm(array $form, FormStateInterface $form_state) {
$form['#prefix'] = '<div id="' . self::ITEM_DATA_FORM_AJAX_WRAPPER . '">';
$form['#suffix'] = '</div>';
return $form;
}
/**
* Trigger update submit click.
*/
public function triggerUpdateClick(array $form, FormStateInterface $form_state) {
$response = new AjaxResponse();
$response->addCommand(new InvokeCommand('input[name="update_modal"]', 'trigger', ['click']));
return $response;
}
/**
* Modal form ajax submit callback.
*/
public function submitModalFormAjax(array $form, FormStateInterface $form_state) {
if ($form_state->hasAnyErrors()) {
return (new AjaxResponse())->addCommand(new ReplaceCommand('#' . self::ITEM_DATA_FORM_AJAX_WRAPPER, $form));
}
$values = $form_state->getValues();
$type = $values['data_type'];
$value = $values[$type];
$ut_cell_field_plugin = $this->ultimateTableCellFieldManager->createInstance($type);
$ut_cell_field_plugin->cellFieldAlterSubmitted($value);
$data = [
'type' => $type,
];
$data[$type] = $value;
if ($this->operation === 'add') {
$this->itemsData[] = $data;
}
else {
$this->itemsData[$this->cellItemIndex] = $data;
}
$data_input_selector = '#data-input-' . $this->rowIndex . '-' . $this->columnIndex . '--' . $this->id;
$id = str_replace('-', '_', $this->id);
$update_button_selector = 'input[name="update_table::' . $id . '"]';
// Pass the selection to the field widget based on the current widget ID.
$response = new AjaxResponse();
$response->addCommand(new InvokeCommand($data_input_selector, 'val', [Json::encode($this->itemsData)]))
->addCommand(new CloseDialogCommand(self::MODAL_FORM_WRAPPER_CSS_ID, FALSE))
->addCommand(new InvokeCommand($update_button_selector, 'trigger', ['mousedown']));
return $response;
}
}
