web-dev-qa-db-ja.com

Drupal FAPIは複数のAJAXコールバックをサポートしていますか?

FAPIのAJAX プロパティを使用して、ノードを非同期に保存しています。関連する AJAXコールバック が呼び出されると、それぞれ$ formおよび$ form_stateパラメーターが渡されます。次に、AJAXコールバックと_oilからdrupal_render($form)を呼び出すだけで、ノード編集ページが非同期に更新されます。これはうまく機能します。

私が抱えている問題は、フォームを置き換えるだけですが、ページのタイトルも置き換えることです。ページタイトルはノード編集フォームの一部ではありません。したがって、編集フォームのノードタイトルを変更できますが、フォームを保存して更新すると、ページタイトルが古くなります(注:編集したタイトルはデータベースに保存されます)。 AJAXコールバックはフォームのコンテンツしか認識しないため、(つまり、ラッパーを本体に向けて変更することにより)DOM階層の上位にある要素をターゲットにすることはできません。

drupal_render($form)はうまく機能しますが、どこに wrapper を指すかを指定すると、本文(またはその近くのどこか)とページ全体をレンダリングします。これにより、意図しない結果(特定のレンダリング手順のスキップ、不完全なDOMデータなど)が発生する可能性があります。そのため、フォーム送信アクションに2番目のAJAXコールバックを追加することを考えました:フォーム自体を処理するためのコールバック、ページタイトルを処理するための別のAJAXコールバック。複数のコールバックが可能かどうか知っていますか?FAPIのAJAXを使用して2つの個別の wrappers をターゲットにする方法を考えられますか?パスが(コールバックの代わりに)プロパティは私の問題の解決策を提供しますか?パスが機能する場合は、短い例を使用して回答を自由に増やしてください。

Drupalコアでサポートされている機能への回答を制限してください。独自のJavaScriptロジック(ctoolsなど)を使用するサードパーティのモジュールには興味がありません。

サンプルコード:

// Add ajaxified save button in hook_form_FORM_ID_alter (foo_form_node_form_alter).
$form['actions']['ajax_save']['#type'] = 'submit';
$form['actions']['ajax_save']['#access'] = TRUE;
$form['actions']['ajax_save']['#value'] = 'Save';
$form['actions']['ajax_save']['#submit'] = array(0 => 'foo_node_form_submit');
$form['actions']['ajax_save']['#weight'] = 9;

$form['actions']['ajax_save']['#ajax'] = array(
  'wrapper' => $form['#node']->type. '-node-form',
  'callback' => 'foo_ajax_callback',
  'method' => 'replace',
    'effect' => 'fade',
);

...    

function foo_ajax_callback(&$form, &$form_state = null) {

  $commands = array('#type' => 'ajax', '#error' => FALSE, '#commands' => array());
  $output = drupal_render($form);
  $commands['#commands'][] = ajax_command_insert(NULL, $output);
  // Prepend status messages to the node form.
  $commands['#commands'][] = ajax_command_prepend(NULL, theme('status_messages'));
  // Update the title on the page.
  $commands['#commands'][] = ajax_command_insert(NULL, $output);


return $commands;
}
5
amateur barista

はい、コアDrupal AJAX Frameworkで解決できます。すでに$commandsを使用しています。あと1つカスタムコマンドが必要です。

新しいコマンドを提供するJavaScriptコード:

(function ($) {
  Drupal.ajax.prototype.commands.change_title = function(ajax, response, status) {
    // Update the <head><title> element.
    document.title = response.data;

    // Update the page title.
    response.data = response.prefix + response.data;
    this.insert(ajax, response, status);
  }

})(jQuery);

このコマンドを呼び出すPHPコード:

  $commands['#commands'][] = array(
    'command' => 'change_title',
    'method' => 'html',
    // Selector targets Drupal 7's default theme <h1> title (Bartik 7.12).
    'selector' => 'div#branding h1.page-title',
    'data' => check_plain($form_state['node']->title),
    'settings' => NULL,
    'prefix' => '<em>Edit '. node_type_get_name($form_state['node']). '</em> ',
  );

オリジナルのアイデアは here から取得されます。

6
kalabro