2

I have a form set up like this:

function mymodule_form_{my_form_id}_alter(&$form, &$form_state, $form_id) {
    $form['actions']['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Save',
        '#ajax' => array(
            'wrapper' => 'ajax-node',
            'method' => 'replace',
            'callback' => 'mymodule_callback',
            'effect' => 'fade'
        ),
        '#submit' => array('node_form_submit'),
    );          
}

And then the callback:

function ajax_complaint_save_callback($form, &$form_state) {
    $nid = $form_state['build_info']['args'][0]->nid;
    $node = node_load($nid);

    return drupal_render(node_view($node));
}

Now this does work sort of, but the node is not rendered correctly. I have some more AJAX stuff on the same page which uses the ajax links api and that produces the node forms correctly. Here are some pictures to demonstrate.

In this picture, one of the links in the table was clicked and the stuff circled with blue was loaded using the links api - this is how it should look.

With links api

But if go to the edit tab on the loaded node (which is also loaded up through the ajax links api) then press the save button, I get this:

with form api

There's more to this picture, but this is loaded in the same div as the other stuff was - but it seems like it is missing style information, and also the view/edit tabs are missing.

How do I make it load up the node form properly?

  • The JS and CSS are loaded in the continer (form) page? If not, this is your problem. You need to load the JS and CSS in the form page (with the right selectors) and thenit should work – rreiss May 15 '14 at 5:22
  • Try to use ajax_render to render the node – inizio May 15 '14 at 6:16
0

I ended up loading the form with tabs in to my ajax-node div using the links api, but then within the form I made the submit button replace the form container.

My full solution:

/* Drupal caches all ids of form elements and when ajax request happen, this
 * results in the new form have id's appended with --2 --3 etc, so css breaks.
 * Unsetting this makes the ids always the same. Maybe hook_init is not the best
 * place for this, but for now it works.
 */
function mymodule_init() {
    if(isset($_POST['ajax_html_ids'])) {
        unset($_POST['ajax_html_ids']);
    }
}

function mymodule_form_{my_form_id}_alter(&$form, &$form_state, $form_id) {    
    //only do the do if this is and ajax request   
    if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
        $form['actions']['submit'] = array(
            '#type' => 'submit',
            '#value' => 'Save',
            '#ajax' => array(
                'wrapper' => 'my_form_id',
                'method' => 'replace',
                'callback' => 'mymodule_callback',
                'effect' => 'fade'
            ),
            '#submit' => array('node_form_submit'),
        );

        /* For some reason this _has_ to be in form_alter. Putting it in a submit
         * callback doesn't work. What this is doing is setting the changed time
         * of the form to be in the future, if we don't do this, when the form is
         * reloaded after a submit, it's not possible to submit the reloaded form
         * because Drupal thinks someone else has edited it (I think it checks
         * the last update time of the node VS this value). This adds a 5min window
         * where changes can still happen. It's not the best solution but I think
         * it will work.
         */        
        $form['changed']['#default_value'] = time() + 300;
    }
}

function mymodule_callback(&$form, &$form_state) {      
    $new_form = drupal_rebuild_form('my_form_id', $form_state, $form);
    $form_html = drupal_render($new_form);

    return $form_html;
}

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.