Use multiselect to select classes

Created on 19 September 2018, over 6 years ago
Updated 18 December 2023, over 1 year ago

For my project I found it useful to provide content builders with a multiselect array to add classes to links.

This allows them to add classes like "btn", "btn-lg", "btn-primary" (or, my project's equivalent of these bootstrap classes) without needing to remember the text.

Here's code that makes this work, I thought this might be useful for someone else. Not sure how one would roll this into editor_advanced_link if they wanted to, this code needs to be added to your own custom module (named my_module below).

This combines nicely with the improved_multi_select module.

<?php

/**
 * @param $form
 * @param $form_state
 * @param $form_id
 *
 * Modify the editor link dialog form
 */
function my_module_form_editor_link_dialog_alter(&$form, $form_state, $form_id){

  $classes_options = [
    'button' =>  'Button',
    'button-orange' =>  'Orange button',
    'button-blue' =>  'Blue button',
    'button-green' =>  'Green button',
    'button-outlined' =>  'Outlined button',
    'button-large' =>  'Large button',
    'button-small' =>  'Small button',
    'button-xs' =>  'Extra small button',
  ];

  // Set the link's default value, we want to make sure we only include allowed classes here
  $classes_value = explode(' ', $form['attributes']['class']['#default_value']);

  // Hide the default class field
  $form['attributes']['class']['#type'] = 'hidden';

  // Build a multiselect for classes which will populate the space delimited 'class' field
  $form['classes']['#type'] = 'select';
  $form['classes']['#multiple'] = true;
  $form['classes']['#description'] = "Please select all attributes that should apply";
  $form['classes']['#default_value'] = $classes_value;
  $form['classes']['#options'] = $classes_options;

  // Add our custom validate handler on submit which will build the attributes.class string from the classes[]
  $form['#validate'] = array_merge(['my_module_form_editor_link_dialog_validate'], $form['#validate']);

}

/**
 * @param array $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *
 * Implode array keys from the classes[] array and make them a string in the attributes.class value
 */
function my_module_form_editor_link_dialog_validate(array &$form, \Drupal\Core\Form\FormStateInterface $form_state) {

  // Get the array of classes set by the multiselect
  $classes = array_keys($form_state->getValue('classes'));

  // If the user included button subclasses, eg "button-white", we want to make sure the base "button" class is also included
  if (count($classes) && !in_array('button', $classes)){
    foreach($classes as $class ){
      if (strpos($class, 'button') === 0){
        $classes[] = "button";
        break;
      }
    }
  }

  // Implode the classes and set it on the attributes.class field
  $form_state->setValueForElement($form['attributes']['class'], implode(' ', $classes));
}
?>
✨ Feature request
Status

Closed: won't fix

Version

1.0

Component

Code

Created by

🇺🇸United States vood002

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024