【Drupal】コントローラにAJAXコールバック関数を作成してJSからPOST送信する
![【Drupal】コントローラにAJAXコールバック関数を作成してJSからPOST送信する](/sites/default/files/styles/wide/public/2024-02/drupal10_28.png?itok=zcY2S6yn)
はじめに
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);
}
この記事に関するご質問やご意見などございましたらお問い合わせフォームからお気軽にご連絡ください。