2017-08-20 50 views
0

我有一個分類選項列表make我選擇說豐田分類列表依賴於從另一個分類列表中選擇,drupal 8

  1. 我想第二個分類選項列表只與豐田模型(例如花冠,hilux等...)。
  2. 當我選擇奔馳第二列表將包含隨後C級,ML等...

我已經從本地主機XAMPP谷歌的例子創建實體車輛,窗口10

在我的車輛形式我可以填充第一個列表。但第二個看起來是空的。

這是我的代碼。請幫助:

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']; 
} 

回答

2

在這裏,我給你根據你的榜樣VehiculesForm.php工作示例:

我冒昧地重新命名一些變量更好的可讀性。

<?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']; 
    } 
} 

另外,我建議你做你的代碼,例如一些改進措施:

  • 不要使用switch但與參考Fields鏈接您的分類法。
  • 添加驗證以確保安全性(請檢查我們不欺騙你的領域,例如)!
  • 請勿使用品牌名稱,而是使用ID。避免$options[$brand->getName()] = $brand->getName();並使用類似$options[$brand->id()] = $brand->getName();

希望它會幫助你的!

+0

你救了我,現在爲我工作。起初有錯誤,但添加了 – Clemabiz

+0

你已經救了我很多,現在工作謝謝。起初有錯誤,但添加了「使用Drupal \ Core \ Form \ FormStateInterface;」並將「class vehicleForm extends FormBase」改爲「class VehicleForm extends ContentEntityForm」。 NB。我還將「車輛」改回「車輛」,因爲我的整個主體文件都涉及此實體。我現在正在研究如何從表單中保存實體(車輛)......因爲這不是將實體保存到數據庫中。感謝批號 – Clemabiz

+0

樂於幫助,並歡迎來到Stack Overflow。如果此答案或任何其他人解決了您的問題,請將其標記爲已接受。它將幫助人們在頁面上看到好的答案,這也有助於撰稿人將注意力集中在仍然沒有答案的舊版SO上。 –

相關問題