Oct 062011
 

Post to Twitter Post to Facebook


En el post “Creating a basic form with Drupal 7” vimos cómo crear un formulario sencillo gracias a la API que nos proporciona Drupal.En esta ocasión crearemos un formulario dinámico, es decir responderá a las acciones del usuario añadiendo o quitando campos del formulario todo ello de una forma amigable con el usuario.Para ello usaremos la propiedad #states

Creando el contexto del formulario:

En el post anterior ya creamos un contexto para ubicar un formulario, en este caso haremos lo mismo pero nuestro módulo será “form_example_dynamic” y en el cual definiremos un enlace en el menu navigation para nuestro formulario:

form_example_dynamic.info:


name = Form Example - Creating a Dynamic Form
description = An example of a dynamic form.
package = Pro Drupal Development
core = 7.x
files[] = form_example_dynamic.module

form_example_dynamic.module:

<?php

/**
 * @file
 * An example of how to use new #states Form API element,allowing dynamic forms behavior with very simple setup
 */

/**
 * Implements hook_menu()
 */
function form_example_dynamic_menu(){
 $items['form_example_dynamic'] = array(
 'title' => 'Ejemplo formulario dinámico',
 'page callback' => 'drupal_get_form',
 'page arguments' => array('form_example_dynamic_form'),
 'access callback' => TRUE,
 'type' => MENU_NORMAL_ITEM
 );
 return $items;
}

Definiendo el formulario :

Supongamos que tenemos un site sobre alquiler de salas para celebrar reuniones, conferencias, etc.. Queremos que mediante un formulario podamos recibir las solicitudes de reserva  de nuestros clientes.El formulario debe cumplir los siguientes requisitos:

  1. El cliente pude solicitar tres tipos salas : sala de estudio , sala de conferencias pequeña o sala de reuniones.
  2. En caso de seleccionar la sala de estudio puede elegir si necesita sillas y/o ordenador , indicando a su vez cuantas sillas necesita y/o qué tipo de ordenador.
  3. En caso de elegir la sala de conferencias puede indicar cuántos ordenadores necesita, qué habitación desearía elegir y si desea pagar por reservarla o puede esperar a que quede libre. En el caso de que desee pagar por reservarla podrá indicar el dia y hora en que desa hacer su reserva.
  4. En caso de elegir la sala de reuniones se le permiritirá escribir de forma libre el día , hora y duración.
  5. Independientemente del tipo de sala que escoja se debe permitir que el usuario deje información extra que sea de utilidad para su reserva, para ello se necesita un checkbox que active/desactive la posibilidad de agregar esta información.

Atendiendo a estos requisitos podemos crear nuestro formulario usando el parámetro #states en los casos que necesitemos que se realice alguna accion dependiendo de algun evento :


/**
 * Defines a Form()
 */
