web-dev-qa-db-ja.com

選択したチェックボックス(分類法)は、選択したボックスの値を新しい選択リストに入力します


*回答済みの質問: データを保存するには、カスタムモジュールのhook_node_submitでヘルプが必要 *


Drupal 7には、カスタムコンテンツタイプがあります。これには、そのコンテンツのカテゴリを選択するための複数選択用語参照があります。

ここで、以前に選択したカテゴリから1つを選択し、何らかの方法で「メイン」カテゴリとしてマークする必要があります。

次のオプションを持つ複数選択用語参照フィールドがあるとします。

_Apples
Bananas
Pears
Oranges
Grapes
Pineapples
_

ユーザーはリンゴ、梨、ブドウを選択します。今私はどちらかが必要です:

  1. プログラムでこれらの選択した項目ごとに別のフィールドを作成し(おそらくAjaxコールバックを使用)、ラジオボタンを使用して、選択した用語の1つだけを選択できるようにします。
  2. チェックされた項目の横に(おそらくAjaxを使用して)ラジオフィールドを作成します。ここで、選択された項目からメインの項目を選択できます。

誰かこれについて何か考えがありますか?

より明確にするために、私は1つのコンテンツタイプにこれらのリストを多数用意しています。各リストを単一の値リストとして繰り返すことはオプションではありません。

私の最善の策は、hook_form_alter()をある種のAJAXコールバックで使用して、ユーザーがチェックしたティックボックスの横に単一のラジオボタンを作成するか、または指定されたリストでチェックされている各項目の新しいラジオフィールドリストをプログラムで作成します。

更新:わかりました、それを行う最善の方法は、ajaxを使用してカスタムモジュールを作成し、チェックされたそれぞれのラジオボタンを作成することです。チェックボックス。メイン要素として使用する要素を選択できます。

したがって、税条件値にアクセスする前にフォームがレンダリングされるのを待つ必要があるので、hook_form_alter()を使用して_#after_build_関数を追加しました。

これが私のモジュールです。私はたくさんのコメントを使用しているので、私が何をしようとしているのかがはっきりしているはずです:

MYMODULE.module

_/**
 * Implementation of HOOK_form_alter()
 * Do the ajax form alteration
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {

  // 1.CONTENT FORM
  // I created a custom content type 'content' and added a term
  // reference to it 
  if($form_id == 'content_node_form') {

    // tax term ref is the main part, so let us
    // remove title and body fields
    unset($form['body']);
    unset($form['title']);

    // do our stuff after the form has been rendered ...
    $form['#after_build'][] = 'MYMODULE_after_build';

  }
}

/**
 * after_build function for content_node_form
 */
function MYMODULE_after_build(&$form, &$form_state) {

    dsm($form);  

    // In the after_build call we can now actually use the 
    // element_children function to grab the values of the fields that
    // don't start with a hash tag #
    // in this test case 1,2,3,4 and 5

    // wrap each of the elements rendered ...
    foreach(element_children($form['field_taxonomy']['und']) as $key) {

      $form['field_taxonomy']['und'][$key] += array(

        // this is added before the element and then replaced by our callback ..
        // we use the $key value in the id so that we know which div to replace 
        // depending on which checkbox is checked ...
        '#prefix' => '<div class="taxonomy_term_wrapper">
                        <div id="callback_replace_'.$key.'">Replace Me ' . $key . '</div>',

        // this is added after the element so we basically wrap around it ..
        '#suffix' => '</div>',

        // add some ajax stuff here ...
        '#ajax' => array(
          // name of the callback function to call upon change
          'callback' => 'MYMODULE_callback',
          // the id of the element that will be replaced
          'wrapper' => 'callback_replace_'.$key,
          // replace the wrapper
          'method' => 'replace',
          // what kind of effect do we want ...
          'effect' => 'fade',
          // show progress on callback
          'progress' => array('type' => 'throbber'),
        ),
      ); 



      if (!empty($form_state['values']['field_taxonomy']['und'][$key])) {
        // the form to show upon change ...
        $form['field_taxonomy']['und']['main_cat'] = array(
          // we want a radio button
          '#type' => 'radio',
          '#title' => t('Test Title'),
          '#description' => t('Test Description ...'),
          '#default_value' => empty($form_state['values']['field_taxonomy']['und'][$key]) ?
                              $form_state['values']['field_taxonomy']['und'][$key] :
                              $form_state['values']['field_taxonomy']['und'][$key],
        );
      }

    }

  return $form;
} 

function MYMODULE_callback($form, $form_state) {
 return $form['field_taxonomy']['und']['main_cat'];
}
_

これは、ボックスをチェックする前の状態です。

This is what it currently looks like prior to checking a box

レンダリングされたフォームのHTMLは次のとおりです。

screenshot

7
tecjam

アイテムをチェックボックスとして作成します。それらが選択された後、これらのアイテムを含むドロップダウンリストを表示するか、別のラジオボタンを使用してプライマリカテゴリを選択します。最初のチェックボックスがオンになるまで、次のコードを使用して2番目のドロップダウンを非表示にできます。

'#states' => array(
'visible' => array(
':input[name="your checkbox"]' => array('checked' => TRUE),
 ),
)

これを非表示にする要素に追加します。これは、チェックボックスがオンの場合にのみ表示されます。

1
ana

2つのリストについて考えてみてください。1つは、1つの選択を取得するタイトル付きのプライマリと、もう1つは複数です。重複を排除するために、2番目のリストまたは選択に対処する必要があります。

0
Ashlar