forms - Taxonomy list dependent on choice from another taxonomy list, drupal 8 -
i have taxonomy option list make choose toyota.
- i want second taxonomy option list models of toyota (eg. corolla, hilux etc...).
- when choose benz second list contains c-class, ml, etc...
i have created entity vehicle google examples on xampp localhost, windows 10.
in vehicle form i'm able populate first list. second appears empty.
here 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 $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 taxonomy list i'm using default if make not found } $terms = \drupal::entitymanager()->getstorage('taxonomy_term')->loadtree($tax, $parent = 0, $max_depth = null, $load_entities = false); foreach ($terms $term) { $options[] = $term->name; } return $options; } public function changeoptionsajax(array &$form, formstateinterface $form_state) { return $form['model']; }
here give working sample based on example vehiculesform.php
:
i took liberty rename variable 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 { /** * 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 form class. return new static( // load service required construct 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 $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 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 populate model field according brand. * * @param array $form * associative array containing structure of form. * @param \drupal\core\form\formstateinterface $form_state * current state of form. * * @return array * 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 $model) { $options[$model->id()] = $model->getname(); } } $form['model']['#options'] = $options; return $form['model']; } }
also, suggest make improvments on code such:
- don't use
switch
link taxonomies reference fields. - add validation ensure security (check don't spoof field example) !!
- don't use brandname id. avoid
$options[$brand->getname()] = $brand->getname();
, use$options[$brand->id()] = $brand->getname();
.
hope !
Comments
Post a Comment