Problemas com o envio de um formulário drupal com uma caixa de seleção cujo valor é 0

StackOverflow https://stackoverflow.com/questions/1745869

  •  20-09-2019
  •  | 
  •  

Pergunta

Estou escrevendo um módulo drupal que envolve um formulário com muitas caixas de seleção.Por exemplo.

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

Tornei a chave dessas caixas de seleção numérica, começando com 0.Por exemplo.

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

Ao implementar a função myform_checkboxes_submit, descobri que é difícil interpretar qual foi a entrada do usuário.Na internet, encontrei algumas linhas de código interessantes que faziam o que eu precisava.

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

Isso parece funcionar muito bem;a variável $checked é uma matriz que inclui apenas as caixas de seleção marcadas.O único problema é que o valor 0 (representando a 0ª caixa de seleção) está sempre incluído em $checked, esteja ele realmente marcado ou não.

Também é útil observar:o zero aparece primeiro na lista se estiver marcado, mas por último se não estiver.

Qual seria a melhor forma de resolver esta situação, supondo que alterar a indexação dos checkboxes estivesse fora de cogitação?(Pergunta bônus relacionada:existe uma maneira mais fácil de obter as caixas marcadas do usuário nas variáveis ​​do formulário drupal?)

Foi útil?

Solução

Como o valor retornado por um desmarcado caixa de seleção for 0, não há como reconhecer o estado verificado se você usar 0 como valor de retorno para isso também.Portanto, a resposta imediata à sua pergunta é que não há melhor maneira, simplesmente porque há não maneira (além de uma solução alternativa js sugerida por Jeremy, que seria uma solução bastante complicada para um problema simples).

Portanto, se você precisar que seu array de resultados comece com o índice 0, você terá que se livrar da entrada 0 temporariamente ao construir as opções do formulário, colocando-a novamente após extrair os resultados.Uma maneira fácil de fazer isso seria usar -1 (ou qualquer outro valor não usado no restante do array) como espaço reservado para 0, substituindo-o novamente após extrair os valores verificados.

Outra solução óbvia seria a reindexação, conforme mencionado por Jeremy.Olhando para o seu exemplo, por que você não usa seus valores de exibição (0:00, 1:00, ...) como chaves/valores de retorno também?Não há ambigüidade e é fácil de converter para números inteiros, se necessário.

Outras dicas

Na verdade, o que acabei fazendo foi isso.

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

Ele verifica se 0 está no array, e se não for o primeiro item, então deve ser o último (isso acontece quando o usuário não marca a caixa correspondente a 0).Então ele remove aquele item do array, já que não foi verificado.Não é ideal nem bonito, mas fazia sentido para minha situação.

Na maioria das outras situações (e talvez na minha), como já foi apontado, a reindexação seria melhor.

EDITAR:para quem se importa, esta é a função auxiliar que acabei criando para mim (comentários incluídos).

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;
}

Você poderia usar um manipulador de envio JS para verificar o estado marcado das caixas de seleção e colocar os valores em um campo oculto.

Você precisaria então usar um manipulador de formulário Drupal para decodificar os valores na outra extremidade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top