1

My problem has to do with Ajax commands and the form being rebuilt after calling ajax_command_append().

I have a form with two elements an option and a textfield. These are built-in with the form on page load. Then, in an Ajax callback function I add two other fields, i.e. another textfield and a text area.

The form runs and rebuilds perfectly fine, but when I try to read the values typed in or stored-from-beginning, nothing happens except that only the values for the first two fields that were originally built-in with the form are displayed.

I think the problem is either 1) I am not rebuilding the (same?) form properly, or 2) I am not calling the elements/fields properly when reading values.

Any hints will be greatly appreciated

Here is a simplified version of the test code I gathered from various examples:

function module_form($form, &$form_state) {
$form = array();
 $form['changethis'] = array(
 '#type' => 'select',
 '#options' => array(
  'one' => 'one',
  'two' => 'two',
  'three' => 'three',
  ),
   '#ajax' => array(
     'callback' => 'ajax_example_simplest_callback',
     'wrapper' => 'replace_textfield_div',
     'method' => 'replace',
     'effect' => 'fade',      
    ),
  );
  $form['replace_textfield'] = array(
    '#type' => 'textfield',
    '#title' => t("The default value will be changed"),
    '#description' => t("Say something about why you chose") . "'" .     (!empty($form_state['values']['changethis']) ? $form_state['values']['changethis'] :     t("Not changed yet")) . "'",
    '#prefix' => '<div id="replace_textfield_div">',
    '#suffix' => '</div>',
   );
 $form['box'] = array(
   '#type' => 'markup',
   '#prefix' => '<div id="box">',
   '#suffix' => '</div>',
   '#markup' => '<h1>Initial markup for box</h1>',
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#ajax' => array(
      'callback' => 'ajax_example_submit_driven_callback',
      'wrapper' => 'box',
     ),
    '#executes_submit_callback' => TRUE,
    '#value' => t('Submit'),

   );
  return $form;
}



function ajax_example_simplest_callback($form, $form_state) {

   $commands = array(); 

   $commands[] = ajax_command_append(NULL, '<div id=replace_textfield_div><input name=replace_textfielddd id=replace_textfielddd value=79898>test data</input></div><br>');

  $commands[] = ajax_command_append(NULL, '<br><textarea rows=4 cols=30 name=replace_textarea id=replace_textarea>Changethis value: '. $form_state['values']['changethis'] .'</textarea>');
  $page = array('#type' => 'ajax', '#commands' => $commands);

  ajax_deliver($page);

  //print ajax_render($commands);       // not helping 
  //drupal_exit();

 // return $form['replace_textfield'];  // not helping 
 }




function ajax_example_submit_driven_callback($form, $form_state) {
   $form_state['rebuild'] = true;  // not helping 
   $element = $form['box'];
   $element['#markup'] = "Clicked submit ({$form_state['values']['op']}): " .  $form_state['values']['replace_textfield']. " - ".  $form_state['values']['replace_textfielddd'] ." -.";
   return $element;
}

Thanks

EDIT

I also tried calling this function from the inside of command: function display_my_form(){

 $form = drupal_get_form('CPR_Calculator_form');

 $form['replace_textfielddd'] = array(
    '#type' => 'textfield',
    '#title' => t("bye"),
    '#description' => t("ummm"),
    '#prefix' => '<div id="replace_textfield_divvv">',
    '#suffix' => '</div>',
  );
  $display = '<div id="replace_textfield_divvv">';
  $display .= render($form);
  $display .= '</div>';

  return $display;
}

and then in the callback I replaced the ajax_command_append() with this line:

$commands[] = ajax_command_replace(NULL, display_my_form());

2 Answers 2

1

You need to build conditional elements in the form definition (mymodule_form) and not in the ajax callback. When the form is rebuilt using ajax, $form_state['values'] will be set, whereas it's not set on the initial form build.

Here is an example:

function mymodule_form($form, &$form_state)
{
  if(isset($form_state['values'])
  {
    // put your conditional form elements here
  }
}
0

Drupal will ignore any form data from elements not created with Form API, so you cannot expect elements created like this to work:

$commands[] = ajax_command_append(NULL, '<br><textarea rows=4 cols=30 name=replace_textarea id=replace_textarea>Changethis value: '. $form_state['values']['changethis'] .'</textarea>');

You should create element using $form array instead, and then use callback function to return changed area of your form. See Form API example in Examples for Developers for correct way.

6
  • Many thanks, but when I try to add elements to the '$form'using a function and calling the function in the command, the same problem persists. the function I have is:'$form['replace_textfielddd'] = array( '#type' => 'textfield', '#prefix' => '<div id="replace_textfield_divvv">', '#suffix' => '</div>', ); $display = '<div id="replace_textfield_divvv">'; $display .= render($form); $display .= '</div>'; return $display;'
    – ati
    Sep 26, 2014 at 12:55
  • @ati you should create elements in form building function, using 'triggering_element' to know what to create. well, that's the most stable way for me so far
    – Mołot
    Sep 26, 2014 at 12:56
  • Thanks, but the problem is that my form is so dynamic that its elements depends on what the user inputs. With triggering_element I'd have to define my element at the beginning, no?
    – ati
    Sep 26, 2014 at 13:00
  • @ati your form building function is called every time AJAX needs it. I succesfully built form that creates fields based on "tags" in user input, and then creates configuration elements based on other configurations for each tag... Doable. And "already tried" code belongs to your question. Not to a comment.
    – Mołot
    Sep 26, 2014 at 13:05
  • Thanks for that, did you use triggering_element? I am not familiar with triggering_element. Ok, I am editing the question with more details. May be you could spot what I am missing in the function...
    – ati
    Sep 26, 2014 at 13:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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