function form_example_dynamic_form($form, &$form_state){
 //Radiobutton con las posibles tipos de salas
 $form['room_type'] = array(
 '#type' => 'radios',
 '#options' => drupal_map_assoc(array(t('Habitación de estudio'), t('Sala de conferencias pequeña'), t('Sala de reuniones'))),
 '#title' => t('Qué tipo de habitación necesitas?'),
 );
 //Fieldset con la información adicional de la habitación de estudio.
 $form['study_room'] = array(
 '#type' => 'fieldset',
 '#title' => t('Detalles de la habitación de estudio'),
 '#states' => array(
 //Acción que realizará: se hará visible.
 'visible' => array(
 //Cuando se realizara : room_type = Habitacion de estudio
 ':input[name="room_type"]' => array('value' => t('Habitación de estudio')),
 ),
 ),
 );
 $form['study_room']['equipment'] = array(
 '#type' => 'checkboxes',
 '#title' => t('Detalles de la habitación de estudio'),
 '#options' => drupal_map_assoc(array(t('Sillas'),t('PC'))),
 );
 $form['study_room']['chairs'] = array(
 '#type' => 'textfield',
 '#title' => t('¿Cuántas sillas necesitas?'),
 '#size' => 4,
 '#states' => array(
 'visible' => array(
 ':input[name="equipment[Sillas]"]' => array('checked' => TRUE),
 ),
 ),
 );
 $form['study_room']['pc'] = array(
 '#type' => 'textfield',
 '#title' => t('¿Qué tipo de ordenador necesitas?'),
 '#size' => 15,
 '#states' => array(
 'visible' => array(
 ':input[name="equipment[PC]"]' => array('checked' => TRUE),
 ),
 ),
 );
 // Fieldset para la información adicional sobre la sala de conferencias.
 $form['small_comference_room'] = array(
 '#type' => 'fieldset',
 '#title' => t('Información sobre la sala de conferencias pequeña'),
 '#size' => 15,
 '#states' => array(
 'visible' => array(
 ':input[name="room_type"]' => array('value' => t('Sala de conferencias pequeña')),
 ),
 ),
 );
 $form['small_comference_room']['how_many_pcs'] = array(
 '#type' => 'select',
 '#title' => t('Cuántos PCs necesitas en la sala de conferencias'),
 '#options' => array(
 1 => t('Uno'),
 2 => t('Dos'),
 3 => t('Tres'),
 4 => t('Cuatro'),
 5 => t('Cinco o más'),
 ),
 );
 $form['small_comference_room']['comment'] = array(
 '#type' => 'item',
 '#description' => t('Vaya,esos van a ser bastantes'),
 '#states' => array(
 'visible' => array(
 ':input[name="how_many_pcs"]' => array('value' => '5'),
 ),
 ),
 );
 $form['small_comference_room']['room_name'] = array(
 '#type' => 'textfield',
 '#title' => t('¿Qué habitacion quiere usar? :'),
 );
 $form['small_comference_room']['hours'] = array(
 '#type' => 'select',
 '#options' => drupal_map_assoc(array(t('Free'), t('Paid'))),
 '#title' =>t('¿Quieres reservar la sala cuando este libre (Free) o pagar por uso prioritario (Paid)?'),
 );
 $form['small_comference_room']['hours_writein'] = array(
 '#type' => 'textfield',
 '#size' =>50,
 '#title' =>t('Por favor introduce fecha,hora que te gustaría reservar la sala al igual que la duración.'),
 '#states' => array(
 'visible' => array(
 ':input[name="hours"]' => array('value' => t('Paid')),
 ),
 ),
 );
 $form['small_comference_room']['reminder'] = array(
 '#type' => 'item',
 '#description' =>t('Recuerda introducir la día,hora de comienzo y fin'),
 '#states' => array(
 'visible' => array(
 ':input[name="hours"]' => array('value' => t('Paid')),
 ':input[name="hours_writein"]' => array('filled' => TRUE),
 ),
 ),
 );

 //Fieldset para el caso "Sala de reuniones"

 $form['board_room']= array(
 '#type' => 'item',
 '#title' =>t('Informacion sobre la sala de reuniones'),
 '#states' => array(
 'visible' => array(
 ':input[name="room_type"]' => array('value' => t('Sala de reuniones')),
 ),
 ),
 );
 $form['board_room']["more_info"]= array(
 '#type' => 'textarea',
 '#title' =>t('Por favor introduce fecha,hora que te gustaría reservar la sala al igual que la duración.'),
 );
 $form['board_room']["info_provide"]= array(
 '#type' => 'checkbox',
 '#title' =>t('Has proporcionado la informacion necesaria anteriormente'),
 '#disabled' => TRUE,
 '#states' => array(
 'checked' => array(
 ':input[name="more_info"]' => array('filled' => TRUE),
 ),
 ),
 );

 $form['expand_more_info'] = array(
 '#type' => 'checkbox',
 '#title' => t('Marca si deseas aportar información adicional'),
 );
 //Field set para la información adicional independientemente de la sala elegida.
 $form['more_info'] = array(
 '#type' => 'fieldset',
 '#title' => t('Instrucciones especiales'),
 '#collapsible' => TRUE,
 '#collapsed' => TRUE,
 '#states' => array(
 'expanded' => array(
 ':input[name="expand_more_info"]' => array('checked' => TRUE),
 ),
 ),
 );

 $form['more_info']['feedback'] = array(
 '#type' => 'textarea',
 '#title' => t('Por favor introduzca la informacíon adicional que nos ayude en su petición'),
 );

 $form['submit'] = array(
 '#type' => 'submit',
 '#value' => t('Enviar'),
 );
 return $form;
}

