Próximo post

Como aumentar o limite de memória do PHP na linha de comando do Mac

Leia mais»
x
jan 05 2012

Criando campos condicionais no Drupal 7

Você já teve que criar um campo condicional em algum formulário do Drupal, que so aparecesse caso outra função fosse selecionada? Por exemplo: O campo "Quantos filhos você tem" somente irá aparecer se o usuário escolher "Sim" para o campo "Tem Filhos".

Tive este necessidade em um projeto recente e já tinha implementado uma solução com um javascript customizado no #after_build do formulário. Aposto que esta é a maneira mais comum de obter este comportamento!

Não faça isto!

Apesar de não haver nada errado com a solução descrita acima, há uma maneira bem melhor de conseguir isto usando funcionalidades nativas do Drupal e escrevendo bem menos código.

Para isto, usamos o #states, introduzido no Drupal 7.

O formulário até então era este:

1
2
3
4
56
7
8
9
$form['temfilhos'] = array(
  '#type' => 'checkbox',
  '#title' => t('Do you have children?'),
);
 $form['numfilhos'] = array(
  '#type' => 'textfield',
  '#title' => t('How many?'),
);

O pulo do gato é utilizar o novo tipo "container" para criar um container para os nossos elementos condicionais e controlar a sua visibilidade através do #states:

1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
$form['temfilhos'] = array(
  '#type' => 'checkbox',
  '#title' => t('Do you have children?'),
);
 $form['filhos_container'] = array(
  '#type' => 'container',
  '#states' => array(
    'invisible' => array(
      'input[name="temfilhos"]' => array('checked' =>FALSE),    ),
  ),
);
 
$form['filhos_container']['numfilhos'] = array(  '#type' => 'textfield',
  '#title' => t('How many?'),
);

Explicação

Através do #states, definimos um estado invisível para o container, que ocorre quando o valor do atributo "checked" do input especificado no seletor é falso. Pode parecer um pouco confuso pois misturamos um seletor de jQuery no PHP, mas esta é a maneira como o Drupal consegue bindar o evento de javascript automaticamente. Na dúvida, simplesmente troque a parte name="temfilhos" pelo attributo "name" do seu campo!

Para saber mais sobre states e como utilizá-los, leia sobre drupal_process_states().

Pronto!

Só isso? É, só isto! :) Não foi preciso de uma linha sequer de javascript e muito menos de criar e usar um callback #after_build.

Espero que tenha curtido a dica!

[]s

Se curtiu este post, por favor tome alguns segundos para compartilhá-lo usando os links do lado esquerdo! Valeu!!!