friggeri_cv-1.0.0-alpha2/src/Plugin/Field/FieldWidget/ProfileContactBoxDefaultWidget.php

src/Plugin/Field/FieldWidget/ProfileContactBoxDefaultWidget.php
<?php

namespace Drupal\friggeri_cv\Plugin\Field\FieldWidget;

use Drupal\Component\Utility\Html;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\Yaml\Yaml;

/**
 * Defines the 'friggeri_cv_profile_contact_box_default' field widget.
 *
 * @FieldWidget(
 *   id = "friggeri_cv_profile_contact_box_default",
 *   label = @Translation("Profile Contact Box Default"),
 *   field_types = {"friggeri_cv_profile_contact_box"},
 * )
 */
class ProfileContactBoxDefaultWidget extends WidgetBase {

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $item = $items[$delta];
    $value = $item->toArray();

    $element += [
      '#type' => 'details',
      '#open' => FALSE,
    ];

    $element["heading"] = [
      '#type' => "textfield",
      '#default_value' => $value["heading"],
      '#title' => $this->t('Heading'),
    ];

    $field_name = $items->getFieldDefinition()->getName();
    $icon_class = $form_state->getValues()[$field_name][$delta]['font_awesome_icon'] ?? $value["font_awesome_icon"];
    $element["font_awesome_icon"] = [
      '#type' => "select",
      '#options' => $this->getOptions(),
      '#default_value' => $value["font_awesome_icon"],
      '#title' => $this->t("Icon"),
      '#prefix' => '<div id="font-awesome-icon__' . $delta . '" class="fa-icon"><i class="' . $icon_class . '"></i>',
      '#suffix' => '</div>',
      '#attached' => [
        'library' => [
          'friggeri_cv/font-awesome',
          'friggeri_cv/font-awesome.select',
        ],
      ],
      '#attributes' => [
        'class' => ['fa-select'],
      ],
      '#ajax' => [
        'callback' => [$this, 'ajaxFontAwesomeIcon'],
        'event' => 'change',
      ],
    ];

    $element["contacts"] = [
      '#type' => 'text_format',
      '#format' => 'full_html',
      '#title' => $this->t("Contact Details"),
      '#default_value' => $value["contacts"],
    ];

    return $element;
  }

  /**
   * Ajax callback for font_awesome_icon select field.
   *
   * @param array $form
   *   The form structure where widgets are being attached to.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   The selected font awesome icon AjaxResponse.
   */
  public function ajaxFontAwesomeIcon(array &$form, FormStateInterface $form_state) {
    $trigger = $form_state->getTriggeringElement();
    $delta = $trigger['#parents'][1];
    $selector = '#font-awesome-icon__' . $delta . ' > i';
    $class = $trigger['#value'];

    $response = new AjaxResponse();
    $response->addCommand(new ReplaceCommand($selector, '<i class="' . $class . '"></i>'));

    return $response;
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
    foreach ($values as &$value) {
      if (count($value['contacts'])) {
        $value['contacts'] = $value['contacts']['value'];
      }
    }

    return $values;
  }

  /**
   * Get the options of the font_awesome_icon select field.
   *
   * @return array
   *   Select options.
   */
  private function getOptions() {
    // @see https://raw.githubusercontent.com/FortAwesome/Font-Awesome/fa-4/src/icons.yml
    $url = drupal_get_path("module", "friggeri_cv") . "/img/icons/icons.yml";
    $icons = Yaml::parse(file_get_contents($url))["icons"];
    $options = ["" => $this->t("-- Select --")];
    foreach ($icons as $icon) {
      $options["fa fa-" . $icon["id"]] = $icon["name"];
    }

    return $options;
  }

  /**
   * {@inheritdoc}
   */
  protected function formMultipleElements(FieldItemListInterface $items, array &$form, FormStateInterface $form_state) {
    $field_name = $this->fieldDefinition->getName();
    $cardinality = $this->fieldDefinition->getFieldStorageDefinition()->getCardinality();
    $parents = $form['#parents'];

    // Determine the number of widgets to display.
    switch ($cardinality) {
      case FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED:
        $field_state = static::getWidgetState($parents, $field_name, $form_state);
        $max = $field_state['items_count'] - 1;
        $is_multiple = TRUE;
        break;

      default:
        $max = $cardinality - 1;
        $is_multiple = ($cardinality > 1);
        break;
    }

    $title = $this->fieldDefinition->getLabel();
    $description = $this->getFilteredDescription();

    $elements = [];

    for ($delta = 0; $delta <= $max; $delta++) {
      // Add a new empty item if it doesn't exist yet at this delta.
      if (!isset($items[$delta])) {
        $items->appendItem();
      }

      // For multiple fields, title and description are handled by the wrapping
      // table.
      if ($is_multiple) {
        $element = [
          '#title' => $this->t('Contact'),
          '#title_display' => 'invisible',
          '#description' => '',
        ];
      }
      else {
        $element = [
          '#title' => $this->t('Contact'),
          '#title_display' => 'before',
          '#description' => $description,
        ];
      }

      $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);

      if ($element) {
        // Input field for the delta (drag-n-drop reordering).
        if ($is_multiple) {
          // We name the element '_weight' to avoid clashing with elements
          // defined by widget.
          $element['_weight'] = [
            '#type' => 'weight',
            '#title' => $this->t('Weight for row @number', ['@number' => $delta + 1]),
            '#title_display' => 'invisible',
            // Note: this 'delta' is the FAPI #type 'weight' element's property.
            '#delta' => $max,
            '#default_value' => $items[$delta]->_weight ?: $delta,
            '#weight' => 100,
          ];
        }
        if ($items[$delta]->isEmpty()) {
          $element['#open'] = TRUE;
        }

        $elements[$delta] = $element;
      }
    }

    $elements += [
      '#theme' => 'field_multiple_value_form',
      '#field_name' => $field_name,
      '#cardinality' => $cardinality,
      '#cardinality_multiple' => $this->fieldDefinition->getFieldStorageDefinition()->isMultiple(),
      '#required' => $this->fieldDefinition->isRequired(),
      '#title' => $title,
      '#description' => $description,
      '#max_delta' => $max,
    ];

    // Add 'add more' button, if not working with a programmed form.
    if ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && !$form_state->isProgrammed()) {
      $id_prefix = implode('-', array_merge($parents, [$field_name]));
      $wrapper_id = Html::getUniqueId($id_prefix . '-add-more-wrapper');
      $elements['#prefix'] = '<div id="' . $wrapper_id . '">';
      $elements['#suffix'] = '</div>';

      $elements['add_more'] = [
        '#type' => 'submit',
        '#name' => strtr($id_prefix, '-', '_') . '_add_more',
        '#value' => $this->t('Add contact'),
        '#attributes' => ['class' => ['field-add-more-submit']],
        '#limit_validation_errors' => [array_merge($parents, [$field_name])],
        '#submit' => [[static::class, 'addMoreSubmit']],
        '#ajax' => [
          'callback' => [static::class, 'addMoreAjax'],
          'wrapper' => $wrapper_id,
          'effect' => 'fade',
        ],
      ];
    }

    return $elements;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc