【パブリッシャー】JavaScriptでの拡張 - KENDO kendoDropDownListコントロール

[Sharperlight](https://sharperlight.jp/)には、[Kendo](https://www.telerik.com/) JavaScript ライブラリが梱包されています。
Kendo JavaScript ライブラリには、様々なWEB UIコントロールが準備されていて、Sharperlightの公開クエリとの組み合わせでいろいろなWebインターフェースを作成することができます。
この記事では、kendoDropDownListコントロールを使用してみます。
準備するものは、kendoDropDownListコントロールを配置するHTML(JavaScriptコード含)、そのHTMLのコンテナとなる公開クエリ、kendoDropDownListコントロールにデータを供給する公開クエリの3点です。
## HTML(JavaScriptコード含)の作成 ##
#### ヘッダー部 ####
Kendo JavaScript ライブラリのコンポーネントを参照するコードを記します。
![2022-04-19 Figure 03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/84992fee-590e-1e66-3b59-405b88162cda.png)
#### HTMLの本体 ####
➊の部分では、```<input>```を配置してIdを与え、ここにKendo DropDownListコントロールを作成します。
➋の箇所にはSharperlightのロゴを取得するURLを設定します。これは、このHTMLのコンテナとなる公開クエリに定義されたクエリの拡張表現の名前を指しています。その拡張表現でロゴ画像へのURLが定義されています。
![2022-04-19 Figure 04.1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/98e94759-08df-1051-6768-d836d1c7e3ab.png)
➌のSharperlightコントロールタグは、現在のSharperlightのバージョンを返します。 
![2022-04-19 Figure 04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/9bad706b-c2cc-180d-bef3-467bd9dc157f.png)
#### スクリプトの本体 ####
ここでは、Kendo DropDownListコントロールの定義とデータ供給関数を呼び出しを行います。
図の➊の部分に注意してください。**JpStateName**、**JpStateId**は、データ供給用公開クエリの出力フィールドの**名前**と一致する必要があります。
![2022-04-19 Figure 05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/880d7c70-253f-f4b3-e2ee-80d17cc80319.png)
#### スクリプト内の関数 ####
ここでは、Kendo DataSourceオブジェクトを作成する関数とデータを読み込んでDropDownListを更新する関数を定義します。
DataSourceオブジェクトを作成する関数内のSchema -> Modelに特に注意してください。それらは、データ供給用公開クエリの出力フィールドの**名前**と一致する必要があります。
![2022-04-19 Figure 05.1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/329c8d06-fea6-4442-1dd7-52a4dcd2a6d9.png)
![2022-04-19 Figure 06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c0b4a9cc-e808-59fd-3c14-c8c2f56a7d59.png)

#### 全コード ####
```
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <base href="{*Url.Root}"/>
        <link rel="shortcut icon" type="image/x-ico" href="favicon.ico"/>
        <link rel="icon" type="image/x-ico" href="favicon.ico"/>
        <title>Qiita KENDO</title>
        
        <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.common.min.css" />
        <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.default.min.css" />
        <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.default.mobile.min.css" />
        <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.silver.min.css"/>
        <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.silver.mobile.min.css" />
        
        <script type="text/javascript" src="{*Url.Root}Resources/jquery/jquery.min.js"></script>
                
        <script type="text/javascript" src="{*Url.Root}Resources/kendo/js/kendo.all.min.js"></script>
        <script type="text/javascript" src="{*Url.Root}Resources/kendo/js/kendo.timezones.min.js"></script>
        
    </head>
    <body style="font-family: arial; font-size:13px">
        <div>
            <table class="QiitaSample_Table">        
                <tr>    
                    <td class="QiitaSample_Table_ColA"><div>都道府県:</div></td>
                    <td class="QiitaSample_Table_ColB"><input id="KDD_ListOfStates" /></td>
                </tr>
            </table>
        </div>
        
        <div id="poweredBySharperlight" style="position: absolute; top: 1px; left: 240px;">
            <a href="https://www.sharperlight.com" target="_blank">
                <img src="{*Row.imgURLSharperlight.text}" title="{*Dictionary.Code.Version} {*Application.Version}" style="width: 48px; height: 48px;"/>
            </a>
            <div style="font-size:9px; font-weight: bold; position: relative; top: -32px; left: 48px;">Powered By Sharperlight</div>
        </div>

        <script>
            var gURL_ReadListOfStates = "{*Row.ReadListOfStates.text}";
            var gKddl_ListOfStates;
            
            $(function () {
                $("#KDD_ListOfStates").kendoDropDownList({
                    dataTextField: "JpStateName",
                    dataValueField: "JpStateId",
                    optionLabel: {
                        JpStateName: "都道府県を選択してください...",
                        JpStateId: 0
                    },
                    change: function(e) {
                        var value = this.value();
                    },
                    optionLabelTemplate:'<span style="color:lightgray">-- 選択してください --</span>'
                });
                gKddl_ListOfStates = $("#KDD_ListOfStates").data("kendoDropDownList");
                
                _ListOfStates_Refresh();
            });    


            function _Datasource_States_Create(){
                try{
                    var dsStates = new kendo.data.DataSource({
                        serverFiltering: false,
                        transport: {
                            read: {
                                datatype: "jsonp",
                                url: gURL_ReadListOfStates
                            }
                        },
                        schema: {
                            model: {
                                fields: {
                                    JpStateId: { type: "number" },
                                    JpStateCode: { type: "string" },
                                    JpStateName: { type: "string" },
                                }
                            }
                        }
                    });
                    return dsStates;
                }catch (err){
                    alert("Error in Datasource_States_Create(): " + err.message);
                    return null;
                }
            };

            function _ListOfStates_Refresh(){
                try{
                    var ds = _Datasource_States_Create();
                    if (ds != null){				
                        ds.read().then(function (){
                            var data = ds.data();
                            if (data.length > 0){
                                gKddl_ListOfStates.setDataSource(ds);
                                gKddl_ListOfStates.refresh();
                                gKddl_ListOfStates.value(0);
                            }else{
                                throw ("Error in _ListOfStates_Refresh(): " + "都道府県データはまだ生成されていません。");
                            }
                        });
                    }
                }catch (err){
                    throw ("Error in _ListOfStates_Refresh(): " + err.message);
                }
            };

        </script>
    </body>
</html>
```
HTMLコードの準備が完了したら、コンテナ用公開クエリに設定します。
## コンテナ用公開クエリへのHTMLの設定 ##
#### 公開クエリの作成 ####
[Sharperlight](https://sharperlight.jp/)アプリケーションメニューから**パブリッシャー**を起動します。
公開クエリを新規作成します。グループ名とコードを入力後、クエリの編集を行います。
![2022-04-19 Figure 07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/11869c07-ea19-1ed4-eaa0-433e64653e95.png)
これはコンテナ用のクエリなので、1行のみ返すクエリを作成します。
フィルター領域のテーブルプロパティを開き、トップ1行のみを返すオプションを設定します。
![2022-04-19 Figure 08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/66ddb1fa-58f1-50f4-3947-19b1c91ba821.png)
出力するフィールドは、この場合基本的になんでもいいのですが、ここでは梱包するHTMLコードに渡す値を定義します。
上記で言及した、データソース用のURLやロゴ用のURLを、拡張表現を用いてここで定義します。
```
JavaScriptEncode( "{_System.Rest.URL}DataSource/?query=QiitaSample" + ".JsKENOData01&dfmt=jsonarray&dcat=UseNames{_System.Rest.Usid}")
```
![2022-04-19 Figure 10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/15bcf826-0dd9-7e8c-72a9-a285f05cfada.png)
![2022-04-19 Figure 09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/3fc622fb-28eb-610c-0805-744756c37c64.png)
#### HTMLコードの梱包 ####
**クエリーの公開**ダイアログの**オプション**タブに移動します。
ここでは、**リソース**と**カスタムHTML**プロパティを使用します。
![2022-04-19 Figure 11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c66d2299-c58c-3ccd-a2c5-460185c06386.png)
先ず**リソース**プロパティを開き、作成したHTMLコードファイルをインポートします。
➊新規作成、➋ファイルの指定、そして➌リソース参照コードをコピー
![2022-04-19 Figure 12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ce3dc1d7-8682-9749-a068-274329ab3571.png)
カスタムHTMLプロパティに移動します。コピーしたリソース参照コードを貼り付けて完了です。
![2022-04-19 Figure 13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/020d5f82-218f-65c9-1b5d-1cc89f763fa8.png)
OKを押して保存します。これでHTMLコードを、コンテナ用公開クエリに梱包できました。
公開クエリもOKを押して保存します。
## データ供給用の公開クエリの作成 ##
最後に、KendoDropDownListコントロールにデータを供給する公開クエリを作成します。公開クエリは、URLパラメータを使用して、JSONフォーマットでデータセットを返すエンドポイントにもなります。
[Sharperlight](https://sharperlight.jp/)アプリケーションメニューから**パブリッシャー**を起動します。
公開クエリを新規作成します。グループ名とコードを入力後、クエリの編集を行います。
今回は、サンプルなのでカスタムデータを準備しました。通常は、ご使用のデータベースからデータを取得します。
![2022-04-19 Figure 14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/f90f39af-14b5-7f3e-fc12-7fce7dc20e84.png)
**ID**、**コード**、**都道府県**を出力領域に設定し、それぞれに**名前**を付与します。(**説明**ではありません)
![2022-04-19 Figure 15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/33a881f5-61d2-d7bb-d333-80696374c0be.png)
以上でデータ供給用公開クエリの定義は完了です。OKを押して保存しましょう。
## 動作確認 ##
[Sharperlight](https://sharperlight.jp/)サービスを起動して、コンテナ用公開クエリのURLをブラウザのアドレスバーに貼り付けます。
このようなページが表示されます。ドロップダウンリストをクリックすると、選択可能なデータが表示されると思います。
![2022-04-19 Figure 01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/702ec331-ca00-0e67-e422-2674141e4d72.png)
![2022-04-19 Figure 02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/4a78e27e-400e-5f2b-96c1-c32fd39999a3.png)
:postbox:[Sharperlight](https://sharperlight.jp/)