1

多くのチェックボックスを備えたフォームを含むdrupalモジュールを書いています。例えば

$form['myform_checkboxes'] = array('#type' => 'checkboxes', ...)

これらのチェックボックスのキーを0から始まる数値にしました。例:

$form['myform_checkboxes']['#options'][0] = '0:00';
$form['myform_checkboxes']['#options'][1] = '1:00';

myform_checkboxes_submit関数を実装すると、ユーザーの入力が何であるかを解釈するのが難しいことがわかりました。インターウェブ上で、必要なことを実行するコードのいくつかの素晴らしい行を見つけました。

$checked = array_intersect(
  array_keys($form_state['values']['myform_checkboxes']),
  array_values($form_state['values']['myform_checkboxes'])
);

これはうまくいくようです。$ checked変数は、チェックされたチェックボックスのみを含む配列です。唯一の問題は、値0(0番目のチェックボックスを表す)が、実際にチェックされているかどうかに関係なく、常に$checkedに含まれていることです。

また、注意が必要です。チェックされている場合はゼロがリストの最初に表示され、チェックされていない場合は最後に表示されます。

チェックボックスのインデックスを変更することが問題外であると仮定して、この状況を解決するための最良の方法は何でしょうか?(関連するボーナスの質問:drupalフォーム変数からユーザーのチェックボックスを取得する簡単な方法はありますか?)

4

3 に答える 3

3

チェックされていないチェックボックスによって返される値は0であるため、その戻り値として0を使用すると、チェックされた状態を認識する方法はありません。したがって、あなたの質問に対する直接の答えは、単に方法がないという理由だけで、最善の方法はないということです(Jeremyによって提案されたjsの回避策は別として、単純な問題に対するかなり複雑な解決策になります)。

したがって、結果配列をインデックス0で開始する必要がある場合は、フォームオプションを作成するときに一時的に0エントリを削除し、結果を抽出した後に元に戻す必要があります。これを行う簡単な方法は、-1(または配列の残りの部分で使用されていない他の値)を0のプレースホルダーとして使用し、チェックされた値を抽出した後に再び置き換えることです。

Jeremyが述べたように、もう1つの明らかな解決策はインデックスの再作成です。例を見て、表示値(0:00、1:00、...)をキー/戻り値としても使用してみませんか?あいまいさはなく、必要に応じて整数に簡単に変換できます。

于 2009-11-17T18:10:15.010 に答える
1

実はこれでした。

if (in_array(0, $checked) && $checked[0] != 0) {
  unset($checked[count($checked) - 1]);
}

0が配列にあるかどうかをチェックし、それが最初の項目でない場合は最後でなければなりません(これは、ユーザーが0に対応するボックスをチェックしない場合に発生します)。そのため、チェックされていないため、そのアイテムは配列から削除されます。理想的でもきれいでもありませんが、私の状況には理にかなっています。

他のほとんどの状況(そしておそらく私の場合)では、指摘されているように、インデックスの再作成がより適切です。

編集:気になる人のために、これは私が自分で作成することになったヘルパー関数です(コメントが含まれています)。

function _mymodule_get_checked_checkboxes(&$form_state, $table) {

  // Discover which boxes were checked.
  $checked = array_intersect(array_keys($form_state['values'][$table]),
                          array_values($form_state['values'][$table]));

  // The key '0' is included in the first position if it was selected,
  //  and in the last if it was not.
  //  this is how checkboxes return their data.
  //  However, we don't want 0 to be in the array
  //  therefore, we remove it if 0 is found to be in the last position
  $num_checked = count($checked);
  if ($checked[0] != 0 && $checked[$num_checked - 1] == 0) {
    unset($checked[count($checked) - 1]);
  }
  // It also happens if nothing is selected.
  // In the case that only 0 is selected, assume otherwise.
  else if ($num_checked == 1 && $checked[0] == 0) {
    unset($checked[0]);
  }

  sort($checked);
  return $checked;
}
于 2009-11-17T23:12:44.577 に答える
0

JS送信ハンドラーを使用して、チェックボックスのチェック状態を確認し、値を非表示フィールドに入れることができます。

次に、Drupalフォームハンドラーを使用して、もう一方の端の値をデコードする必要があります。

于 2009-11-17T16:57:49.120 に答える