【ローコードのSKE】標準部品アドオン開発の紹介

SKEを利用してリポジトリ定義で業務画面を設定で実現します。設定だけで実現できない要件が存在する場合、「アドオン開発」というプログラミングの世界へようこそ。

## アドオンを選ぶ
要件に関わる場所とタイミングに応じてアドオンを選びます。SKEには以下のアドオンがあります。
|場所|アドオン|タイミング|
|-|-|-|
|[各種入力項目](https://github.com/efwGrp/ske/blob/main/help/fds.md)|
||タイトルのアドオン|初期化された時|
||値のアドオン|初期化された時|
||ソースのアドオン|初期化された時|
||タイトル操作のアドオン|クリックされた時|
||入力枠操作のアドオン|変更された時|
|[検索結果](https://github.com/efwGrp/ske/blob/main/help/ths.md)|
||フォーマットのアドオン|検索結果表示時|
|[追加ボタン](https://github.com/efwGrp/ske/blob/main/help/btns.md)
||ボタン処理のアドオン|クリックされた時|
|[CRUD前後](https://github.com/efwGrp/ske/blob/main/help/comm.beforeAfter.md)|
||検索前処理のアドオン|Select SQL実行前|
||検索後処理のアドオン|Select SQL実行後|
||削除前処理のアドオン|Delete SQL実行前|
||削除後処理のアドオン|Delete SQL実行後|
||保存前処理のアドオン|Insert/Update SQL実行前|
||保存後処理のアドオン|Insert/Update SQL実行後|
|[テーブル＆クエリ項目](https://github.com/efwGrp/ske/blob/main/help/comm.fields.md)|
||モード別項目設定値のアドオン|Insert/Update SQLのパラメータ作成時|

## インタフェースを確認
アドオンの開発は、リポジトリ定義画面で関連項目をクリックして開くスクリプト登録ダイアログにて行います。
それぞれのアドオンは場所とタイミングによりインタフェースが微妙に違っています。アドオンのパラメータと戻り値を確認するため、上記一覧のリンク先を閲覧できます。または、その定義場所から開くスクリプト登録ダイアログに記載するサンプルによりも確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/1048854c-b712-4397-ae1f-88147864cf4d.png)

パラメータはよくオブジェクト型または配列型になりますが、どの属性があるかどの値があるか確認したい場合、debug関数を利用して、tomcatコンソール画面に出力できます。上記画像のアドオンなら以下のようにデバッグ可能です。※debugの引数の文字列はコンソール画面で探す場合の目標です。
```js
touchConditionData.debug("***touchConditionData***");
```
## プログラミング
SKEは[EFW(ESCCO Framework)](https://github.com/efwGrp/efw4.X)を利用して開発されています。SKEのアドオンもEFWのイベントjsと同じくサーバサイトjavaScriptで[EFW API](https://github.com/efwGrp/efw4.X/blob/master/README_J.md)のモジュールとクラスを利用できます。ここでイベントjsと違う注意点を説明します。
### サーバ処理
#### DB処理
EFWのDB処理には外だしSQLが推奨されます。SKEの場合リポジトリ定義で開発するので、外だしSQLを利用すると操作の難易度が上がります。SKE専用の「freeSql」方式を推奨します。
「freeSql」方式には、Sqlへのパラメータは「:」で表現します。これは実行時にプリペアドステートメントへ変換されるため、セキュリティ面でのメリットがあります。
```js:検索例
var obj検索用={
    sql:`
        select * from tb1 where field_nm like '%' || :field_nm || '%'
    `,
    field_nm:"検索したい名称"
}
var ary=db.select("skeComm","freeSql",obj検索用).getArray();
```
```js:更新例
var obj更新用={
    sql:`
        update tb1 set field_nm  = :field_nm
        where field_id=:field_id
    `,
    field_id:"検索したい名称"
    field_nm:"検索したい名称"
}
db.change("skeComm","freeSql",obj更新用);
```
#### メール処理
```js:送信例
mail.send("skeMail","freeMail",{
    to:d["メール"],
    cc:"",
    bcc:"",
    mdn:"",
    subject:"請求書："+d["請求番号"],
    body:d["送付先名前1"]+"　"+d["送付先敬称"]+"\n"+d["請求番号"]+"\n"+"よろしくお願いします。",
    attachment:"attach/SEIKYU/"+d["請求番号"]+"/"+d["請求番号"]+".pdf",
});
```

### クライアント処理
アドオン開発ではCSSを調整したりJSPファイルを修正したりなどの操作を推奨しません。どうしても必要な場合、部品開発の[自作画面](https://github.com/efwGrp/ske/blob/main/help/part.myPage.md)、[自作ダイアログ](https://github.com/efwGrp/ske/blob/main/help/part.myDialog.md)をご参考ください。
#### Resultクラスで画面処理
アドオン開発のクライアント処理は、基本的に「result」のパラメータまたは戻り値を利用して、ブラウザ表示を操作することです。この点はEFWイベントjsと類似しています。

#### jQueryセレクタで項目特定
EFWはjQueryのセレクタ式で画面項目を特定します。SKEのリポジトリ定義で作成された項目を特定したい場合同じくセレクタ式が必要です。また、EFW開発と同様に、項目IDが重複する可能性を考慮して、「#id」のような単純な記述方法を避けてください。ID属性にリポジトリ定義IDを含む親タグの下位タグのように記載すれば安全です。
```js
//ラベル
#{defId} #lbl_{itemId}
#{defId}_inputDialog #lbl_{itemId}
#{defId}_selectDialog #lbl_{itemId}
//入力枠
#{defId} #{itemId}
#{defId}_inputDialog #{itemId}
#{defId}_selectDialog #{itemId}
```
#### Result.eval関数の活用
標準部品の各種操作に対して、クライアントjavaScriptのメソッドが設けられています。必要に応じてそれらのメソッドを呼び出したい場合、Result.eval関数を利用できます。
[SKE](https://github.com/efwGrp/ske)説明の部品モデル部分をご確認ください。



## 例
- [自動採番のさまざま](https://qiita.com/changkejun/items/6ebe7d24fd54feac5be3)
- [更新日時の排他処理](https://qiita.com/changkejun/items/532e5a177782937d2842)
- [階層連動ドロップダウン](https://qiita.com/changkejun/items/c3837e00fa42f0381795)
- [選択ダイアログの利用](https://qiita.com/changkejun/items/0cee4173eac17ce7cf98)
- [検索結果の加工](https://qiita.com/changkejun/items/d36c8bbe3c74ceaaddb9)


## 参考：イベントにアドオンの実行順番
### 初期化イベント

<table>
<tr><th>一覧画面</th><th>選択ダイアログ</th></tr>
<tr><td>listPage.jsp</td><td>selectDialog.jsp</td></tr>
<tr><td>Efw("${DefId}_listPage_init")</td><td>Efw("${defId}_selectDialog_init")</td></tr>
<tr><td colspan=2>検索条件項目⇒<font color=red>タイトルのアドオン</font></td></tr>
<tr><td colspan=2>検索条件項目⇒<font color=red>値のアドオン</font></td></tr>
<tr><td colspan=2>検索条件項目（コンボ・ラジオ）⇒<font color=red>ソースのアドオン</font></td></tr>
<tr><td colspan=2>検索イベントを呼び出す</td></tr>
</table>

<table>
<tr><th>入力画面</th><th>入力ダイアログ</th></tr>
<tr><td>inputPage.jsp</td><td>inputDialog.jsp</td></tr>
<tr><td>Efw("${DefId}_inputPage_init")</td><td>Efw("${defId}_inputDialog_init")</td></tr>
<tr><td colspan=2><font color=red>検索前処理のアドオン</font>　※新規モードではない場合</td></tr>
<tr><td colspan=2><font color=red>検索後処理のアドオン</font>　※新規モードではない場合</td></tr>
<tr><td colspan=2>入力項目⇒<font color=red>タイトルのアドオン</font></td></tr>
<tr><td colspan=2>入力項目・⇒<font color=red>値のアドオン</font>※モード別</td></tr>
<tr><td colspan=2>入力項目（コンボ・ラジオ）⇒<font color=red>ソースのアドオン</td></tr>
</table>

### 検索イベント
<table>
<tr><th>一覧画面</th><th>選択ダイアログ</th></tr>
<tr><td>Efw("${DefId}_listPage_search")</td><td>Efw("${defId}_selectDialog_search")</td></tr>
<tr><td colspan=2><font color=red>検索前処理のアドオン</font></td></tr>
<tr><td colspan=2><font color=red>検索後処理のアドオン</font></td></tr>
<tr><td colspan=2>検索結果項目⇒<font color=red>フォーマットのアドオン</font></td></tr>
</table>

### クリアイベント
<table>
<tr><th>一覧画面</th><th>選択ダイアログ</th></tr>
<tr><td>Efw("${DefId}_listPage_clear")</td><td>Efw("${defId}_selectDialog_clear")</td></tr>
<tr><td colspan=2>検索イベントを呼び出す</td></tr>
</table>

### ダウンロードイベント
<table>
<tr><th>一覧画面</th><th>選択ダイアログ</th></tr>
<tr><td>Efw("${DefId}_listPage_download")</td><td>Efw("${defId}_selectDialog_download")</td></tr>
<tr><td colspan=2><font color=red>検索前処理のアドオン</font></td></tr>
<tr><td colspan=2><font color=red>検索後処理のアドオン</font></td></tr>
</table>

### アップロードイベント
<table>
<tr><th>一覧画面</th><th>選択ダイアログ</th></tr>
<tr><td>Efw("${DefId}_listPage_upload")</td><td>Efw("${defId}_selectDialog_upload")</td></tr>
</table>

※アップロードイベントは、保存前処理と保存後処理のアドオンは実行しません。

### 削除イベント
<table>
<tr><th>一覧画面</th><th>選択ダイアログ</th></tr>
<tr><td>Efw("${DefId}_listPage_delete")</td><td>Efw("${defId}_selectDialog_delete")</td></tr>
<tr><td colspan=2><font color=red>削除前処理のアドオン</font></td></tr>
<tr><td colspan=2><font color=red>削除後処理のアドオン</font></td></tr>
</table>

### 保存イベント
<table>
<tr><th>入力画面</th><th>入力ダイアログ</th></tr>
<tr><td>Efw("${DefId}_inputPage_save")</td><td>Efw("${defId}_inputDialog_save")</td></tr>
<tr><td colspan=2><font color=red>保存前処理のアドオン</font></td></tr>
<tr><td colspan=2><font color=red>モード別項目設定値のアドオン</font></td></tr>
<tr><td colspan=2><font color=red>保存後処理のアドオン</font></td></tr>
</table>

### タイトル操作・入力枠操作・ボタン処理のイベント
<table>
<tr><th>一覧画面</th><th>入力画面</th><th>入力ダイアログ</th><th>選択ダイアログ</th></tr>
<tr><td>Efw("${defId}_listPage_touch")</td><td>Efw("${defId}_inputPage_touch")</td><td>Efw("${defId}_inputDialog_touch")</td><td>Efw("${defId}_selectDialog_touch")</td></tr>
<tr><td colspan=4><font color=red>タイトル操作のアドオン</font><br>
<font color=red>入力枠操作のアドオン</font><br>
<font color=red>ボタン処理のアドオン</font></td></tr>
</table>

https://github.com/efwGrp/ske?tab=readme-ov-file