/**
  * {@inheritdoc}
  */
 public function flagErrors(FieldItemListInterface $items, ConstraintViolationListInterface $violations, array $form, FormStateInterface $form_state)
 {
     // Never flag validation errors for the remove button.
     $clicked_button = end($form_state->getTriggeringElement()['#parents']);
     if ($clicked_button !== 'remove_button') {
         parent::flagErrors($items, $violations, $form, $form_state);
     }
 }
 /**
  * Constructs a new instance.
  *
  * @param string $plugin_id
  *   The plugin_id for the widget.
  * @param mixed[] $plugin_definition
  *   The plugin implementation definition.
  * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
  *   The definition of the field to which the widget is associated.
  * @param mied[] $settings
  *   The widget settings.
  * @param array[] $third_party_settings
  *   Any third party settings.
  * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
  *   The config factory.
  * @param \Drupal\Core\Session\AccountInterface $current_user
  *   The current user.
  * @param \Drupal\payment_reference\PaymentFactoryInterface $payment_factory
  *   The payment reference factory.
  */
 public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, ConfigFactoryInterface $config_factory, AccountInterface $current_user, PaymentFactoryInterface $payment_factory)
 {
     parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
     $this->configFactory = $config_factory;
     $this->currentUser = $current_user;
     $this->paymentFactory = $payment_factory;
 }
