Проблемы с отправкой формы drupal с флажком, значение которого равно 0 - PullRequest
1 голос
/ 17 ноября 2009

Я пишу модуль 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-й флажок) всегда включается в $ флажок, независимо от того, был ли он проверен или нет.

Также полезно отметить: ноль появляется первым в списке, если он был отмечен, но последним, если это не так.

Как лучше всего разрешить эту ситуацию, если предположить, что об изменении индексации флажков не может быть и речи? (Связанный бонусный вопрос: есть ли более простой способ получить флажки пользователя из переменных формы drupal?)

Ответы [ 3 ]

3 голосов
/ 17 ноября 2009

Поскольку значение, возвращаемое флажком unchecked , равно 0, невозможно определить проверенное состояние, если для этого также используется 0 в качестве возвращаемого значения. Таким образом, немедленный ответ на ваш вопрос заключается в том, что не существует лучший способ, просто потому, что существует нет (кроме обходного пути js, предложенного Джереми, который был бы довольно сложным). решение простой проблемы).

Таким образом, если вам нужно, чтобы ваш массив результатов начинался с индекса 0, вам придется временно избавиться от записи 0 при построении параметров формы, а затем вернуть ее после извлечения результатов. Простой способ сделать это - использовать -1 (или любое другое значение, не используемое в остальной части массива) в качестве заполнителя для 0, заменяя его снова после извлечения проверенных значений.

Другим очевидным решением будет переиндексация, как упоминал Джереми. Глядя на ваш пример, почему бы вам просто не использовать отображаемые значения (0:00, 1:00, ...) в качестве ключей / возвращаемых значений? Там нет двусмысленности, и легко конвертировать в целые числа, если это будет необходимо.

1 голос
/ 18 ноября 2009

На самом деле, я закончил тем, что сделал.

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;
}
0 голосов
/ 17 ноября 2009

Вы можете использовать обработчик отправки JS, чтобы проверить состояние флажков и поместить значения в скрытое поле.

Затем вам потребуется использовать обработчик форм Drupal для декодирования значений на другом конце.

...