Observe la sintaxis de cómo se ha definido el parámetro #states :


$form['study_room'] = array(
 '#type' => 'fieldset',
 '#title' => t('Detalles de la habitación de estudio'),
 '#states' => array(
 //Acción que realizará: se hará visible.
 'visible' => array(
 //Cuando se realizara : room_type = Habitacion de estudio
 ':input[name="room_type"]' => array('value' => t('Habitación de estudio')),
 ),
 ),
 );

Con todo esto habremos terminado nuestro formulario y podremos comprobar que cumple cada uno de los requisitos especificados:

Captura de pantalla de un ejemplo de formulario avanzado en drupal 7

  14 Responses to “Formularios avanzados en Drupal 7 usando #states”

  1. Muy útil. gracias amigo.

  2. buen documento, muy claro; gracias bacan por tu excelente aporte

  3. bueno la verdad me ha gustado mucho los ejemplos que usted tiene, muy buenos todos, pero quisiera saber si yo quiero consultar la base datos o introducir datos como podria hacerlo

    gracias
    saludos

    • Amigo. Puedes consultar las bases de datos con algo como asi:
      $titulo = db_query(“SELECT item FROM {kmrhuellauno_pregunta} WHERE sid=:nid”, array(‘:nid’=>1) )-> fetchField();

  4. Cordial saludo José Luis y muchas gracias por compartir tus conocimientos. Me identifico con tu filosofía, puesto que yo también soy autodidacta, sin embargo, aún soy un principiante en el mundo de la programación. Sólo cuento con conocimientos básicos en html, css, jquery, php y MySql. También he incursionado en el mundo de los CMS sobre todo en Drupal 7. Actualmente estoy creando algunas sitios usando drupal 7. Me ha llamado mucho la atención el formulario avanzado que has publicado en este blog, porque es justo lo que necesito en este momento. He estado estudiándolo y lo entiendo bien, sin embargo, no sé como implementarlo en el sitio que estoy construyendo. Es decir no sé dónde debo poner el código, si debo usar un tipo de contenido o un bloque o qué debo hacer? Te agradecería infinitamente si pudieras explicarme que debo hacer. Luego yo adaptaría el código a lo que yo necesito que aparezca en el formulario. Gracias!!!

  5. Ya tengo el código ubicado correctamente dentro de una carpeta nueva que creé con el nombre “modulos_creados” la cual ubiqué dentro del direcctorio: sites/all/modules/, sin embargo, el enlace de menú no aparece en el menú navegación, por lo tanto no puedo acceder al formulario.

    Qué debo hacer?

    Agradezco la atención y la colaboración que me puedan prestar.

  6. Tienes que revisar, ya que le cambiaste el nombre al modulo por tanto tienes que cambiar donde te aparezca “form_example_dynamic” por “modulos_creados”.

  7. Buenas noches. Disculpa me base en tu tutorial para el sitio que estoy intentando desarrollar, pero fijate que cuando estoy en la función del validate, o al submit no se como recuperar la información de que opción el usuario selecciono, si me pudieras ayudar con esto te lo agradezco porque no he encontrado solucion para esto. Saludos

  8. Muy bueno tu post. Los campos quedan uno debajo del otro como tendría que hacer para organizarlos de alguna manera, que quede un campo al lado de otro….?

    Saludos

  9. Excellent website. Plenty of useful info here. I am sending it to a few pals ans also sharing in delicious.
    And certainly, thank you in your effort!

  10. Bro. muy buen ejemplo, como yo puedo hacer insert y/o consultas guardando esa info en una tabla..donde puedo bajar los fuentes de ese modulo

  11. Buen tuto, como haria si tuviese un campo que posee expresiones regulares ejemplo un numero telefonico, para validarlo, gracias.

Leave a Reply to Ricardo Cancel reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>