keyboard_shortcuts-1.0.0/src/Form/KeyboardShortcutsSettingsForm.php

src/Form/KeyboardShortcutsSettingsForm.php
<?php

namespace Drupal\keyboard_shortcuts\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\Entity\Role;

class KeyboardShortcutsSettingsForm extends ConfigFormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'keyboard_shortcuts';
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [
      'keyboard_shortcuts.settings',
    ];
  }

  /**
   * Get a descriptive help text.
   *
   * @return \Drupal\Core\StringTranslation\TranslatableMarkup
   */
  protected function getDescription() {
    $description = $this->t(<<< QQ
        <b>Modifier keys</b>
        <p>You can use the following modifier keywords: <em>shift</em>,
        <em>ctrl</em>, <em>alt</em>, or <em>meta</em>.</p>
        <p>You can use substitute keywords <em>option</em> for <em>alt</em> and
        <em>command</em> for <em>meta</em>.</p>
        <p>Other special keywords are: <em>backspace</em>, <em>tab</em>,
        <em>enter</em>, <em>return</em>,
        <em>capslock</em>, <em>esc</em>, <em>escape</em>, <em>space</em>,
        <em>pageup</em>, <em>pagedown</em>, <em>end</em>, <em>home</em>,
        <em>left</em>, <em>up</em>, <em>right</em>, <em>down</em>, <em>ins</em>,
        <em>del</em> and <em>plus</em>.</p>
        <p>Any other key you should be able to reference directly by it's
        character: a-z, /, $, *, or =.</p>
        <b>Single key</b>
        <p>Just type in the character or special key names (see above).</p>
        <b>Combination of keys</b>
        <p>Combine several keys using a '+' sign (ctrl+s).</p>
        <b>Sequence of keys</b>
        <p>Define a sequence of keys using a space (d ctrl+s).</p>
        <b>Tokens</b>
        <p>You can use '[node:]' and '[user:]' tokens in the action argument
        fields. (e.g. [node:edit-url])</p>
        <b>Note</b>
        <p>Some browsers block standard shortcuts like for example (ctrl+n or
        command+n). It is advised to use combinations that don't overwrite
        default browser behavior.</p>
    QQ);

    return $description;
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildForm($form, $form_state);

    $config = $this->config('keyboard_shortcuts.settings');

    $roles = Role::loadMultiple();
    array_walk($roles, function(&$role) {
      $role = $role->label();
    });

    $form['#title'] = $this->t('Keyboard shortcut settings');
    $form['#tree'] = true;

    $form['shortcuts'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Shortcuts'),
      '#collapsed' => FALSE,
      '#prefix' => '<div id="shortcuts-wrapper">',
      '#suffix' => '</div>',
    ];

    $shortcuts = $form_state->getValue('shortcuts') ?? $config->get('shortcuts') ?? [];

    if (empty($shortcuts)) {
      $shortcuts[] = $this->getNewShortcut();
    }

    foreach ($shortcuts as $delta => $shortcut) {

      $auto_label = (empty($shortcut['keystroke']) ? 'Undefined shortcut' : $shortcut['keystroke']);
      $label = empty($shortcut['label']) ? $auto_label : $shortcut['label'];

      $form['shortcuts'][$delta] = [
        '#type' => 'details',
        '#collapsed' => !empty($shortcut['keystroke']),
        '#collapsible' => TRUE,
        '#title' => ($label != $auto_label ? $label . ' (' . $auto_label . ')' : $label),
      ];

      $form['shortcuts'][$delta]['label'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Label') . ' ' . $delta,
        '#description' => $this->t('Give the shortcut a label (used in the gui).'),
        '#default_value' => $label,
        '#required' => true,
      ];

      $form['shortcuts'][$delta]['keystroke'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Keystroke(s)'),
        '#description' => $this->t('Give the keystroke(s) to associate to this shortcut. Separate multiple keystrokes with a comma. Leave empty to remove this keystroke entry.'),
        '#default_value' => $shortcut['keystroke'] ?? '',
        '#required' => true,
      ];

      $form['shortcuts'][$delta]['roles'] = [
        '#type' => 'checkboxes',
        '#title' => $this->t('Roles'),
        '#options' => $roles,
        '#description' => $this->t('Select which roles are allowed to use this keystroke. Select none to disable this check.'),
        '#default_value' => $shortcut['roles'] ?? [],
      ];

      $form['shortcuts'][$delta]['enable_during_input'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Enable during input'),
        '#description' => $this->t('Enable the use of the shortcut inside of inputs (textarea, text, select, editable content)'),
        '#default_value' => $shortcut['enable_during_input'] ?? 1,
      ];

      $form['shortcuts'][$delta]['prevent_default'] = [
        '#type' => 'checkbox',
        '#title' => $this->t('Prevent default'),
        '#description' => $this->t('Prevent default behaviour of the shortcut keystroke (eg. Ctrl+S, normally saves the webpage).'),
        '#default_value' => $shortcut['prevent_default'] ?? 1,
      ];

      $form['shortcuts'][$delta]['action'] = [
        '#type' => 'select',
        '#title' => $this->t('Action'),
        '#description' => $this->t('Give the action to be executed'),
        '#default_value' => $shortcut['action'] ?? 'redirect',
        '#options' => [
          'trigger' => 'trigger',
          'modal' => 'modal',
          'redirect' => 'redirect',
          'callback' => 'callback',
        ],
        '#required' => true,
      ];

      $form['shortcuts'][$delta]['arguments'] = [
        '#type' => 'fieldset',
        '#collapsed' => FALSE,
        '#collapsible' => FALSE,
        '#title' => $this->t('Action settings'),
      ];

      $arguments = $shortcut['arguments'] ?? [];

      // Trigger arguments
      $form['shortcuts'][$delta]['arguments']['type'] = [
        '#type' => 'select',
        '#title' => $this->t('Type'),
        '#default_value' => $arguments['type'] ?? '',
        '#options' => [
          'click' => 'click',
          'mouseleave' => 'mouseleave',
          'mouseenter' => 'mouseenter',
        ],
        '#states' => [
          'visible' => [
            ':input[name="shortcuts['.$delta.'][action]"]' => ['value' => 'trigger'],
          ],
        ],
      ];
      $form['shortcuts'][$delta]['arguments']['selector'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Selector'),
        '#description' => $this->t('Enter a jQuery style element selector. You can use tokens (see below).'),
        '#default_value' => $arguments['selector'] ?? '',
        '#states' => [
          'visible' => [
            ':input[name="shortcuts['.$delta.'][action]"]' => ['value' => 'trigger'],
          ],
        ],
      ];

      // 'redirect':
      $form['shortcuts'][$delta]['arguments']['url'] = [
        '#type' => 'textfield',
        '#title' => $this->t('URL'),
        '#description' => $this->t('Enter a url to redirect to. You can use tokens (see below).'),
        '#default_value' => $arguments['url'] ?? '',
        '#states' => [
          'visible' => [
            ':input[name="shortcuts['.$delta.'][action]"]' => [
              ['value' => 'redirect'],
              ['value' => 'modal'],
            ],
          ],
        ],
      ];

      // 'callback':
      $form['shortcuts'][$delta]['arguments']['callback'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Callback'),
        '#description' => $this->t('The javascript callback to execute when the shortcut is pressed.'),
        '#default_value' => $arguments['callback'] ?? '',
        '#states' => [
          'visible' => [
            ':input[name="shortcuts['.$delta.'][action]"]' => ['value' => 'callback'],
          ],
        ],
      ];

      $form['shortcuts'][$delta]['remove'] = [
        '#type' => 'submit',
        '#value' => $this->t('Remove'),
        '#submit' => ['::removeCallback'],
        '#name' => 'remove-shortcut-' . $delta,
        '#ajax' => [
          'callback' => '::ajaxCallback',
          'wrapper' => 'shortcuts-wrapper',
        ],
      ];
    }

    $form['shortcuts']['actions']['add'] = [
      '#type' => 'submit',
      '#value' => $this->t('Add shortcut'),
      '#submit' => ['::addCallback'],
      '#ajax' => [
        'callback' => '::ajaxCallback',
        'wrapper' => 'shortcuts-wrapper',
      ],
    ];

    $form_state->setCached(FALSE);

    $form['info'] = [
      '#type' => 'item',
      '#description' => $this->getDescription(),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    $config = $this->config('keyboard_shortcuts.settings');
    $shortcuts = $form_state->getValue('shortcuts');

    // Filter out any empty keystrokes.
    $shortcuts = array_filter($shortcuts, function ($shortcut ) {
      return !empty($shortcut['keystroke']);
    });

    // Don't save the add more button.
    unset($shortcuts['actions']);

    // Clean up the arguments we don't need.
    array_walk($shortcuts, function(&$shortcut) {
      $arguments = [
        '' => [],
        'trigger' => ['url', 'callback'],
        'modal' => ['callback', 'type', 'selector'],
        'redirect' => ['callback', 'type', 'selector'],
        'callback' => ['url', 'type', 'selector'],
      ][$shortcut['action'] ?? ''];
      foreach($arguments as $argument) {
        unset($shortcut['arguments'][$argument]);
      }
      // Don't save the remove button.
      unset($shortcut['remove']);
    });

    $config->set('shortcuts',  array_values($shortcuts));
    $config->save();

    parent::submitForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $element = $form_state->getTriggeringElement();
    if (isset($element['#array_parents'][2]) && $element['#array_parents'][2] == 'remove') {
      $form_state->clearErrors();
    }
  }

  public function addCallback(array &$form, FormStateInterface $form_state) {
    $shortcuts = $form_state->getValue('shortcuts');
    unset($shortcuts['actions']);
    $shortcuts[] = $this->getNewShortcut();
    $form_state->setValue('shortcuts', $shortcuts);
    $form_state->setRebuild();
  }

  public function ajaxCallback(array &$form, FormStateInterface $form_state) {
    return $form['shortcuts'];
  }

  public function removeCallback(array &$form, FormStateInterface $form_state) {
    $shortcuts = $form_state->getValue('shortcuts');
    unset($shortcuts['actions']);
    $element = $form_state->getTriggeringElement();
    $index = $element['#array_parents'][1];
    unset($shortcuts[$index]);
    $form_state->setValue('shortcuts', $shortcuts);
    $form_state->setRebuild();
  }

  protected function getNewShortcut() {
    return [
      'label' => $this->t('New shortcut'),
      'keystroke' => '',
      'roles' => [],
      'enable_during_input' => 1,
      'prevent_default' => 1,
      'action' => 'redirect',
      'arguments' => [
        'type' => '',
        'selector' => '',
        'url' => '',
        'callback' => '',
      ],
    ];
  }
}

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

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