1

Why do changes don't get saved in $form, or what is it that's overriding it?

I would like to set custom class to multiple fieldsets in an ajax callback function:

if (something) {
  $form['fieldset_01']['#attributes'] = array('class' => array('custom_class'));
  $form['fieldset_02']['#attributes'] = array('class' => array('custom_class'));
}
elseif (somethingelse) {
  $form['fieldset_11']['#attributes'] = array('class' => array('custom_class'));
  $form['fieldset_12']['#attributes'] = array('class' => array('custom_class'));
} 

return $form;

When $form is returned, the element that I have set in this call is rendered fine, with a new CSS class but the elements I have rendered in previous calls have lost this new class, as if they were rendered with default values.

EDIT: my form creation function

function mynode_form($form, &$form_state) {

$nid = $form_state['values']['nid'];

$ajax = array(
'callback' => 'mynode_ajax',
'wrapper' => 'mynode_form',        
'event' => 'change',
'method' => 'replace',
);

$node = node_load($nid);
$title = $node->field_title['und'][0]['value'];              

$form = array();
$form['#prefix'] = '<div id="mynode_form">';
$form['#suffix'] = '</div>';

$form['nid'] = array(
  '#value' => $nid,
  '#type' => 'hidden',
);

$form['fieldset_0'] = array(
  '#type' => 'fieldset',
  '#collapsible' => true,    
  '#title' => 'Fieldset title 0',      
  //'#attributes' => array('class' => array('a', 'b')),
  '#weight' => 1,
);

$form['fieldset_0']['textfield_0'] = array(
  '#type' => 'textfield',
  '#title' => t('Title 0?'),        
  '#ajax' => $ajax,    
);

$form['fieldset_1'] = array(
  '#type' => 'fieldset',
  '#collapsible' => true,    
  '#title' => 'Fieldset title 1',      
  //'#attributes' => array('class' => array('a', 'b')),
  '#weight' => 1,
);

$form['fieldset_1']['textfield_1'] = array(
  '#type' => 'textfield',
  '#title' => t('Title 1?'),        
  '#ajax' => $ajax,    
);

if (isset($form_state['triggering_element']['#name'])){
  $key = $form_state['triggering_element']['#name'];
  switch($key){
    case 'textfield_0':            
      $form['fieldset_0']['#attributes'] = array('class' => array('a', 'b',   'c'));                                    
      $form['fieldset_1']['#attributes'] = array('class' => array('a',   'b'));
    break;    
  }
}
else{
  //only the first time
  $form['fieldset_0']['#attributes'] = array('class' => array('a', 'b'));
  $form['fieldset_1']['#attributes'] = array('class' => array('a', 'b'));
}     
return $form;
}
  • There's syntax errors in this code. – Beebee Jun 12 '13 at 8:38
  • I must have done something, while indenting.. i think it is fixed now. – gregab Jun 12 '13 at 8:46
  • I can't see anything wrong with that code. I hope you're clearing all cache after you change your functions as form arrays sometimes may get cached. Also I'd wrap anything referencing $form_state inside an isset() check to avoid warnings and notices. – Beebee Jun 12 '13 at 9:02
3

AJAX callback function is meant to only tell Drupal what to update. By design all you do in it is for one call only.

Permanent changes needs to be done in main form creation function. I usually see them done in block like that:

if (!empty($form_state['values'])) {
  //here you are supposed to use these values
}
  • I have checked this, but i couldn't find the style changes - class values for certain element. How can i check this? It is not a value.. – gregab Jun 11 '13 at 6:48
  • You need to alter $form array, not $form_state. You need $form_state only to know that ajax was actually called and what element triggered your form building function. – Mołot Jun 11 '13 at 6:51
  • I get form with print drupal_render(drupal_get_form($form_name, $request_id)); and it seems that function for creating that form si getting called only the first time. – gregab Jun 11 '13 at 7:04
  • 1
    Your form function is called everytime before an ajax callback is called. So the condition and the modification of $form should be inside your form function. – Beebee Jun 11 '13 at 9:01
  • 1
    @Molot I am pretty sure. In the same debug session i reach form_name_form function and in ajax call i reach ajax callback function but not form_name_form function. – gregab Jun 11 '13 at 10:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.