分类列表取决于其他分类列表(drupal 8)中的选择 [英] Taxonomy list dependent on choice from another taxonomy list, drupal 8

查看:97
本文介绍了分类列表取决于其他分类列表(drupal 8)中的选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个分类选项列表制作,在这里我选择说丰田

I have a taxonomy option list make where I choose say Toyota.


  1. 我只希望使用丰田汽车的型号(例如花冠,hilux等)的第二个分类选项列表。

  2. 当我选择Benz时,第二个列表将包含C-类,ML等...

我已经从xampp本地主机,Windows 10上的google示例创建了实体工具。

I have created the entity vehicle from google examples on xampp localhost, windows 10.

在我的车辆表格中,我可以填充第一个列表。但是第二个似乎为空。

In my vehicle form I'm able to populate the first list. But the second appears empty.

这是我的代码。请帮助:

Here is my code. Please help:

public function buildForm(array $form, FormStateInterface $form_state, $params = NULL) {
  $options = array(); 
  $tax = "make";  
  $terms = \Drupal::entityManager()->getStorage('taxonomy_term')->loadTree($tax, $parent = 0, $max_depth = NULL, $load_entities = FALSE);
  foreach ($terms as $term) {
    $options[] = $term->name;
  } 

  $form['make'] = array(
    '#type' => 'select',
    '#title' => t('Make'),
    'weight' => 0,
    '#options' => $options,
    '#ajax' => array(
      'callback' => [$this, 'changeOptionsAjax'],
      'wrapper' => 'model_wrapper',
    ),
  );

  $form['model'] = array(
    '#type' => 'select',
    '#title' => t('Model'),
    'weight' => 1,
    '#options' => $this->getOptions($form_state),
    '#prefix' => '<div id="model_wrapper">',
    '#suffix' => '</div>',
  );

  return $form;
}

public function getOptions(FormStateInterface $form_state) {
  $options = array();
  if ($form_state->getValue('make') == "Benz") { 
    $tax="benz";
  }
  elseif ($form_state->getValue('make') == "BMW") {
    $tax="bmw";
  } 
  elseif ($form_state->getValue('make') == "Toyota") {
    $tax="toyota";
  } 
  else {
    $tax="title";
    // title is just another taxonomy list I'm using as default if make is not found
  }

  $terms = \Drupal::entityManager()->getStorage('taxonomy_term')->loadTree($tax, $parent = 0, $max_depth = NULL, $load_entities = FALSE);
  foreach ($terms as $term) {
    $options[] = $term->name;
  }  
  return $options;
}

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


推荐答案

在这里,我给您一个工作基于您的示例的示例 VehiculesForm.php

Here I give you a working sample based on your example VehiculesForm.php:

我随意重命名某些变量以提高可读性。

I took the liberty to rename some variable for better readability.

<?php

namespace Drupal\example\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;

/**
 * VehiculesForm.
 */
class VehiculesForm extends FormBase {
  /**
   * The term Storage.
   *
   * @var \Drupal\taxonomy\TermStorageInterface
   */
  protected $termStorage;

  /**
   * {@inheritdoc}
   */
  public function __construct(EntityTypeManagerInterface $entity) {
    $this->termStorage = $entity->getStorage('taxonomy_term');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    // Instantiates this form class.
    return new static(
    // Load the service required to construct this class.
    $container->get('entity_type.manager')
    );
  }

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $params = NULL) {
    $brands = $this->termStorage->loadTree('make', 0, NULL, TRUE);
    $options = [];
    if ($brands) {
      foreach ($brands as $brand) {
        $options[$brand->getName()] = $brand->getName();
      }
    }
    $form['brand'] = array(
      '#type'    => 'select',
      '#title'   => $this->t('brand'),
      '#options' => $options,
      '#ajax'    => array(
        'callback' => [$this, 'selectModelsAjax'],
        'wrapper'  => 'model_wrapper',
      ),
    );

    $form['model'] = array(
      '#type'      => 'select',
      '#title'     => $this->t('Model'),
      '#options'   => ['_none' => $this->t('- Select a brand before -')],
      '#prefix'    => '<div id="model_wrapper">',
      '#suffix'    => '</div>',
      '#validated' => TRUE,
    );

    $form['actions']['submit'] = [
      '#type'  => 'submit',
      '#value' => $this->t('Send'),
    ];

    return $form;
  }

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

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

  /**
   * Called via Ajax to populate the Model field according brand.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   *
   * @return array
   *   The form model field structure.
   */
  public function selectModelsAjax(array &$form, FormStateInterface $form_state) {
    $options = [];

    $vocabulary = 'title';
    switch ($form_state->getValue('brand')) {
      case 'Benz':
        $vocabulary = 'benz';
        break;
      case 'BMW':
        $vocabulary = 'bmw';
        break;
      case 'Toyota':
        $vocabulary = 'toyota';
        break;
    }

    $models = $this->termStorage->loadTree($vocabulary, 0, NULL, TRUE);
    if ($models) {
      foreach ($models as $model) {
        $options[$model->id()] = $model->getName();
      }
    }
    $form['model']['#options'] = $options;

    return $form['model'];
  }
}






另外,我建议您对代码进行一些改进,例如:


Also, I suggest you to make some improvments on you code such:


  • 不要使用开关,但将您的分类法与参考字段链接。

  • 添加验证以确保安全性(例如,检查我们是否不欺骗您的字段)!!

  • 不要使用品牌名称,而是ID。避免使用 $ options [$ brand-> getName()] = $ brand-> getName(); 并使用 $ options [$ brand-> id()] = $ brand-> getName();

  • Don't use a switch but link your taxonomies with a reference fields.
  • Add validation to ensure security (check we don't spoof your field for example) !!
  • Don't use the brandname but the ID. Avoid $options[$brand->getName()] = $brand->getName(); and use something like $options[$brand->id()] = $brand->getName();.

希望它将对您有帮助!

Hope it will help you !

这篇关于分类列表取决于其他分类列表(drupal 8)中的选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