Example #3
0
 /**
  * {@inheritdoc}
  */
 public function settingsForm(array $form, FormStateInterface $form_state)
 {
     $elements = parent::settingsForm($form, $form_state);
     $elements['placeholder_isbn_13'] = array('#type' => 'textfield', '#title' => $this->t('Placeholder for ISBN 13'), '#default_value' => $this->getSetting('placeholder_isbn_13'), '#description' => $this->t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'));
     $elements['placeholder_isbn_10'] = array('#type' => 'textfield', '#title' => $this->t('Placeholder for ISBN 10'), '#default_value' => $this->getSetting('placeholder_isbn_10'), '#description' => $this->t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'));
     return $elements;
 }
 /**
  * {@inheritdoc}
  */
 public static function defaultSettings() {
   return [
     'autocomplete_threshold' => 7,
     'autocomplete_size' => 60,
     'autocomplete_placeholder' => '',
   ] + parent::defaultSettings();
 }
 /**
  * {@inheritdoc}
  */
 public function settingsForm(array $form, FormStateInterface $form_state)
 {
     $element = parent::settingsForm($form, $form_state);
     $element['size'] = array('#type' => 'number', '#title' => t('Size'), '#default_value' => $this->getSetting('size'), '#required' => TRUE, '#min' => 20);
     $element['placeholder'] = array('#type' => 'textfield', '#title' => t('Placeholder'), '#default_value' => $this->getSetting('placeholder'));
     return $element;
 }
 /**
  * {@inheritdoc}
  */
 public function settingsForm(array $form, FormStateInterface $form_state)
 {
     $elements = parent::settingsForm($form, $form_state);
     $elements['field'] = array('#type' => 'select', '#weight' => 10, '#title' => $this->t('Field to use'), '#description' => $this->t('Select which field you would like to use.'), '#default_value' => $this->getSetting('field'), '#required' => TRUE, '#options' => $this->getAvailableFields());
     $enabled_plugins = array();
     $i = 0;
     foreach ($this->getSetting('provider_plugins') as $plugin_id => $plugin) {
         if ($plugin['checked']) {
             $plugin['weight'] = intval($i++);
             $enabled_plugins[$plugin_id] = $plugin;
         }
     }
     $elements['geocoder_plugins_title'] = array('#type' => 'item', '#weight' => 15, '#title' => t('Geocoder plugin(s)'), '#description' => t('Select the Geocoder plugins to use, you can reorder them. The first one to return a valid value will be used.'));
     $elements['provider_plugins'] = array('#type' => 'table', '#weight' => 20, '#header' => array(array('data' => $this->t('Enabled')), array('data' => $this->t('Weight')), array('data' => $this->t('Name'))), '#tabledrag' => array(array('action' => 'order', 'relationship' => 'sibling', 'group' => 'provider_plugins-order-weight')));
     $rows = array();
     $count = count($enabled_plugins);
     foreach (Geocoder::getPlugins('Provider') as $plugin_id => $plugin_name) {
         if (isset($enabled_plugins[$plugin_id])) {
             $weight = $enabled_plugins[$plugin_id]['weight'];
         } else {
             $weight = $count++;
         }
         $rows[$plugin_id] = array('#attributes' => array('class' => array('draggable')), '#weight' => $weight, 'checked' => array('#type' => 'checkbox', '#default_value' => isset($enabled_plugins[$plugin_id]) ? 1 : 0), 'weight' => array('#type' => 'weight', '#title' => t('Weight for @title', array('@title' => $plugin_id)), '#title_display' => 'invisible', '#default_value' => $weight, '#attributes' => array('class' => array('provider_plugins-order-weight'))), 'name' => array('#plain_text' => $plugin_name));
     }
     uasort($rows, function ($a, $b) {
         return strcmp($a['#weight'], $b['#weight']);
     });
     foreach ($rows as $plugin_id => $row) {
         $elements['provider_plugins'][$plugin_id] = $row;
     }
     $elements['dumper_plugin'] = array('#type' => 'select', '#weight' => 25, '#title' => 'Output format', '#default_value' => $this->getSetting('dumper_plugin'), '#options' => Geocoder::getPlugins('dumper'), '#description' => t('Set the output format of the value. Ex, for a geofield, the format must be set to WKT.'));
     $elements['delta_handling'] = array('#type' => 'select', '#weight' => 30, '#title' => $this->t('Multi-value input handling'), '#description' => $this->t('Should geometries from multiple inputs be: <ul><li>Matched with each input (e.g. One POINT for each address field)</li><li>Aggregated into a single MULTIPOINT geofield (e.g. One MULTIPOINT polygon from multiple address fields)</li><li>Broken up into multiple geometries (e.g. One MULTIPOINT to multiple POINTs.)</li></ul>'), '#default_value' => $this->getSetting('delta_handling'), '#options' => $this->getDeltaHandling(), '#required' => TRUE);
     return $elements;
 }
Example #7
0
 /**
  * {@inheritdoc}
  */
 public function settingsSummary()
 {
     $summary = parent::settingsSummary();
     $viewMode = ucfirst($this->getSetting('view_mode'));
     $summary[] = t('View mode: @view_mode', array('@view_mode' => $viewMode));
     return $summary;
 }
 /**
  * {@inheritdoc}
  */
 public static function defaultSettings()
 {
     foreach (['first', 'second'] as $subfield) {
         $settings[$subfield] = ['type' => 'textfield', 'prefix' => '', 'suffix' => '', 'size' => 10, 'placeholder' => '', 'label' => t('Ok'), 'cols' => 10, 'rows' => 5];
     }
     $settings['inline'] = FALSE;
     return $settings + parent::defaultSettings();
 }
 /**
  * {@inheritdoc}
  */
 public function form(FieldItemListInterface $items, array &$form, FormStateInterface $form_state, $get_delta = NULL)
 {
     $ret = parent::form($items, $form, $form_state, $get_delta);
     $field_name = $this->fieldDefinition->getName();
     // Add a new wrapper around all the elements for Ajax replacement.
     $ret['#prefix'] = '<div id="' . $field_name . '-ajax-wrapper">';
     $ret['#suffix'] = '</div>';
     return $ret;
 }
    /**
     * {@inheritdoc}
     */
    public static function defaultSettings()
    {
        return array('default_colors' => '
#AC725E,#D06B64,#F83A22,#FA573C,#FF7537,#FFAD46
#42D692,#16A765,#7BD148,#B3DC6C,#FBE983
#92E1C0,#9FE1E7,#9FC6E7,#4986E7,#9A9CFF
#B99AFF,#C2C2C2,#CABDBF,#CCA6AC,#F691B2
#CD74E6,#A47AE2') + parent::defaultSettings();
    }
  /**
   * Constructs a new PriceDefaultWidget object.
   *
   * @param string $pluginId
   *   The plugin_id for the widget.
   * @param mixed $pluginDefinition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Field\FieldDefinitionInterface $fieldDefinition
   *   The definition of the field to which the widget is associated.
   * @param array $settings
   *   The widget settings.
   * @param array $thirdPartySettings
   *   Any third party settings.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\commerce_price\NumberFormatterFactoryInterface $numberFormatterFactory
   *   The number formatter factory.
   */
  public function __construct($pluginId, $pluginDefinition, FieldDefinitionInterface $fieldDefinition, array $settings, array $thirdPartySettings, EntityTypeManagerInterface $entityTypeManager, NumberFormatterFactoryInterface $numberFormatterFactory) {
    parent::__construct($pluginId, $pluginDefinition, $fieldDefinition, $settings, $thirdPartySettings);

    $this->currencyStorage = $entityTypeManager->getStorage('commerce_currency');
    $this->numberFormatter = $numberFormatterFactory->createInstance(NumberFormatterInterface::DECIMAL);
    $this->numberFormatter->setMinimumFractionDigits(0);
    $this->numberFormatter->setMaximumFractionDigits(6);
    $this->numberFormatter->setGroupingUsed(FALSE);
  }
Example #12
0
 /**
  * @inheritdoc
  *
  * N.B. massageFormValues and $element['#element_validate'] do comparable things.
  */
 public function massageFormValues(array $values, array $form, FormStateInterface $form_state)
 {
     $values = parent::massageFormValues($values, $form, $form_state);
     // Convert the values to real languagecodes,
     // but ONLY on Entity form, NOT in the 'field settings - default value'.
     if (isset($form_state->getBuildInfo()['form_id']) && $form_state->getBuildInfo()['form_id'] !== 'field_config_edit_form') {
         foreach ($values as &$value) {
             $value['value'] = LanguageItem::_getLanguageConfigurationValues($value['value']);
         }
     }
     return $values;
 }
 /**
  * {@inheritdoc}
  */
 public function settingsForm(array $form, FormStateInterface $form_state)
 {
     $elements = parent::settingsForm($form, $form_state);
     $entityFieldDefinitions = \Drupal::entityManager()->getFieldDefinitions($this->fieldDefinition->entity_type, $this->fieldDefinition->bundle);
     $options = array();
     foreach ($entityFieldDefinitions as $id => $definition) {
         if ($definition->getType() == 'geofield') {
             $options[$id] = $definition->getLabel();
         }
     }
     $elements['destination_field'] = array('#type' => 'select', '#title' => $this->t('Destination Geo Field'), '#default_value' => $this->getSetting('destination_field'), '#required' => TRUE, '#options' => $options);
     $elements['placeholder'] = array('#type' => 'textfield', '#title' => t('Placeholder'), '#default_value' => $this->getSetting('placeholder'), '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'));
     return $elements;
 }
Example #14
0
 /**
  * {@inheritdoc}
  */
 public function onDependencyRemoval(array $dependencies)
 {
     $changed = parent::onDependencyRemoval($dependencies);
     // Only the setting 'role' is resolved here. When the dependency related to
     // this setting is removed, is expected that the widget component will be
     // update accordingly in the display entity. The 'role2' setting is
     // deliberately left out from being updated. When the dependency
     // corresponding to this setting is removed, is expected that the widget
     // component will be disabled in the display entity.
     if (!empty($role_id = $this->getSetting('role'))) {
         if (!empty($dependencies['config']["user.role.{$role_id}"])) {
             $this->setSetting('role', 'anonymous');
             $changed = TRUE;
         }
     }
     return $changed;
 }
 /**
  * {@inheritdoc}
  */
 public function massageFormValues(array $values, array $form, FormStateInterface $form_state)
 {
     $values = parent::massageFormValues($values, $form, $form_state);
     // It is likely that the url provided for this field is not existing and
     // so the logic in the parent method did not set any defaults. Just run
     // through all url values and add defaults.
     foreach ($values as &$value) {
         if (!empty($value['path'])) {
             // In case we have query process the url.
             if (strpos($value['path'], '?') !== FALSE) {
                 $url = UrlHelper::parse($value['path']);
                 $value['path'] = $url['path'];
                 $value['query'] = $url['query'];
             }
         }
     }
     return $values;
 }
Example #16
0
 /**
  * {@inheritdoc}
  */
 public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings)
 {
     parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
     $property_names = $this->fieldDefinition->getFieldStorageDefinition()->getPropertyNames();
     $this->column = $property_names[0];
 }
Example #17
0
  /**
   * Cleans up the form state for a submitted entity form.
   *
   * After field_attach_submit() has run and the form has been closed, the form
   * state still contains field data in $form_state->get('field'). Unless that
   * data is removed, the next form with the same #parents (reopened add form,
   * for example) will contain data (i.e. uploaded files) from the previous form.
   *
   * @param $entity_form
   *   The entity form.
   * @param $form_state
   *   The form state of the parent form.
   */
  public static function submitCleanFormState(&$entity_form, FormStateInterface $form_state) {
    $info = \Drupal::entityTypeManager()->getDefinition($entity_form['#entity_type']);
    if (!$info->get('field_ui_base_route')) {
      // The entity type is not fieldable, nothing to cleanup.
      return;
    }

    $bundle = $entity_form['#entity']->bundle();
    $instances = \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_form['#entity_type'], $bundle);
    foreach ($instances as $instance) {
      $field_name = $instance->getName();
      if (!empty($entity_form[$field_name]['#parents'])) {
        $parents = $entity_form[$field_name]['#parents'];
        array_pop($parents);
        if (!empty($parents)) {
          $field_state = array();
          WidgetBase::setWidgetState($parents, $field_name, $form_state, $field_state);
        }
      }
    }
  }
