Skip to Content

Redirect aus einem AJAX-Formular

Im normalen Drupal-Alltag kommt es selten vor - aber wenn es doch sein muss, dann hilft nur noch cTools.

Ausgangssituation

Ich habe ein AJAX-Formular (gebaut wie hier beschrieben), welches sich bei Klick auf einen Button vollständig austauscht (das unterscheidet es von anderen Drupal-Formularen (zB: /node/edit), wo nur einzelne Teile AJAX-getrieben sind). Diese Formulare sind extrem praktisch - aber nach einem Submit lässt sich in einem solchen Formular kein Redirect auslösen. 

Problem

Wird ein AJAX-Submit-Button betätigt, ruft javascript per load() Drupal auf und erwartet HTML, welches an gewünschter Stelle (Stichwort 'wrapper'-ID) eingesetzt wird. Ein drupal_goto($url) liefert eine neue Seite, die dann vom javascript im DOM eingesetzt werden würde. Das ist sicher unerwünscht.

Lösung

Der zurückgelieferte HTML-Code muss Informationen enthalten, die einen Wunsch zum Redirect beinhalten.

Das Modul CTools bietet einen solchen Mechanismus.

Die folgende Funktion kann in jedem AJAX-Submit-Callback aufgerufen werden:

/**
 * myform_ajax_redirect()
 *
 * @param $redirect    url
 *
 *  redirect on AJAX-Form is a pain
 *  $form_state['redirect'] = 'admin';  // can not work.
 *  This solution uses ctools (unbelievable) [http://tagmycode.com/snippet/452/d7-ajax-redirection]
 *
 */
function myform_ajax_redirect($redirect) {
  ctools_include('ajax');
  ctools_add_js('ajax-responder');
  $commands = array();
  $commands[] = ctools_ajax_command_redirect($redirect);
  print ajax_render($commands);
  exit;
}
Vereinfacht beschrieben passiert dies:

Javascript wartet (ganz normal) auf Daten, die es im DOM einbauen kann: das ist der HTML-Code und eventuelle js-Settings.

Statt des Formulars wird nun ein cTools-Kommando retourniert (kein HTML-Code und js-Settings, welche die Redirect-URL enthält).

Das ajax-responder.js reagiert auf diese Settings und löst vom Client her den gewünschten Redirect aus. 

Kommentare

So ähnlich hab ich das auch eingesetzt. Leider funktioniert ein Redirect zu einem Anchor nicht. trotzdem Danke.

Hm - sollte eigentlich. Kann es sein, dass du auf einen Anchor der aktuellen URL springen möchtest ?  In dem Fall würde js die Seite nicht neu laden, sondern versuchen dahin zu scrollen.

Ich hab das so gelöst: obige Funktion sichert ein optionales 2. Argument $anchor in $_SESSION[]. Ein hook_init macht (davon Abhängig) ein redirect zu diesem Anchor:

function c_tools_ajax_redirect($redirect, $anchor = NULL) {
  if ($anchor) {
    // loads page again - and jumps to ID -> see c_tools_init()
    $_SESSION['go_anchor'] = $anchor;
  }
  ...
}
 
function mymodule_init() {
  // $_SESSION['go_anchor']  redirects to url#[go_anchor-value]
  if (isset($_SESSION['go_anchor'])) {
    $anchor = $_SESSION['go_anchor'];
    unset($_SESSION['go_anchor']);
    drupal_goto($_GET['q'], array('fragment' => $anchor));
    exit;
  }
}

 

Kommentar hinzufügen

Der Inhalt dieses Feldes wird nicht öffentlich zugänglich angezeigt.
  • Internet- und E-Mail-Adressen werden automatisch umgewandelt.
  • Zulässige HTML-Tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <drupal6>, <java>, <javascript>, <php>. The supported tag styles are: <foo>, [foo]. PHP source code can also be enclosed in <?php ... ?> or <% ... %>.

Weitere Informationen über Formatierungsoptionen

CAPTCHA
Nerd oder Robot ?
_ltrav_olett: