kintoneカスタマイズ例-ダイアログとテーブル更新-

# 概要
この記事では、下記の処理を行うjsコードを掲載しております。
1. 詳細画面にボタンを作成する。
2. ボタンをクリックするとダイアログ(ポップアップ画面)が表示される。
3. ダイアログのボタンをクリックすると、その内容を「文字列フィールド」と「テーブル」に反映する。

## 利用イメージ
kintoneの標準プロセスでは、1本の流れでプロセスを管理するイメージです。
しかし、今回は1レコードに対して複数のプロセスが並行で動く場合があったため、
それを実現するためのカスタマイズとなります。
イメージ図
<img width="407" alt="image26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374573/cd195a30-6e21-54d5-ba71-40c5ba552872.png">

※この例はモバイル対応しておりません。
※ワークフローや承認者の指定といった機能はコードが長くなりすぎてしまうため別記事とします。

## 完成イメージ
<img width="433" alt="image29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374573/a7ad0cc7-7f33-4b0d-d612-f3df88753d85.png">
<img width="955" alt="ukeire1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374573/26c37ecd-5333-9602-109b-2c88709ec7f9.png">


# 準備
## フィールド作成
kintoneのアプリに下記のフィールドを作成してください。

|フィールドの種類  |フィールド名  |フィールドコード(要素ID)  |その他  |
|----|----|----|----|
|スペース  |  |btn  | |
|文字列(1行)  |最新ステータス  |lastUpd  ||
|文字列(1行)  <br>※サブテーブル|プロセス名  |process  |初期値：[起票]|
|文字列(1行)  <br>※サブテーブル|更新ステータス  |status |初期値：[起票]|
|日時 <br>※サブテーブル|更新日時  |updTime |[レコード登録時の日時を初期値にする]にチェック|
|ユーザー選択  <br>※サブテーブル|担当者  |updUser |初期値：[ログインユーザー]|
|文字列(1行)  |hid機能A  |hidAkinou |※プロセスごとの最新状態を取得するために使います。|
|文字列(1行)  |hid機能B |hidBkinou |※プロセスごとの最新状態を取得するために使います。|

作成後イメージ
<img width="929" alt="image27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374573/0221c065-e59a-6b3e-55bd-2f43c389f67f.png">

## ファイルをkintoneに添付
| アップロード先 |ファイル  |
|----|----|
|PC用のJavascriptファイル   |https://js.cybozu.com/jquery/2.2.4/jquery.min.js  |
|同上  |https://js.cybozu.com/jqueryui/1.12.0/jquery-ui.min.js  |
|同上  |https://js.cybozu.com/momentjs/2.10.3/moment-with-locales.min.js  |
|同上  |https://js.cybozu.com/momentjs/2.10.3/moment-with-locales.min.js  |
|同上  |custom.js (下記で作成するjsファイル) |
|PC用のCSSファイル  |https://js.cybozu.com/jqueryui/1.12.1/themes/smoothness/jquery-ui.css  |

アップロード後イメージ
<img width="390" alt="omage28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374573/4388c21c-7604-8f2d-46c2-2fb8a2fa9ce0.png">


# サンプルコード
それでは、やっとコードの紹介をします。

```js
(function($) {
    "use strict";

    kintone.events.on('app.record.detail.show', function(event) {
        /**
         * 定義1：ボタンや値の変数
         * 定義2：表示するボタン・更新する値
         * 定義3：表示するダイアログとボタンの数
         */
        //共通変数一覧
        var dialog_1 =  $('<div id="dialog_1" title="ステータス更新"></div>');
        var subtable = []; // 最終的にPUTするサブテーブル
        var user = kintone.getLoginUser(); // ログインユーザー情報取得
        var existing_subtable = event.record["Table"].value; // 既存のサブテーブルの値を取得
        /**機能Aの定義1 */
        var dialog_A =  $('<div id="dialog_A" title="機能Aステータス更新"></div>');
        var A_daikubun="機能A";     //ステータス進捗テーブルの区分
        var A_statusvalue="";  //ステータスボタン1の値
        var A_statusvalue2=""; //ステータスボタン2の値
        var hid_A_saisinstatus="hidAkinou"; //ステータスを裏で持つ格納先

        /**機能Bの定義1 */
        var dialog_B =  $('<div id="dialog_B" title="機能B更新"></div>');
        var B_daikubun="機能B";     //ステータス進捗テーブルの区分
        var B_statusvalue="";  //ステータスボタン1の値
        var B_statusvalue2=""; //ステータスボタン2の値
        var hid_B_saisinstatus="hidBkinou"; //ステータスを裏で持つ格納先


        /**共通：進捗状況テーブル更新処理 */
        var addTable = function(daikubun,statusvalue,hid_saisinstatus) {
            // 既存のサブテーブルを抽出
            for (var i = 0; i < existing_subtable.length; i++) {
                subtable.push(existing_subtable[i]);
            }
            // 既存テーブルのレコードに追加する用のレコード作成
            var addTablerecord = {
                "value": 
                {
                    "process": {
                        "value": daikubun
                    },
                    "status": {
                        "value": statusvalue
                    },
                    "updTime": {
                        "value": moment().format("YYYY-MM-DDTHH:mmZ")
                    },
                    "updUser": { 
                        "value": [{
                            "code":user.code
                        }]
                    }
                }
            }
            subtable = subtable.concat(addTablerecord); // 既存と追加分のサブテーブルを結合
            var put_record = {}; // レコード更新用オブジェクト
            put_record["Table"] = {value: subtable};
            put_record[hid_saisinstatus] = {value: statusvalue};
            put_record["lastUpdStatus"] = {value: statusvalue};
            //  REST APIでレコードを更新する
            kintone.api('/k/v1/record', 'PUT', {
                app: kintone.app.getId(),　// アプリID
                id: kintone.app.record.getId(),//   レコードID
                record: put_record
            }, function(resp) {
            // 成功時は画面をリロード
                location.reload(true);
            });
        }

        /**機能Aの定義2 */
        // 現在のステータスを取得
        var getAvalue = event["record"]["hidAkinou"]["value"];
        //区分ボタン定義
        var A_kubun = {
            text: '機能A',
            click: function(){
               $(this).dialog("close");
               $(dialog_A).dialog().dialog("open");
            }
        };
        if (getAvalue==""||getAvalue=="保留"){
            A_statusvalue="着手";
            A_statusvalue2="対応不要";
        } else if(getAvalue=="着手"){
            A_statusvalue="完了";
            A_statusvalue2="保留";
        }else if(getAvalue=="完了"||getAvalue=="対応不要"){
            A_kubun = {
                text: '-',
                click: function(){
                    $(this).dialog("close");
                }
            };
        }

       /**機能Bの定義2 */
        // 現在のステータスを取得
        var getBvalue = event["record"]["hidBkinou"]["value"];
        //区分ボタン定義
        var B_kubun = {
            text: '機能B',
            click: function(){
               $(this).dialog("close");
               $(dialog_B).dialog().dialog("open");
            }
        };
        if (getBvalue==""){
            B_statusvalue="検証";
            B_statusvalue2="検証保留";
        } else if(getBvalue=="検証"){
            B_statusvalue="検証完了";
            B_statusvalue2="検証失敗";
        } else if(getBvalue=="検証保留"){
            B_statusvalue="検証";
            B_statusvalue2="検証中止";
        }else if(getBvalue=="検証完了"||getBvalue=="検証失敗"||getBvalue=="検証中止"){
            B_kubun = {
                text: '-',
                click: function(){
                    $(this).dialog("close");
                }
            };
        }

        var cancel = {
            text: 'キャンセル',
            click: function(){
                $(this).dialog("close");
            }
        };

        // メインダイアログの初期設定
        $(dialog_1).dialog({
            autoOpen: false,  // 自動的に開かないように設定
            width: 500,       // 横幅のサイズを設定
            modal: true,      // モーダルダイアログにする
            buttons: [        // ボタン名 : 処理 を設定
                A_kubun,B_kubun,cancel
            ]
        });
        
        /**機能A定義3 */
        // 機能Aのダイアログの設定
        $(dialog_A).dialog({
            autoOpen: false,  // 自動的に開かないように設定
            width: 500,       // 横幅のサイズを設定
            modal: true,      // モーダルダイアログにする
            buttons: [        // ボタン名 : 処理 を設定
            {
                text: A_statusvalue,
                click: function(){
                    addTable(A_daikubun,A_statusvalue,hid_A_saisinstatus)
                }
            },
            {
                text: A_statusvalue2,
                click: function(){
                    addTable(A_daikubun,A_statusvalue2,hid_A_saisinstatus)
                }
            },
            {
                text: 'キャンセル',
                click: function(){
                // ダイアログを閉じる
                $(this).dialog("close");
                }
            }
            ]
        });

        /**機能B定義3 */
        // 機能Bのダイアログの設定
        $(dialog_B).dialog({
            autoOpen: false,  // 自動的に開かないように設定
            width: 500,       // 横幅のサイズを設定
            modal: true,      // モーダルダイアログにする
            buttons: [        // ボタン名 : 処理 を設定
            {
                text: B_statusvalue,
                click: function(){
                    addTable(B_daikubun,B_statusvalue,hid_B_saisinstatus)
                }
            },
            {
                text: B_statusvalue2,
                click: function(){
                    addTable(B_daikubun,B_statusvalue2,hid_B_saisinstatus)
                }
            },
            {
                text: 'キャンセル',
                click: function(){
                // ダイアログを閉じる
                $(this).dialog("close");
                }
            }
            ]
        });
        
        /**共通処理 ボタンを設置*/
        var mySpaceFieldButton = document.createElement('button');
        mySpaceFieldButton.id = 'processbtn';
        mySpaceFieldButton.innerText = 'プロセス更新';
        mySpaceFieldButton.onclick = function () {
            $(dialog_1).dialog().dialog("open");
        };

        kintone.app.record.getSpaceElement('btn').appendChild(mySpaceFieldButton);    

    });
})(jQuery);

```
上記のコードをjsファイルにコピペしたら、kintoneにアップロードしてください。
また、「hid機能A 」と「hid機能B」は制御のために必要なフィールドなため、
使用者には見えないように非表示にすると良いと思います。 


# 最後に
もっと上手いコーディング方法はいくらでもあると思います。
もし、こうやっているよとか、ここに公開しているよっていう情報があったら教えてください！
また、稼働中のファイルから流用する形で掲載したため、命名規則や構成があまりよくない形になっています。
気になる方は、ぜひ直したうえで参考にしてください。