Formularis dinàmics (Part II)

dt., 01/12/2015 - 13:33 - Joan Alsina Morillo

En l’article anterior vam parlar del mòdul Field Conditional States, que ens permet habilitar/inhabilitar, fer obligatori/opcional i/o fer visible/invisible camps d’un formulari a partir del contingut d’altres camps del mateix formulari. Però, què passa si volem emplenar amb un valor concret un camp a partir d’informació d’un altre?  

A continuació expliquem un cas en el que se’ns va demanar que un camp de text s’auto-emplenés amb un valor concret si l’usuari marcava un checkbox amb l'intenció de normalitzar el contingut. Com s’observa a l’animació de sota, al marcar el checkbox ‘Patch directe’ es deshabilita el camp ‘Roseta’ i s’auto-emplena amb la paraula ‘Directe’.

Com que Drupal 7 permet l’ús d’Ajax, vam decidir crear per codi un camp del tipus checkbox amb una crida a una funció que, al modificar el valor d’aquest camp, recarrega una part del formulari. Aprofitant que el hook_form_FORM_ID_alter ens permet modificar un formulari a partir del seu identificador, vam implementar el següent codi:

//Creació al formulari del camp checkbox amb crida Ajax
$form['direct_patch'] = array(
 '#type' => 'checkbox',
 '#title' => t('Direct patch'),
 '#prefix' => '<div class="publish_checkbox"',
 '#suffix' => '</div>',
 '#ajax' => array(
     'callback' => 'ajax_field_socket_callback', //Crida Ajax a funció 
     'wrapper' => 'edit-field-socket'), //embolcall del camp a modificar
);

A més, vam crear la funció per a la crida d'Ajax que recarrega la part del formulari que ens interessa. 

//Crida Ajax del camp 'direct_patch'
function ajax_field_socket_callback($form, $form_state) {
 //Tornem a carregar el camp que volem modificar ('field_socket')
 return $form['field_socket'];
}

Un cop ja teníem creat el camp que ens activa els canvis dinàmics al formulari, vam haver d’adaptar el camp ‘Roseta’, creat per interfície, utilitzant novament el hook_form_FORM_ID_alter. A continuació vam afegir l’embolcall que utilitzem a la crida d’Ajax.

//Creació de l'embolcall al camp a modificar ('field_socket')
 $form['field_socket']['#prefix'] = '<div id="edit-field-socket">';
 $form['field_socket']['#suffix'] = '</div>'; 

Un cop relacionats els dos camps, comprovem que el camp creat per codi ‘Patch directe’ tingui valor i modifiquem el valor per defecte del camp ‘Roseta’, a més de deshabilitar-lo. 

//Si el camp creat per codi ('direct_patch') té valor
if (!empty($form_state['values']['direct_patch'])){
 $form['field_socket']['#disabled'] = TRUE; //Deshabilitem el camp desitjat
 $form['field_socket'][LANGUAGE_NONE][0]['value']['#default_value'] = t('Direct'); //Auto-emplenem el valor del camp
}
if(isset($form_state['values']['direct_patch'])&&$form_state['values']['direct_patch']==0){
 $form['field_socket']['#disabled'] = FALSE;
}

Per tancar aquesta sèrie d'articles i a mode de resum, mostrem el codi que vam implementar per a complir amb la funcionalitat desitjada. 

function MY_MODULE_form_FORM_ID_alter(&$form, &$form_state){ 
//Creació al formulari del camp checkbox amb crida Ajax
 $form['direct_patch'] = array(
  '#type' => 'checkbox',
  '#title' => t('Direct patch'),
  '#prefix' => '<div class="publish_checkbox"',
  '#suffix' => '</div>',
  '#ajax' => array(
      'callback' => 'ajax_field_socket_callback', //Crida Ajax a funció 
      'wrapper' => 'edit-field-socket'), //embolcall del camp a modificar
 );

 //Creació de l'embolcall al camp a modificar ('field_socket')
 $form['field_socket']['#prefix'] = '<div id="edit-field-socket">';
 $form['field_socket']['#suffix'] = '</div>'; 

 //Actualitzem dinàmicament el camp a modificar ('field_socket')
 //Si el camp creat per codi ('direct_patch') té valor
 if (!empty($form_state['values']['direct_patch'])){
  $form['field_socket']['#disabled'] = TRUE; //Deshabilitem el camp desitjat
  $form['field_socket'][LANGUAGE_NONE][0]['value']['#default_value'] = t('Direct'); //Auto-emplenem el valor del camp
 }
 if(isset($form_state['values']['direct_patch'])&&$form_state['values']['direct_patch']==0){
  $form['field_socket']['#disabled'] = FALSE;
 }
}

//Crida Ajax del camp 'direct_patch'
function ajax_field_socket_callback($form, $form_state) {
 //Tornem a carregar el camp que volem modificar ('field_socket')
 return $form['field_socket'];
}