Динамический список выбора в форме (зависимый раскрывающийся список)


Я использую Drupal seven. Я хочу, чтобы параметры в списке выбора зависели от значения, выбранного в другом списке выбора в форме. Я уверен, что об этом уже много раз спрашивали, но мне трудно найти четкий ответ на то, как это сделать.

Форма предназначена для ввода пользователями истории работ. Им нужно выбрать эскадрилью, которая является ссылкой узла на тип поля эскадрильи, и это находится в раскрывающемся списке. Однако эскадрилья, зависимая в раскрывающемся списке "город". Пользователям сначала нужно выбрать город, который затем будет фильтровать параметры для эскадрильи. В типе содержимого эскадрильи я создал таксономию для города, которая помечается для эскадрильи.

Я был бы очень признателен за любые указания относительно наилучшего (самого простого?) способа решения этой проблемы или за любые полезные ресурсы в Интернете, которые могли бы помочь.

 29
Author: Hugo, 2011-08-28

5 answers

Для этого вы можете использовать Ajax. В Drupal 7 теперь есть хорошая поддержка Ajax. В вашем первом списке выбора (город) вам нужно будет добавить информацию Ajax. Затем второй список выбора может быть заполнен на основе информации, содержащейся в первом. Вы также можете даже скрыть второй список выбора, пока не будет выбран вариант в первом, и я немного объясню, как это сделать. Во-первых, чтобы настроить базовую форму:

$form['city'] = array(
  '#type' => 'select',
  '#title' => t('City'),
  '#options' => $options,
  '#ajax' => array(
    'event' => 'change',
    'wrapper' => 'squadron-wrapper',
    'callback' => 'mymodule_ajax_callback',
    'method' => 'replace',
  ),
);
$form['squadron_wrapper'] = array('#prefix' => '<div class="squadron-wrapper">', '#suffix' => '</div>');
$form['squadron_wrapper']['squadron'] = array(
  '#type' => 'select',
  '#title' => t('Squadron'),
  '#options' => $squadron_options,
);

Это всего лишь базовая настройка элементов. Теперь вам понадобится способ определите, какие варианты должны быть в эскадрилье. Сначала вам нужно сделать свой обратный вызов Ajax, указанный в списке выбора "город". В большинстве случаев вы можете просто вернуть элемент, который обертывает элемент ajax, в данном случае $form.

function mymodule_ajax_callback($form, $form_state) {
  return $form;
}

Теперь, когда список выбора "город" изменится, он перестроит часть формы, содержащую оболочку эскадрильи. Ваше значение "город" теперь будет в $form_state["значения"]. Итак, когда форма будет перестроена, нам нужно определить, какие параметры следует предоставить списку выбора на основе значения "город".

// Get the value of the 'city' field.
$city = isset($form_state['values']['city']) ? $form_state['values']['city'] : 'default';
switch ($city) {
  case 'default':
    // Set default options.
    break;
  case 'losangeles':
    // Set up $squadron_options for los angeles.
    break;
}

// If you want to hide the squadron select list until a city is
// selected then you can do another conditional.
if ($city !== 'default') {
  $form['squadron_wrapper']['squadron'] = array(
    '#type' => 'select',
    '#title' => t('Squadron'),
    '#options' => $squadron_options,
  );
}
 27
Author: jordojuice, 2011-08-28 11:53:04

Большое спасибо jordojuice выше. С его помощью мне удалось найти решение. Я также ссылался на пример в http://public-action.org/content/drupal-7-form-api-dependent-lists-and-ajax-form-submission. В конце концов я использовал приведенный ниже код, который работал в пользовательском модуле. По какой-то причине я не смог найти ни одного из своих значений в значениях $form_state, но смог найти их в $form. Наконец, когда я тестировал, я получал сообщение об ошибке о том, что Drupal обнаружил незаконный выбор в раскрывающемся списке. Я обошел это, прокомментировав строку 1290 в форме.inc:

form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));

Окончательный код, который я использовал, был:

<?php

function sappers_squadron_form_work_history_node_form_alter(&$form, &$form_state) {     
        //echo '<pre>';
        //print_r ($form);
        //echo '</pre>';

        $squadron_options = array();

        if(isset($form['field_wkhist_city']['und']['#default_value'][0])) {
            $city = $form['field_wkhist_city']['und']['#default_value'][0];
        }
        else {
            $city = 0;
        }

        $squadron_options = sappers_squadron_squadrons($city);

        $form['field_wkhist_city']['und']['#ajax'] = array(
            'event' => 'change',
            'wrapper' => 'squadron-wrapper',
            'callback' => 'sappers_squadron_ajax_callback',
            'method' => 'replace',
        );

        $form['field_squadron']['und']['#prefix'] = '<div id="squadron-wrapper">';
        $form['field_squadron']['und']['#suffix'] = '</div>';
        $form['field_squadron']['und']['#options'] = $squadron_options;
}


function sappers_squadron_ajax_callback($form, $form_state) {   
    $city = $form['field_wkhist_city']['und']['#value'];

    $form['field_squadron']['und']['#options'] = sappers_squadron_squadrons($city);

    return $form['field_squadron'];
}


function sappers_squadron_squadrons($city) {
    $nodes = array();

    $select = db_query("SELECT node.title AS node_title, node.nid AS nid FROM  {node} node INNER JOIN {taxonomy_index} taxonomy_index ON node.nid = taxonomy_index.nid WHERE (( (node.status = '1') AND (node.type IN  ('squadron')) AND (taxonomy_index.tid = $city) )) ORDER BY node_title ASC");

    $nodes[]="";

    foreach ($select as $node) {
            $nodes[$node->nid] = $node->node_title;
    }

    return $nodes;
}

?>
 11
Author: Ben, 2011-08-29 10:32:27

Поместите строку кода, т.е.
$nodes[''] = '- None -'; после

 $nodes = array();

В уре sappers_squadron_squadrons function и это решит вашу ошибку

form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));

 2
Author: Hacker, 2011-11-23 07:06:00

Обнаружена первопричина "Незаконного выбора. Пожалуйста, свяжитесь с администратором сайта." заключается в том, что пустая строка со значением 0, добавленная $nodes[]="";, недопустима для поля field_squadron.

Смотрите Продвиньте программирование и разработку PHP, но имейте в виду, что флаги DANGEROUS_SKIP_CHECK и validated устарели в D7.

После того, как я удалил эту строку, ошибка исчезла.

 1
Author: Siripong, 2011-12-01 16:30:31

Используйте Ограничение параметра ссылочного поля модуль

Этот модуль позволяет ссылочным полям нескольких типов ограничивать доступные параметры их виджетов значениями других полей в текущей сущности.

 0
Author: Rakesh Nimje, 2016-01-27 09:21:15