function FormHooks::stickyActionButtonsAndSidebar

Same name and namespace in other branches
  1. 11.x core/themes/admin/src/Hook/FormHooks.php \Drupal\admin\Hook\FormHooks::stickyActionButtonsAndSidebar()

Add some major form overrides.

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

string $form_id: The form id.

See also

hook_form_alter()

File

core/themes/admin/src/Hook/FormHooks.php, line 632

Class

FormHooks
Provides form related hook implementations.

Namespace

Drupal\admin\Hook

Code

public function stickyActionButtonsAndSidebar(array &$form, FormStateInterface $form_state, string $form_id) : void {
  if ($this->isModalOrOffcanvas()) {
    $form['is_ajax_request'] = [
      '#weight' => -1,
    ];
    return;
  }
  if (str_ends_with($form_id, '_exposed_form') || str_starts_with($form_id, 'views_ui_')) {
    return;
  }
  // Save form types and behaviors.
  $is_content_form = Helper::isContentForm($form_state, $form_id);
  // If there are action buttons, and they should either be sticky or there
  // is a content form, where the sidebar toggle is required, prepare the
  // sticky action container for the top bar.
  if (isset($form['actions']) && (self::useStickyActionButtons($is_content_form) || $is_content_form)) {
    // Sticky action container.
    $form['gin_sticky_actions'] = [
      '#type' => 'container',
      '#weight' => -1,
      '#multilingual' => TRUE,
      '#attributes' => [
        'class' => [
          'gin-sticky-form-actions',
        ],
      ],
    ];
    $form['#after_build'][] = [
      __CLASS__,
      'formAfterBuild',
    ];
  }
  // Sticky action buttons.
  if (self::useStickyActionButtons($is_content_form) && isset($form['actions'])) {
    // Add sticky class.
    $form['actions']['#attributes']['class'][] = 'gin-sticky-form-actions';
    // Add a class to identify modified forms.
    if (!isset($form['#attributes']['class'])) {
      $form['#attributes']['class'] = [];
    }
    elseif (is_string($form['#attributes']['class'])) {
      $form['#attributes']['class'] = [
        $form['#attributes']['class'],
      ];
    }
    $form['#attributes']['class'][] = 'gin--has-sticky-form-actions';
    // Assign status to gin_actions.
    $form['gin_sticky_actions']['status'] = [
      '#type' => 'container',
      '#weight' => -1,
      '#multilingual' => TRUE,
    ];
    // Only alter the status field on content forms.
    if ($is_content_form) {
      // Set form id to status field.
      if (isset($form['status']['widget']['value'])) {
        $form['status']['widget']['value']['#attributes']['form'] = $form['#id'];
        $widget_type = $form['status']['widget']['value']['#type'] ?? FALSE;
      }
      else {
        $widget_type = $form['status']['widget']['#type'] ?? FALSE;
      }
      // Only move status to status group if it is a checkbox.
      if ($widget_type === 'checkbox') {
        $form['status']['#group'] = 'status';
      }
    }
    // Helper item to move focus to sticky header.
    $form['gin_move_focus_to_sticky_bar'] = [
      '#markup' => '<a href="#" class="visually-hidden" role="button" gin-move-focus-to-sticky-bar>Moves focus to sticky header actions</a>',
      '#weight' => 999,
    ];
    // Attach library.
    $form['#attached']['library'][] = 'admin/more_actions';
  }
  // Remaining changes only apply to content forms.
  if (!$is_content_form) {
    return;
  }
  // Provide a default meta form element if not already provided.
  // @see NodeForm::form()
  $form['advanced']['#attributes']['class'][] = 'entity-meta';
  if (!isset($form['meta'])) {
    $form['meta'] = [
      '#group' => 'advanced',
      '#weight' => -10,
      '#title' => $this->t('Status'),
      '#attributes' => [
        'class' => [
          'entity-meta__header',
        ],
      ],
      '#tree' => TRUE,
    ];
  }
  $this->ensureAdvancedSettings($form);
  // Add sidebar toggle.
  $hide_panel = $this->t('Hide sidebar panel');
  $form['gin_sticky_actions']['gin_sidebar_toggle'] = [
    '#markup' => '<a href="#toggle-sidebar" class="meta-sidebar__trigger trigger" role="button" title="' . $hide_panel . '" aria-controls="gin_sidebar"><span class="visually-hidden">' . $hide_panel . '</span></a>',
    '#weight' => 1000,
  ];
  $form['#attached']['library'][] = 'admin/sidebar';
  // Create gin_sidebar group.
  $form['gin_sidebar'] = [
    '#group' => 'meta',
    '#type' => 'container',
    '#weight' => 99,
    '#multilingual' => TRUE,
    '#attributes' => [
      'class' => [
        'gin-sidebar',
      ],
    ],
  ];
  // Copy footer over.
  $form['gin_sidebar']['footer'] = $form['footer'] ?? [];
  // Sidebar close button.
  $close_sidebar_translation = $this->t('Close sidebar panel');
  $form['gin_sidebar']['gin_sidebar_close'] = [
    '#markup' => '<a href="#close-sidebar" class="meta-sidebar__close trigger" role="button" title="' . $close_sidebar_translation . '"><span class="visually-hidden">' . $close_sidebar_translation . '</span></a>',
  ];
  $form['gin_sidebar_overlay'] = [
    '#markup' => '<div class="meta-sidebar__overlay trigger"></div>',
  ];
  // Specify necessary node form theme and library.
  // @see gin_form_node_form_alter
  $form['#theme'] = [
    'node_edit_form',
  ];
  // Attach libraries.
  $form['#attached']['library'][] = 'admin/node-form';
  $form['#attached']['library'][] = 'admin/edit_form';
  // Add a class that allows the logic in edit_form.js to identify the form.
  $form['#attributes']['class'][] = 'gin-node-edit-form';
  // If not logged in hide changed and author node info on add forms.
  $not_logged_in = $this->currentUser
    ->isAnonymous();
  $route = $this->routeMatch
    ->getRouteName();
  if ($not_logged_in && $route === 'node.add') {
    unset($form['meta']['changed'], $form['meta']['author']);
  }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.