こちらのサイトではDRUPAL10に関連する記事を掲載しています。
はじめに
Drupalはさまざまな方法でAjaxが利用できる仕組みがあります。一番簡単なのはフォームを利用する方法です。この方法は、#AJAX属性にコールバック関数等の情報を設定するだけでフロントエンド側のコード(HTMLやJS)を意識することなくAJAXが利用できます。ただ、フォームを使わない場合は利用できないため、直接JQueryからコールバック関数を呼び出す必要があります。ここでは、フォームを使わないでjQueryのAjaxを使用してコールバック関数にPOSTデータを連携する方法を紹介しています。
AjaxでControllerコールバック関数呼び出す仕組み
準備
- 【ルーティングYMLファイル】ルーティングYMLにページ表示用関数を定義する
- 【ライブラリYMLファイル】ライブラリーYMLに使用するJavascriptを定義する
- 【モジュールYMLファイル】モジュールYMLのHOOOKテーマに、指定したフックテーマIDと使用するTWIGテンプレート情報を設定する
- 【コントローラ】ページ表示用関数内でDRUPAL RENDER APIを使用して以下の設定を行った後に、RENDER情報を返すようにする
– #THEME属性にフックデータIDを設定する
– #ATTACHED属性にライブラリーYMLに定義したJSのIDを設定する - 【TWIGテンプレート】TWIGテンプレートには表示するコンテンツをHTMLで作成する
- 【Javascriptファイル】Javascriptファイルには、jQueryで起動の定義およびAJAXのクライアント側処理を記述する
動作の順序
ページにアクセスされると以下の順序で処理が行われます
- コントローラのページ表示用関数が呼び出される
- TWIGテンプレートに設定したHTMLコンテンツが表示される
- クライアントのAJAXが呼び出されるとデータをPOSTでコールバック関数に送信する
- コントローラのコールバック関数がPOSTデータを受信して処理をした後にJSONでクライアントにデータを送信する
- クライアント側はAJAXで受信に成功した場合、失敗した場合で、それぞれの処理をする
実装
ライブラリ登録
JSを使用するためには、クライアント側のhtmlファイルにJavaScriptコードを書くか、JavaScriptのソースコードを記述した別ファイルを埋め込む必要があります。Drupalでは、クライアント側のスクリプトやプログラムもすべて独自のルールにしたがって管理されています。
DrupalでJavascriptプログラムを読み込む場合は、かならずライブラリYAMLファイルに登録する必要があります。テーマを作成する場合とモジュールを作成する場合で多少作法は異なりますが、ライブラリYAMLファイルの登録の方法は同じで以下のようになります。
カスタムモジュール作成の場合は、カスタムモジュールフォルダの直下に存在する{モジュール名}.libraries.ymlファイルに読み込み対象のJSファイルを登録します。
DrupalでjQueryのajaxを使用するため、dependenciesには以下のコアモジュールを設定します。
scraping_module.ajax:
js:
js/ajax.js: {}
dependencies:
- core/jquery
- core/drupal.ajax
- core/drupal.dialog.ajax
JSファイル
Drupalで使用するJSの書き方
DrupalでJSを使用する場合は、必ず以下の構文の中にスクリプトを記述します。この中では通常のJavascriptコマンドはもちろんのことDependenciesに指定したjQueryも使用可能です。
(function($, Drupal){
//ここにJSスクリプト(jQuery利用可能)を記述する
})(jQuery, Drupal);
トリガー
上記で説明したDrupalの構文の中でトリガコマンドを追加します。ここでは、users-prompt-likeクラスがクリックされるとmainfunc関数を呼び出します
$(".users-prompt-like").on('click', { ID: 123, actionmode: "いいね" }, mainfunc);
メイン処理
トリガ関数により呼び出される関数を作成します。この中でAJAX処理関数を呼び出します。
function mainfunc(event){
ここに処理をかく
・
・
// AJAX処理関数を呼び出す
// パラメータはAJAXで送信するデータを渡す
ajax_func(actionmode, actstatus, plugincode, pluginname);
}
AJAX処理
メイン処理から呼び出されるAJAX処理関数を記述します。
function ajax_func(actionmode,actstatus,plugincode,pluginname){
var jsonObjects = {"MODE" : actionmode, "STATUS" : actstatus, "CODE" : plugincode , "NAME" : pluginname};
$.ajax({
url: '/ajax-post-callback',
type: "POST",
data: JSON.stringify(jsonObjects),
dataType: "json",
beforeSend: function (x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("application/json;charset=UTF-8");
}
},
success: function (result) {
var from_json = JSON.parse(result);
if(from_json['ERRMESSAGE'] != '') {
//エラーメッセージを表示する
alert(from_json['ERRMESSAGE']);
}else {
alert("AJAX通信に成功しました");
}
console.log(result);
},
error: function (result) {
alert("AJAX通信に失敗しました");
console.log(result);
}
});
}
コントローラ(PHP)
ページ表示
AJAXを使用するページで、先に登録したライブラリのJSファイルを呼び出すために、レンダーAPIに#attached属性、#library属性を追加して、先に登録したライブラリのコードを指定します。
public function index(){
$output = [];
$output['guidance'] = [
'#theme' => 'scraping_module_tile',
'#listoftemplates' => $this->_getPluginListArray(),
'#listofmytemplates' => $promptlist,
'#attributes' => [
'class' => ['my-marquee-element'],
'direction' => 'right',
],
];
//CSS
$output['guidance']['#attached']['library'][] = 'scraping_module/scraping_module.gridlayout';
//JS
$output['guidance']['#attached']['library'][] = 'scraping_module/scraping_module.ajax';
return $output;
}
コールバック関数
コールバック関数は、Javascript側から直接呼び出されるバックエンド側の関数(エンドポイントを指定)のことです。Drupalで用意されたサービスAPIを使用して、URLパラメータのパース処理やJSONのデコードおよびエンコード処理が可能です。
public function ajax_post_callback(Request $request) {
$json_string = \Drupal::request()->getContent();
//JSONを配列にデコードする
$decoded = \Drupal\Component\Serialization\Json::decode($json_string);
・
・
(ここで処理関数を実行する)
$ret に処理の判定結果を返す
//結果を配列に設定する
if($ret == 0) {
$decoded['ERRMESSAGE'] = "";
}else{
$decoded['ERRMESSAGE'] = "AJAXコールバック関数内でエラーが発生しました";
}
//配列をJSONにエンコードする
$json_string = \Drupal\Component\Serialization\Json::encode($decoded);
return new JsonResponse($json_string);
}
この記事またはDrupalに関するご質問がございましたら、お気軽にお問い合わせください。