Skip to content

Instantly share code, notes, and snippets.

@init90
Last active August 21, 2018 20:20
Show Gist options
  • Select an option

  • Save init90/186ff548cbe93823a25114df5dfaa25e to your computer and use it in GitHub Desktop.

Select an option

Save init90/186ff548cbe93823a25114df5dfaa25e to your computer and use it in GitHub Desktop.
Drupal 8, create custom form API element. In the example below, the element outputs two fields for entering a range of numeric values.
Usage example:
$form['photo_size'] = [
'#type' => 'number_range',
'#title' => $this->getFieldTitle($product, 'field_insert_size'),
'#min' => min($size_config['field_photo_insert_diapason']),
'#max' => max($size_config['field_photo_insert_diapason']),
'#prefix' => '<div id="photo_size">',
'#suffix' => '</div>',
'#states' => [
'visible' => [
':input[name="insert_types"]' => [
[
'value' => PHOTO_INSERT_SECTION,
],
],
],
],
'#ajax' => $this->updatePreviewAjaxWrapper(),
'#default_value' => [
'from' => $size_config['field_photo_insert_diapason']['from'] ,
'to' => ceil($size_config['field_photo_insert_diapason']['to'] / 2),
],
];
<?php
namespace Drupal\builder_module\Element;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\FormElement;
/**
* Provides a form element for numeric range.
*
* @FormElement("number_range")
*/
class NumberRange extends FormElement {
/**
* {@inheritdoc}
*/
public function getInfo() {
$class = get_class($this);
return [
'#input' => TRUE,
'#step' => 0.5,
'#min' => 1,
'#max' => 30,
'#title' => '',
'#ajax' => NULL,
'#delimiter' => 'x',
'#states' => [],
'#process' => [
[$class, 'processNumberRange'],
[$class, 'processAjaxForm'],
],
'#theme_wrappers' => [
'container',
],
];
}
/**
* Process 'number_range' element.
*/
public static function processNumberRange(&$element, FormStateInterface &$form_state, &$complete_form) {
$name = $element['#name'];
$input = $form_state->getUserInput();
$element['from'] = [
'#type' => 'number',
'#title' => $element['#title'],
'#name' => "{$name}_from",
'#min' => $element['#min'],
'#max' => $element['#max'],
'#step' => $element['#step'],
'#states' => $element['#states'],
'#ajax' => $element['#ajax'],
'#default_value' => !empty($element['#default_value']['from']) ? $element['#default_value']['from'] : $element['#min'],
'#attributes' => [
'name' => "{$name}_from",
'class' => [
'range_from',
],
],
];
$element['delimiter'] = array(
'#type' => 'item',
'#states' => $element['#states'],
'#markup' => $element['#delimiter'],
'#attributes' => [
'class' => [
'range_delimiter',
],
],
);
$element['to'] = [
'#type' => 'number',
'#name' => "{$name}_to",
'#min' => $element['#min'],
'#max' => $element['#max'],
'#step' => $element['#step'],
'#states' => $element['#states'],
'#ajax' => $element['#ajax'],
'#default_value' => !empty($element['#default_value']['to']) ? $element['#default_value']['to'] : $element['#min'],
'#attributes' => [
'name' => "{$name}_to",
'class' => [
'range_to',
],
],
];
if (
isset($input["{$name}_from"]) && is_numeric($input["{$name}_from"]) &&
isset($input["{$name}_to"]) && is_numeric($input["{$name}_to"])
) {
$element['#value'] = [
'from' => $input["{$name}_from"],
'to' => $input["{$name}_to"],
];
$form_state->setValue($name, $element['#value']);
}
return $element;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment