Skip to content
Snippets Groups Projects
HmDisplayJstree.php 4.14 KiB
Newer Older
<?php

namespace Drupal\hierarchy_manager\Plugin\HmDisplayPlugin;

use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\hierarchy_manager\Plugin\HmDisplayPluginBase;
Mingsong's avatar
Mingsong committed
use Drupal\hierarchy_manager\Plugin\HmDisplayPluginInterface;

/**
 * JsTree display plugin.
 *
 * @HmDisplayPlugin(
 *   id = "hm_display_jstree",
 *   label = @Translation("JsTree")
 * )
 */
class HmDisplayJstree extends HmDisplayPluginBase implements HmDisplayPluginInterface {
  use StringTranslationTrait;
Mingsong's avatar
Mingsong committed
  /**
   * Build the tree form.
   */
  public function getForm(string $url_source, string $url_update, array &$form = [], FormStateInterface &$form_state = NULL, $options = NULL, $confirm = FALSE) {
    if (!empty($url_source)) {
      if (!empty(($form_state))) {
        $parent_formObj = $form_state->getFormObject();
        $parent_id = $parent_formObj->getFormId();
      }
      // The jsTree default theme.
      $theme = 'default';
      if (!empty($options)) {
        $jsonObj = json_decode($options);
        if (isset($jsonObj->theme) && isset($jsonObj->theme->name)) {
          $theme = $jsonObj->theme->name;
      // Search input.
      $form['search'] = [
        '#type' => 'textfield',
        '#title' => $this
Mingsong's avatar
Mingsong committed
          ->t('Search'),
        '#description' => $this->t('Type in the search keyword here to filter the tree below. Multiple keywords separated by spaces. Empty the keyword to reset the tree.'),
        '#attributes' => [
          'name' => 'jstree-search',
          'id' => isset($parent_id) ? 'hm-jstree-search-' . $parent_id : 'hm-jstree-search',
Mingsong's avatar
Mingsong committed
          'parent-id' => $parent_id ?? '',
          'class' => [
            'hm-jstree-search',
          ],
        ],
        '#size' => 60,
        '#maxlength' => 128,
      ];
      $form['jstree'] = [
        '#type' => 'html_tag',
        '#suffix' => '<div class="description">' . $this->t('Click an item to edit it. Drag and drop items to change their position in the tree.') . '</div>',
        '#tag' => 'div',
        '#value' => '',
        '#attributes' => [
          'class' => [
            'hm-jstree',
          ],
          'id' => isset($parent_id) ? 'hm-jstree-' . $parent_id : 'hm-jstree',
Mingsong's avatar
Mingsong committed
          'parent-id' => $parent_id ?? '',
          'options' => $options,
          'data-source' => $url_source,
          'url-update' => $url_update,
        ],
      ];
      $form['#attached']['library'][] = 'hierarchy_manager/libraries.jquery.jstree.' . $theme;
      $form['#attached']['library'][] = 'hierarchy_manager/feature.hm.jstree';
      $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
    return $form;
  /**
   * Build the data array that JS library accepts.
   */
  public function treeData(array $data) {
    $jstree_data = [];
    // The array key of jsTree is different from the data source.
    // So we need to translate them.
    foreach ($data as $tree_node) {
      // Applies a very permissive XSS/HTML filter for node text.
      $tree_node['text'] = Xss::filterAdmin($tree_node['text']);
      $jstree_node = $tree_node;
      // The root id for jsTree is #.
      if (empty($tree_node['parent'])) {
        $jstree_node['parent'] = '#';
      }
      if (!$tree_node['status']) {
        $jstree_node['li_attr'] = [
          'class' => 'hm-tree-node-disabled',
        ];
      }

      $dialog_options = [
        'minWidth' => '300',
        'width' => '960',
        'title' => $this->t('Edit') . ' ' . preg_replace('~<span(.*?)</span>~Usi', '', $tree_node['text']),
Mingsong's avatar
Mingsong committed
      // Custom data.
      $jstree_node['a_attr'] = [
        'href' => $jstree_node['edit_url'],
        'class' => 'use-ajax',
        'data-dialog-type' => 'modal',
        'data-dialog-options' => Json::encode($dialog_options),
Mingsong Hu's avatar
Mingsong Hu committed
      $jstree_node['data'] = [
        'weight' => $tree_node['weight'],
Mingsong's avatar
Mingsong committed
        'draggable' => $tree_node['draggable'],
Mingsong Hu's avatar
Mingsong Hu committed
      ];
      unset($jstree_node['edit_url']);
      // Add this node into the data array.
      $jstree_data[] = $jstree_node;
    }
    return $jstree_data;
  }