Example #18
0
 /**
  * {@inheritdoc}
  *
  * Override the '%uri' message parameter, to ensure that 'internal:' URIs
  * show a validation error message that doesn't mention that scheme.
  */
 public function flagErrors(FieldItemListInterface $items, ConstraintViolationListInterface $violations, array $form, FormStateInterface $form_state)
 {
     /** @var \Symfony\Component\Validator\ConstraintViolationInterface $violation */
     foreach ($violations as $offset => $violation) {
         $parameters = $violation->getParameters();
         if (isset($parameters['@uri'])) {
             $parameters['@uri'] = static::getUriAsDisplayableString($parameters['@uri']);
             $violations->set($offset, new ConstraintViolation($this->t($violation->getMessageTemplate(), $parameters), $violation->getMessageTemplate(), $parameters, $violation->getRoot(), $violation->getPropertyPath(), $violation->getInvalidValue(), $violation->getPlural(), $violation->getCode()));
         }
     }
     parent::flagErrors($items, $violations, $form, $form_state);
 }
 /**
  * {@inheritdoc}
  */
 public static function defaultSettings()
 {
     return array() + parent::defaultSettings();
 }
Example #20
0
 /**
  * {@inheritdoc}
  */
 public static function defaultSettings()
 {
     return array('display_label' => FALSE) + parent::defaultSettings();
 }
 /**
  * {@inheritdoc}
  */
 public function extractFormValues(FieldItemListInterface $items, array $form, FormStateInterface $form_state)
 {
     if ($this->isDefaultValueWidget($form_state)) {
         $items->filterEmptyItems();
         return;
     }
     $field_name = $this->fieldDefinition->getName();
     $path = array_merge($form['#parents'], array($field_name));
     $submitted_values = $form_state->getValue($path);
     $values = [];
     foreach ($items as $delta => $value) {
         $this->setIefId(sha1($items->getName() . '-ief-single-' . $delta));
         /** @var \Drupal\Core\Entity\EntityInterface $entity */
         if (!($entity = $form_state->get(['inline_entity_form', $this->getIefId(), 'entity']))) {
             return;
         }
         $values[$submitted_values[$delta]['_weight']] = ['entity' => $entity];
     }
     // Sort items base on weights.
     ksort($values);
     $values = array_values($values);
     // Let the widget massage the submitted values.
     $values = $this->massageFormValues($values, $form, $form_state);
     // Assign the values and remove the empty ones.
     $items->setValue($values);
     $items->filterEmptyItems();
     // Put delta mapping in $form_state, so that flagErrors() can use it.
     $field_name = $this->fieldDefinition->getName();
     $field_state = WidgetBase::getWidgetState($form['#parents'], $field_name, $form_state);
     foreach ($items as $delta => $item) {
         $field_state['original_deltas'][$delta] = isset($item->_original_delta) ? $item->_original_delta : $delta;
         unset($item->_original_delta, $item->_weight);
     }
     WidgetBase::setWidgetState($form['#parents'], $field_name, $form_state, $field_state);
 }
 /**
  * {@inheritdoc}
  */
 public static function defaultSettings()
 {
     return array('match_operator' => 'CONTAINS', 'size' => '60', 'placeholder' => '') + parent::defaultSettings();
 }
 /**
  * {@inheritdoc}
  *
  * @DCG: Optional.
  */
 public static function defaultSettings()
 {
     return ['size' => 60, 'placeholder' => '', 'prefix' => '', 'suffix' => ''] + parent::defaultSettings();
 }
 /**
  * {@inheritdoc}
  */
 public function settingsForm(array $form, FormStateInterface $form_state)
 {
     $elements = parent::settingsForm($form, $form_state);
     $elements['html5_geolocation'] = array('#type' => 'checkbox', '#title' => 'Use HTML5 Geolocation to set default values', '#default_value' => $this->getSetting('html5_geolocation'));
     return $elements;
 }
