ダイアログとして開かれた対話グリッド上で選択した列を引数にして、プロセスを実行したいという相談がありました。
元々は対話グリッドは別のページに作成し、それをモーダル・ダイアログとして開こうとしていたのですが、(できなくはないが)それだと実装が難しくなります。
代わりにインライン・ダイアログで実装してみました。Always FreeのAutonomous Databaseで動くAPEX 21.2上で、アプリケーションを作成しています。
作成したアプリケーションは、以下のような動作をします。
最初は対話グリッド上で選択した行に含まれる従業員名を、直接ページ・アイテムに設定します。その後、対話グリッド上では従業員番号を取り出し、サーバー側に送信して従業員名に変換した上でページ・アイテムに設定します。
アプリケーションで作成するデータは、サンプル・データセットのEMP/DEPTに含まれる表EMPを使用します。
アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前はプロセス呼び出しとします。アプリケーションはホーム・ページに実装します。
Bodyに静的コンテンツのリージョン従業員を作成します。
対話グリッド上で行を選択したときに実行される、動的アクションの作成を行います。
対話グリッド上で選択した、従業員の名前を保持するページ・アイテムの作成を行います。
識別の名前をP1_ENAME、タイプはテキスト・フィールド、ラベルは従業員名とします。
従業員を選択するために使用する、対話グリッドのリージョンの作成を行います。
識別のタイトルを従業員選択、タイプを対話グリッド、ソースの表名としてEMPを指定します。外観のテンプレートにInline Dialogを選択します。
行を選択するために使用するので、Attributesの編集の有効はOFFにします。
インライン・ダイアログである従業員選択のリージョンを開く、ボタンの作成を行います。
識別のボタン名はB_SELECT、ラベルは従業員選択、動作のアクションとして動的アクションで定義を選択します。
ボタンに、動的アクションの作成を行います。
識別の名前を従業員選択をクリックとします。タイミングのイベントはクリック、選択タイプはボタン、ボタンはB_SELECTとなります。
TRUEアクションの識別はリージョンを開く、影響を受ける要素は、選択タイプがリージョン、リージョンは従業員選択とします。これで、ボタンを押すと対話グリッドが開きます。
識別の名前を従業員の選択とします。タイミングのイベントは選択の変更[対話グリッド]、選択タイプはリージョン、リージョンは従業員選択とします。
最初は、従業員名を直接、ページ・アイテムP1_ENAMEに設定します。
TRUEアクションの識別のアクションに値の設定を選択します。設定のタイプの設定にJavaScript Expression、JavaScript式に以下を指定します。
this.data.selectedRecords[0][1]
選択される行は複数可であるため配列ですが、今回は常に1行です。そのため、最初の引数は常に0、次の引数は列ENAMEの位置を表す1になります。(位置ではなく列名を指定したいときはmodelインターフェースを介す必要があります。こちらの記事では対話グリッドのmodelインターフェースを使用しています。)影響を受ける要素の選択タイプはアイテム、アイテムはP1_ENAMEになります。実行オプションの初期化時に実行はOFF、クライアント側の条件のタイプはJavaScript式、JavaScript式として以下を記述します。
this.data.selectedRecords.length > 0
行が選択されているときに限定して、値の設定(つまりP1_ENAMEへの値の設定)が実行されます。
対話グリッドのAttributesの外観の最初の行の選択はOFFにします。この設定がONの場合、対話グリッドを開いた時点で最初の行が選択されます。その時点で対話グリッドのイベント選択の変更[対話グリッド]が発火し、動的アクション行の選択が実行されてしまいます。
値の設定を行った後に、対話グリッドのリージョンを閉じます。
TRUEアクションを作成し、識別のアクションとしてリージョンを閉じるを選択します。影響を受ける要素の選択タイプはリージョン、リージョンは従業員選択を選びます。クライアントの条件は、値の設定と同じく、タイプがJavaScript式、JavaScript式は以下になります。
this.data.selectedRecords.length > 0
これから、今回の目的であるサーバー側のプロセスを呼び出す実装を行います。
Ajaxコールバックとして、プロセスget_enameを作成します。引数x01として従業員番号を受け取り、それより従業員名を検索します。結果をJSONフォーマットで呼び出し元に返します。
declare
l_response varchar2(4000);
begin
select json_object(ename) into l_response
from emp
where empno = apex_application.g_x01;
htp.p(l_response);
apex_debug.info(l_response);
exception
when others then
htp.p('{}');
end;
呼び出し側を変更します。
TRUEアクションの値の設定を、JavaScriptコードの実行に変更します。設定のコードでは、先ほど作成したAjaxコールバックget_enameを呼び出すコードを記述します。
apex.server.process(
"get_ename" // Simple Echoback writen in PL/SQL is called, running inside DB server.
, {
x01: this.data.selectedRecords[0][0] // The argument on the browser passed to the server process.
}
,{
success: function( data )
{
apex.items.P1_ENAME.setValue(data.ENAME);
},
error: function ( jqXHR, textStatus, errorThrown )
{
// do something here
}
}
);
以上で、アプリケーションは完成です。アプリケーションを実行すると、記事の最初のGIF動画の動作をします。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完