field_collection_table_d8-8.x-1.x-dev/src/Plugin/Field/FieldWidget/FieldCollectionTable.php
src/Plugin/Field/FieldWidget/FieldCollectionTable.php
<?php
/**
* @file
* Contains \Drupal\field_collection_table\Plugin\Field\FieldWidget\FieldCollectionTable.
*/
namespace Drupal\field_collection_table\Plugin\Field\FieldWidget;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Field\WidgetInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Annotation\Plugin;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\Validator\ConstraintViolationInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\Html;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\field_collection\Entity\FieldCollectionItem;
use Drupal\Core\Render\Element;
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
/**
* @FieldWidget(
* id = "field_collection_table",
* label = @Translation("Table"),
* field_types = {"field_collection"}
* )
*/
class FieldCollectionTable extends WidgetBase implements WidgetInterface {
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'nodragging' => FALSE,
'hide_title' => FALSE,
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$element = [];
$element['nodragging'] = [
'#type' => 'checkbox',
'#title' => $this->t('Disable drag and drop'),
'#description' => $this->t('If checked, users cannot rearrange the rows.'),
'#default_value' => $this->getSetting('nodragging'),
'#weight' => 1,
];
$element['hide_title'] = [
'#type' => 'checkbox',
'#title' => $this->t('Hide title'),
'#description' => $this->t('If checked, the field title will be hidden.'),
'#default_value' => $this->getSetting('hide_title'),
'#weight' => 2,
];
return $element;
}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element,
array &$form, FormStateInterface $form_state) {
//building the form using field_collection_embed and not calling the same
//TODO: alter formElement by calling field_collection_embed instead
$field_name = $this->fieldDefinition->getName();
$parents = array_merge($element['#field_parents'], array($field_name, $delta));
$element += [
'#element_validate' => [[static::class, 'validate']],
'#parents' => $parents,
'#field_name' => $field_name,
];
if ($this->fieldDefinition->getFieldStorageDefinition()->getCardinality() == 1) {
$element['#type'] = 'fieldset';
}
$field_state = static::getWidgetState($element['#field_parents'], $field_name, $form_state);
$display = \Drupal::service('entity_display.repository')
->getFormDisplay('field_collection_item', $field_name)
->setComponent($field_name, [
'type' => 'text_textfield',
]);
save();
$display->buildForm($field_collection_item, $element, $form_state);
if (empty($element['#required'])) {
$element['#after_build'][] = [static::class, 'delayRequiredValidation'];
$form['#attributes']['novalidate'] = 'novalidate';
}
if ($this->fieldDefinition->getFieldStorageDefinition()->getCardinality() == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
$options = ['query' => ['element_parents' => implode('/', $element['#parents'])]];
$element['actions'] = [
'#type' => 'actions',
'remove_button' => [
'#delta' => $delta,
'#name' => implode('_', $parents) . '_remove_button',
'#type' => 'submit',
'#value' => t('Remove'),
'#validate' => [],
'#submit' => [[static::class, 'removeSubmit']],
'#limit_validation_errors' => [],
'#ajax' => [
'callback' => [$this, 'ajaxRemove'],
'options' => $options,
'effect' => 'fade',
'wrapper' => $form['#wrapper_id'],
],
'#weight' => 1000,
],
];
}
return $element;
}
/**
* {@inheritdoc}
*/
public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
return $element[$violation->arrayPropertyPath[0]];
}
}
