You are here

public function SlickForm::form in Slick Carousel 8.2

Same name and namespace in other branches
  1. 8 slick_ui/src/Form/SlickForm.php \Drupal\slick_ui\Form\SlickForm::form()

Gets the actual form array to be built.

Overrides SlickFormBase::form

See also

\Drupal\Core\Entity\EntityForm::processForm()

\Drupal\Core\Entity\EntityForm::afterBuild()

File

slick_ui/src/Form/SlickForm.php, line 18

Class

SlickForm
Extends base form for slick instance configuration form.

Namespace

Drupal\slick_ui\Form

Code

public function form(array $form, FormStateInterface $form_state) {
  $form = parent::form($form, $form_state);
  $path = drupal_get_path('module', 'slick');
  $slick = $this->entity;
  $options = $slick
    ->getOptions() ?: [];
  $tooltip = [
    'class' => [
      'is-tooltip',
    ],
  ];
  $route = [
    'name' => 'slick_ui',
  ];
  $is_help = $this
    ->manager()
    ->getModuleHandler()
    ->moduleExists('help');
  $readme = $is_help ? Url::fromRoute('help.page', $route)
    ->toString() : Url::fromUri('base:' . $path . '/docs/README.md')
    ->toString();
  $admin_css = $this->manager
    ->configLoad('admin_css', 'blazy.settings');
  $form['label'] = [
    '#type' => 'textfield',
    '#title' => $this
      ->t('Label'),
    '#default_value' => $slick
      ->label(),
    '#maxlength' => 255,
    '#required' => TRUE,
    '#description' => $this
      ->t("Label for the Slick optionset."),
    '#attributes' => $tooltip,
    '#prefix' => '<div class="form__header form__half form__half--first has-tooltip clearfix">',
  ];

  // Keep the legacy CTools ID, i.e.: name as ID.
  $form['name'] = [
    '#type' => 'machine_name',
    '#default_value' => $slick
      ->id(),
    '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH,
    '#machine_name' => [
      'source' => [
        'label',
      ],
      'exists' => '\\Drupal\\slick\\Entity\\Slick::load',
    ],
    '#attributes' => $tooltip,
    '#disabled' => !$slick
      ->isNew(),
    '#suffix' => '</div>',
  ];
  $form['skin'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Skin'),
    '#options' => $this->admin
      ->getSkinsByGroupOptions(),
    '#empty_option' => $this
      ->t('- None -'),
    '#default_value' => $slick
      ->getSkin(),
    '#description' => $this
      ->t('Skins allow swappable layouts like next/prev links, split image and caption, etc. However a combination of skins and options may lead to unpredictable layouts, get yourself dirty. See main <a href="@url">README</a> for details on Skins. Only useful for custom work, and ignored/overridden by slick formatters or sub-modules. If you are using Slick Lightbox, this is the only option to change its skin at the Slick Lightbox optionset.', [
      '@url' => $readme,
    ]),
    '#attributes' => $tooltip,
    '#prefix' => '<div class="form__header form__half form__half--last has-tooltip clearfix">',
  ];
  $form['group'] = [
    '#type' => 'select',
    '#title' => $this
      ->t('Group'),
    '#options' => [
      'main' => $this
        ->t('Main'),
      'overlay' => $this
        ->t('Overlay'),
      'thumbnail' => $this
        ->t('Thumbnail'),
    ],
    '#empty_option' => $this
      ->t('- None -'),
    '#default_value' => $slick
      ->getGroup(),
    '#description' => $this
      ->t('Group this optionset to avoid confusion for optionset selections. Leave empty to make it available for all.'),
    '#attributes' => $tooltip,
  ];
  $form['breakpoints'] = [
    '#title' => $this
      ->t('Breakpoints'),
    '#type' => 'textfield',
    '#default_value' => $form_state
      ->hasValue('breakpoints') ? $form_state
      ->getValue('breakpoints') : $slick
      ->getBreakpoints(),
    '#description' => $this
      ->t('The number of breakpoints added to Responsive display, max 9. This is not Breakpoint Width (480px, etc).'),
    '#ajax' => [
      'callback' => '::addBreakpoints',
      'wrapper' => 'edit-breakpoints-ajax-wrapper',
      'event' => 'change',
      'progress' => [
        'type' => 'fullscreen',
      ],
      'effect' => 'fade',
      'speed' => 'fast',
    ],
    '#attributes' => $tooltip,
    '#maxlength' => 1,
  ];
  $form['optimized'] = [
    '#type' => 'checkbox',
    '#title' => $this
      ->t('Optimized'),
    '#default_value' => $slick
      ->optimized(),
    '#description' => $this
      ->t('Check to optimize the stored options. Anything similar to defaults will not be stored, except those required by sub-modules and theme_slick(). Like you hand-code/ cherry-pick the needed options, and are smart enough to not repeat defaults, and free up memory. The rest are taken care of by JS. Uncheck only if theme_slick() can not satisfy the needs, and more hand-coded preprocess is needed which is less likely in most cases.'),
    '#access' => $slick
      ->id() != 'default',
    '#attributes' => $tooltip,
    '#wrapper_attributes' => [
      'class' => [
        'form-item--tooltip-wide',
      ],
    ],
  ];
  if ($slick
    ->id() == 'default') {
    $form['breakpoints']['#suffix'] = '</div>';
  }
  else {
    $form['optimized']['#suffix'] = '</div>';
  }
  if ($admin_css) {
    $form['optimized']['#field_suffix'] = '&nbsp;';
    $form['optimized']['#title_display'] = 'before';
  }

  // Options.
  $form['options'] = [
    '#type' => 'vertical_tabs',
    '#tree' => TRUE,
    '#parents' => [
      'options',
    ],
  ];

  // Main JS options.
  $form['settings'] = [
    '#type' => 'details',
    '#tree' => TRUE,
    '#title' => $this
      ->t('Settings'),
    '#attributes' => [
      'class' => [
        'details--settings',
        'has-tooltip',
      ],
    ],
    '#group' => 'options',
    '#parents' => [
      'options',
      'settings',
    ],
  ];
  foreach ($this
    ->getFormElements() as $name => $element) {
    $element['default'] = isset($element['default']) ? $element['default'] : '';
    $default_value = NULL !== $slick
      ->getSetting($name) ? $slick
      ->getSetting($name) : $element['default'];
    $form['settings'][$name] = [
      '#title' => isset($element['title']) ? $element['title'] : '',
      '#default_value' => $default_value,
    ];
    if (isset($element['type'])) {
      $form['settings'][$name]['#type'] = $element['type'];
      if ($element['type'] != 'hidden') {
        $form['settings'][$name]['#attributes'] = $tooltip;
      }
      else {

        // Ensures hidden element doesn't screw up the states.
        unset($element['states']);
      }
      if ($element['type'] == 'textfield') {
        $form['settings'][$name]['#size'] = 20;
        $form['settings'][$name]['#maxlength'] = 255;
      }
    }
    if (isset($element['options'])) {
      $form['settings'][$name]['#options'] = $element['options'];
    }
    if (isset($element['empty_option'])) {
      $form['settings'][$name]['#empty_option'] = $element['empty_option'];
    }
    if (isset($element['description'])) {
      $form['settings'][$name]['#description'] = $element['description'];
    }
    if (isset($element['states'])) {
      $form['settings'][$name]['#states'] = $element['states'];
    }

    // Expand textfield for easy edit.
    if (in_array($name, [
      'prevArrow',
      'nextArrow',
    ])) {
      $form['settings'][$name]['#default_value'] = trim(strip_tags($default_value));
    }
    if (isset($element['field_suffix'])) {
      $form['settings'][$name]['#field_suffix'] = $element['field_suffix'];
    }
    if (is_int($element['default'])) {
      $form['settings'][$name]['#maxlength'] = 60;
      $form['settings'][$name]['#attributes']['class'][] = 'form-text--int';
    }
    if ($admin_css && !isset($element['field_suffix']) && is_bool($element['default'])) {
      $form['settings'][$name]['#field_suffix'] = '&nbsp;';
      $form['settings'][$name]['#title_display'] = 'before';
    }
  }

  // Responsive JS options.
  // https://github.com/kenwheeler/slick/issues/951
  $form['responsives'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Responsive display'),
    '#open' => TRUE,
    '#tree' => TRUE,
    '#group' => 'options',
    '#parents' => [
      'options',
      'responsives',
    ],
    '#description' => $this
      ->t('Containing breakpoints and settings objects. Settings set at a given breakpoint/screen width is self-contained and does not inherit the main settings, but defaults. Be sure to set Breakpoints option above.'),
  ];
  $form['responsives']['responsive'] = [
    '#type' => 'details',
    '#title' => $this
      ->t('Responsive'),
    '#open' => TRUE,
    '#group' => 'responsives',
    '#parents' => [
      'options',
      'responsives',
      'responsive',
    ],
    '#prefix' => '<div id="edit-breakpoints-ajax-wrapper">',
    '#suffix' => '</div>',
    '#attributes' => [
      'class' => [
        'has-tooltip',
        'details--responsive--ajax',
      ],
    ],
  ];

  // Add some information to the form state for easier form altering.
  $form_state
    ->set('breakpoints_count', 0);
  $breakpoints_count = $form_state
    ->hasValue('breakpoints') ? $form_state
    ->getValue('breakpoints') : $slick
    ->getBreakpoints();
  if (!$form_state
    ->hasValue('breakpoints_count')) {
    $form_state
      ->setValue('breakpoints_count', $breakpoints_count);
  }
  $user_input = $form_state
    ->getUserInput();
  $breakpoints_input = isset($user_input['breakpoints']) ? (int) $user_input['breakpoints'] : $breakpoints_count;
  if ($breakpoints_input && $breakpoints_input != $breakpoints_count) {
    $form_state
      ->setValue('breakpoints_count', $breakpoints_input);
  }
  if ($form_state
    ->getValue('breakpoints_count') > 0) {
    $slick_responsive_options = $this
      ->getResponsiveFormElements($form_state
      ->getValue('breakpoints_count'));
    foreach ($slick_responsive_options as $i => $responsives) {

      // Individual breakpoint details depends on the breakpoints amount.
      $form['responsives']['responsive'][$i] = [
        '#type' => $responsives['type'],
        '#title' => $responsives['title'],
        '#open' => FALSE,
        '#group' => 'responsive',
        '#attributes' => [
          'class' => [
            'details--responsive',
            'details--breakpoint-' . $i,
            'has-tooltip',
          ],
        ],
      ];
      unset($responsives['title'], $responsives['type']);
      foreach ($responsives as $key => $responsive) {
        switch ($key) {
          case 'breakpoint':
          case 'unslick':
            $form['responsives']['responsive'][$i][$key] = [
              '#type' => $responsive['type'],
              '#title' => $responsive['title'],
              '#default_value' => isset($options['responsives']['responsive'][$i][$key]) ? $options['responsives']['responsive'][$i][$key] : $responsive['default'],
              '#description' => $responsive['description'],
              '#attributes' => $tooltip,
            ];
            if ($responsive['type'] == 'textfield') {
              $form['responsives']['responsive'][$i][$key]['#size'] = 20;
              $form['responsives']['responsive'][$i][$key]['#maxlength'] = 255;
            }
            if (is_int($responsive['default'])) {
              $form['responsives']['responsive'][$i][$key]['#maxlength'] = 60;
            }
            if (isset($responsive['field_suffix'])) {
              $form['responsives']['responsive'][$i][$key]['#field_suffix'] = $responsive['field_suffix'];
            }
            if ($admin_css && !isset($responsive['field_suffix']) && $responsive['type'] == 'checkbox') {
              $form['responsives']['responsive'][$i][$key]['#field_suffix'] = '&nbsp;';
              $form['responsives']['responsive'][$i][$key]['#title_display'] = 'before';
            }
            break;
          case 'settings':
            $form['responsives']['responsive'][$i][$key] = [
              '#type' => $responsive['type'],
              '#title' => $responsive['title'],
              '#open' => TRUE,
              '#group' => $i,
              '#states' => [
                'visible' => [
                  ':input[name*="[responsive][' . $i . '][unslick]"]' => [
                    'checked' => FALSE,
                  ],
                ],
              ],
              '#attributes' => [
                'class' => [
                  'details--settings',
                  'details--breakpoint-' . $i,
                  'has-tooltip',
                ],
              ],
            ];
            unset($responsive['title'], $responsive['type']);

            // @fixme, boolean default is ignored at index 0 only.
            foreach ($responsive as $k => $item) {
              $item['default'] = isset($item['default']) ? $item['default'] : '';
              $form['responsives']['responsive'][$i][$key][$k] = [
                '#title' => isset($item['title']) ? $item['title'] : '',
                '#default_value' => isset($options['responsives']['responsive'][$i][$key][$k]) ? $options['responsives']['responsive'][$i][$key][$k] : $item['default'],
                '#description' => isset($item['description']) ? $item['description'] : '',
                '#attributes' => $tooltip,
              ];
              if (isset($item['type'])) {
                $form['responsives']['responsive'][$i][$key][$k]['#type'] = $item['type'];
              }

              // Specify proper states for the breakpoint form elements.
              if (isset($item['states'])) {
                $states = '';
                switch ($k) {
                  case 'pauseOnHover':
                  case 'pauseOnDotsHover':
                  case 'pauseOnFocus':
                  case 'autoplaySpeed':
                    $states = [
                      'visible' => [
                        ':input[name*="[' . $i . '][settings][autoplay]"]' => [
                          'checked' => TRUE,
                        ],
                      ],
                    ];
                    break;
                  case 'centerPadding':
                    $states = [
                      'visible' => [
                        ':input[name*="[' . $i . '][settings][centerMode]"]' => [
                          'checked' => TRUE,
                        ],
                      ],
                    ];
                    break;
                  case 'touchThreshold':
                    $states = [
                      'visible' => [
                        ':input[name*="[' . $i . '][settings][touchMove]"]' => [
                          'checked' => TRUE,
                        ],
                      ],
                    ];
                    break;
                  case 'swipeToSlide':
                    $states = [
                      'visible' => [
                        ':input[name*="[' . $i . '][settings][swipe]"]' => [
                          'checked' => TRUE,
                        ],
                      ],
                    ];
                    break;
                  case 'verticalSwiping':
                    $states = [
                      'visible' => [
                        ':input[name*="[' . $i . '][settings][vertical]"]' => [
                          'checked' => TRUE,
                        ],
                      ],
                    ];
                    break;
                }
                if ($states) {
                  $form['responsives']['responsive'][$i][$key][$k]['#states'] = $states;
                }
              }
              if (isset($item['options'])) {
                $form['responsives']['responsive'][$i][$key][$k]['#options'] = $item['options'];
              }
              if (isset($item['empty_option'])) {
                $form['responsives']['responsive'][$i][$key][$k]['#empty_option'] = $item['empty_option'];
              }
              if (isset($item['field_suffix'])) {
                $form['responsives']['responsive'][$i][$key][$k]['#field_suffix'] = $item['field_suffix'];
              }
              if ($admin_css && !isset($item['field_suffix']) && is_bool($item['default'])) {
                $form['responsives']['responsive'][$i][$key][$k]['#field_suffix'] = '&nbsp;';
                $form['responsives']['responsive'][$i][$key][$k]['#title_display'] = 'before';
              }
            }
            break;
          default:
            break;
        }
      }
    }
  }
  return $form;
}