Example #25
0
 /**
  * {@inheritdoc}
  */
 public function settingsForm(array $form, FormStateInterface $form_state)
 {
     $element = parent::settingsForm($form, $form_state);
     $browsers = [];
     /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */
     foreach ($this->entityManager->getStorage('entity_browser')->loadMultiple() as $browser) {
         $browsers[$browser->id()] = $browser->label();
     }
     $element['entity_browser'] = ['#title' => t('Entity browser'), '#type' => 'select', '#default_value' => $this->getSetting('entity_browser'), '#options' => $browsers];
     $target_type = $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type');
     $entity_type = \Drupal::entityTypeManager()->getStorage($target_type)->getEntityType();
     $displays = [];
     foreach ($this->fieldDisplayManager->getDefinitions() as $id => $definition) {
         if ($this->fieldDisplayManager->createInstance($id)->isApplicable($entity_type)) {
             $displays[$id] = $definition['label'];
         }
     }
     $id = Html::getUniqueId('field-' . $this->fieldDefinition->getName() . '-display-settings-wrapper');
     $element['field_widget_display'] = ['#title' => t('Entity display plugin'), '#type' => 'select', '#default_value' => $this->getSetting('field_widget_display'), '#options' => $displays, '#ajax' => ['callback' => array($this, 'updateSettingsAjax'), 'wrapper' => $id]];
     $element['field_widget_edit'] = ['#title' => t('Display Edit button'), '#type' => 'checkbox', '#default_value' => $this->getSetting('field_widget_edit')];
     $element['field_widget_remove'] = ['#title' => t('Display Remove button'), '#type' => 'checkbox', '#default_value' => $this->getSetting('field_widget_remove')];
     $element['open'] = ['#title' => t('Show widget details as open by default'), '#type' => 'checkbox', '#default_value' => $this->getSetting('open')];
     $element['field_widget_display_settings'] = ['#type' => 'fieldset', '#title' => t('Entity display plugin configuration'), '#tree' => TRUE, '#prefix' => '<div id="' . $id . '">', '#suffix' => '</div>'];
     if ($this->getSetting('field_widget_display')) {
         $element['field_widget_display_settings'] += $this->fieldDisplayManager->createInstance($form_state->getValue(['fields', $this->fieldDefinition->getName(), 'settings_edit_form', 'settings', 'field_widget_display'], $this->getSetting('field_widget_display')), $form_state->getValue(['fields', $this->fieldDefinition->getName(), 'settings_edit_form', 'settings', 'field_widget_display_settings'], $this->getSetting('field_widget_display_settings')) + ['entity_type' => $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type')])->settingsForm($form, $form_state);
     }
     return $element;
 }
 /**
  * {@inheritdoc}
  */
 protected function formMultipleElements(FieldItemListInterface $items, array &$form, FormStateInterface $form_state)
 {
     // Adjust wrapper identifiers as they are shared between parents and
     // children in nested field collections.
     $form['#wrapper_id'] = Html::getUniqueID($items->getName());
     $elements = parent::formMultipleElements($items, $form, $form_state);
     $elements['#prefix'] = '<div id="' . $form['#wrapper_id'] . '">';
     $elements['#suffix'] = '</div>';
     $elements['add_more']['#ajax']['wrapper'] = $form['#wrapper_id'];
     return $elements;
 }
 /**
  * {@inheritdoc}
  */
 public static function defaultSettings()
 {
     return array('placeholder' => '') + parent::defaultSettings();
 }
Example #28
0
 /**
  * {@inheritdoc}
  */
 public function settingsForm(array $form, array &$form_state)
 {
     $elements = parent::settingsForm($form, $form_state);
     $elements['placeholder_url'] = array('#type' => 'textfield', '#title' => $this->t('Placeholder for URL'), '#default_value' => $this->getSetting('placeholder_url'), '#description' => $this->t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'));
     $elements['placeholder_title'] = array('#type' => 'textfield', '#title' => $this->t('Placeholder for link text'), '#default_value' => $this->getSetting('placeholder_title'), '#description' => $this->t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'), '#states' => array('invisible' => array(':input[name="instance[settings][title]"]' => array('value' => DRUPAL_DISABLED))));
     return $elements;
 }
 /**
  * {@inheritdoc}
  */
 public static function defaultSettings()
 {
     return array('test_widget_setting_multiple' => 'dummy test string') + parent::defaultSettings();
 }
 /**
  * {@inheritdoc}
  */
 public function extractFormValues(FieldItemListInterface $items, array $form, FormStateInterface $form_state)
 {
     if ($this->isDefaultValueWidget($form_state)) {
         $items->filterEmptyItems();
         return;
     }
     if (!$this->isSubmitRelevant($form, $form_state)) {
         return;
     }
     $field_name = $this->fieldDefinition->getName();
     // Extract the values from $form_state->getValues().
     $parents = array_merge($form['#parents'], [$field_name, 'form']);
     $ief_id = sha1(implode('-', $parents));
     $this->setIefId($ief_id);
     $inline_entity_form_state = $form_state->get('inline_entity_form');
     if (isset($inline_entity_form_state[$this->getIefId()])) {
         $values = $inline_entity_form_state[$this->getIefId()];
         $key_exists = TRUE;
     } else {
         $values = [];
         $key_exists = FALSE;
     }
     if ($key_exists) {
         $values = $values['entities'];
         // Account for drag-and-drop reordering if needed.
         if (!$this->handlesMultipleValues()) {
             // Remove the 'value' of the 'add more' button.
             unset($values['add_more']);
             // The original delta, before drag-and-drop reordering, is needed to
             // route errors to the corect form element.
             foreach ($values as $delta => &$value) {
                 $value['_original_delta'] = $delta;
             }
             usort($values, function ($a, $b) {
                 return SortArray::sortByKeyInt($a, $b, '_weight');
             });
         }
         foreach ($values as $delta => &$item) {
             /** @var \Drupal\Core\Entity\EntityInterface $entity */
             $entity = $item['entity'];
             if (!empty($item['needs_save'])) {
                 $entity->save();
             }
             if (!empty($item['delete'])) {
                 $entity->delete();
                 unset($items[$delta]);
             }
         }
         // Let the widget massage the submitted values.
         $values = $this->massageFormValues($values, $form, $form_state);
         // Assign the values and remove the empty ones.
         $items->setValue($values);
         $items->filterEmptyItems();
         // Put delta mapping in $form_state, so that flagErrors() can use it.
         $field_state = WidgetBase::getWidgetState($form['#parents'], $field_name, $form_state);
         foreach ($items as $delta => $item) {
             $field_state['original_deltas'][$delta] = isset($item->_original_delta) ? $item->_original_delta : $delta;
             unset($item->_original_delta, $item->_weight);
         }
         WidgetBase::setWidgetState($form['#parents'], $field_name, $form_state, $field_state);
     }
 }