2

I'm facing a problem with Ajax enabled forms, so this is the scenario. I have 2 blocks, the first one has some buttons and the other one has a form ,constructed using the Form API.

When I click any of the buttons in the first block and AJAX Request is sent to the server, then in my callback function it replaces the second's block form data with new values, for doing this I call the drupal_get_form function, so the code for the callback is more or less like this:

$form = drupal_get_form('panorama_info_form');
print render($form);

And the elements of the form have the following style:

//Text field for title
$form['panorama_titulo'] = array(
        '#type' => 'textfield',
        '#title' => t('Nombre del panorama'),
        '#default_value' => $panorama['titulo'],
        '#description' => t('Nombre del panorama'),
        '#size' => 40,
        '#maxlenght' => 120,
        '#required' => TRUE,
        '#prefix' => '<div id="panorama_titulo_div">',
        '#suffix' => '</div>',
        '#ajax' => array(
          'callback' => 'panorama_info_form_callback',
          'wrapper' => 'panorama_titulo_div',
          'method'  => 'replace',
          'effect' => 'fade',),);

Now, in my jQuery Http 200 success function I replace the old form with the response data like this:

function reload_element(data){
    $("#panorama-info-form").replaceWith(data);

}

where data is the rendered form.

This works, and I can see my form with the new default values that I declared, however after the form is replaced, ajax is no longer triggered by events. What I mean is that before I replaced the form with jQuery, it used to work, the value was sent to the server and the callback function declared for the textfield was in fact getting called. However after the replacement, no more ajax request... Why is this happening??? I guess that's because there's some kind of script that uses the form's element's classes to attach functions dynamically to it... Maybe that could be one reason. How could I fix this??? Thanks a lot.

1 Answer 1

2

You don't post the code performing the actual AJAX request, so I have to assume it's directly calling an URL returning just the rendered version of the textfield wrapper with id "panorama_titulo_div".

Since this is sort of side-stepping Drupal's own AJAX functionality (which operates on a per-form basis, initiated by the "#ajax" key being present on certain elements), you'll need to perform some steps manually.

First you need to tell elements in the form that they are about to be removed using Drupal.detachBehaviors($('#panorama_titulo_div').get(0), Drupal.settings, 'unload');

Then you replace the form like you already do.

Finally, you need to re-attach all the JavaScript behaviors since any script operating on the elements in the replaced form won't have any references to the new elements.

Drupal.attachBehaviors($('#panorama_titulo_div').get(0)); This is where Drupal would normally pass the settings received together with other commands returned from an AJAX operation. We don't have that here, and it's not that important since we're not adding/removing elements or otherwise alter the DOM structure and won't introduce any new scrips. Just to be sure every behaviors works, Drupal calls Drupal.attachBehaviors() again with the entire form as the context argument. You may want to do that too if you notice some things aren't working. It's a safe operation since all behaviors are required to keep track of whether they're already attached or not (often done using jQuery's .once() method.

4
  • Very well written answer, friend. Welcome to DSO. Commented Jul 10, 2013 at 2:58
  • Thanks! I tried to be as clear as possible, but it's difficult without full code samples.
    – TwoD
    Commented Aug 18, 2013 at 12:43
  • I just got here 8 years later to say that I love you! A million thanks, could not find a good answer anywhere.
    – Lia
    Commented Aug 24, 2021 at 13:09
  • @Lia No problem :) Wish I could have been a bit more detailed or precise in the response but hard to not risk being misleading when the original question doesn't include all context.
    – TwoD
    Commented Aug 25, 2021 at 14:33

Your Answer

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

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