web-dev-qa-db-ja.com

フォームの動的選択リスト(依存ドロップダウン)

Drupal sevenを使用しています。選択リストのオプションを、フォーム内の別の選択リストで選択した値に依存させたいのですが、これは何度も尋ねられたことでしょう。以前は、これを行う方法について明確な答えを見つけるのが困難です。

このフォームは、ユーザーが作業履歴を入力するためのものです。戦隊フィールドタイプへのノード参照である戦隊を選択する必要があり、これはドロップダウンリストにあります。ただし、戦隊は都市のドロップダウンリストに依存しています。ユーザーは最初に都市を選択する必要があり、次にそれは飛行隊のオプションをフィルターします。飛行隊のコンテンツタイプでは、飛行隊にタグ付けされる都市の分類法を作成しました。

これを実行するための最良の方法(最も簡単な方法)についてのアドバイスや、役立つオンラインの役立つリソースについて、私は非常に感謝しています。

29
Ben

Ajaxを使用してこれを実現できます。 Drupal 7はAjaxをサポートしています。最初の選択リスト(市)でAjax情報を追加する必要があります。次に、最初の選択リストの情報に基づいて2番目の選択リストにデータを入力できます。最初のオプションが選択されるまで、2番目の選択リストを非表示にすることもできます。その方法を少し説明します。最初に、基本的なフォームを設定します。

$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 ['values']になります。したがって、フォームが再構築されるとき、「city」の値に基づいて選択リストにどのオプションを与えるかを決定する必要があります。

// 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
jordojuice

上記のjordojuiceに感謝します。彼の助けを借りて、なんとか解決策を見つけました。 http://public-action.org/content/drupal-7-form-api-dependent-lists-and-ajax-form-submission の例も参照しました。私は最終的にカスタムモジュールで動作する以下のコードを使用しました。何らかの理由で、$ form_state値で値を見つけることができませんでしたが、$ formでそれらを見つけることができました。最後に、テストすると、Drupalがドロップダウンで不正な選択を検出したというエラーメッセージが表示されました。form.incの1290行目をコメントアウトすることでこれを回避しました。

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
Ben

コードの行を置く、すなわち
_$nodes[''] = '- None -';_後

_ $nodes = array();
_

ur _sappers_squadron_squadrons function_でエラーが解決します

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

2
Hacker

「不正な選択が検出されました。サイト管理者に連絡してください」の根本的な原因。 $nodes[]="";によって0の値が追加された空の文字列は、field_squadronフィールドでは無効です。

Advance PHP Programming and Development を参照してください。ただし、 DANGEROUS_SKIP_CHECKおよび検証済みフラグはD7では非推奨 であることに注意してください。

その行を削除した後、エラーはなくなりました。

1
Siripong

参照フィールドオプションの制限 モジュールを使用する

このモジュールを使用すると、いくつかのタイプの参照フィールドで、ウィジェットの使用可能なオプションを現在のエンティティの他のフィールドの値によって制限できます。

0
Rakesh Nimje