kintone プラグイン設定画面

2022/09/26に公開

kintoneプラグインの開発で設定画面にテーブルを入れましたが、知らないことが多かったのでテーブルまわりの操作を中心として備忘録をまとめます。

プラグインの機能としては、ルックアップで参照、フィールドの値をコピーしている時に参照元のレコードが変更されたら参照先のレコードを更新したい場合に使えるプラグインです。
設定画面に必要な情報は、参照されているフィールドコード(プラグインを添付するアプリ)、参照先のルックアップフィールドのフィールドコードのそのアプリIDです。
さらに、参照先は一つとは限らないので複数指定できるようにテーブルにしています。

機能自体は下記の記事と同様のことをしようとしています。
※今回はこの記事と同じようなことをするプラグインの設定画面についての内容です。

https://developer.cybozu.io/hc/ja/articles/204537310-第11回-kintone-REST-APIを利用したレコード更新-ルックアップ自動更新-

まずは仕上がったコードです。

コード

config.html
<div id="body">
       <div id="header">
              <h2>レコード更新時にルックアップしている別アプリの更新を行います</h2>
       </div>
       <div class="kintoneplugin-label">自動取得したいルックアップフィールド(このアプリ)</div>
       
       
       <div class="kintoneplugin-select-outer">
              <div class="kintoneplugin-select">
                     <select id="lookup_field">
                     </select>
              </div>
      </div>

      <div class="kintoneplugin-label">更新したい別アプリのアプリID(半角数値)と、ルックアップフィールドのフィールドコード</div>
       <table class="kintoneplugin-table" id="plugin-table">
              <thead>
              <tr>
              <th class="kintoneplugin-table-th"><span class="title">アプリID</span></th>
              <th class="kintoneplugin-table-th"><span class="title">フィールドコード</span></th>
              <th class="kintoneplugin-table-th-blankspace"></th>
              </tr>
              </thead>
              <tbody id="appInfo">
              <tr>
              <td>
                     <div class="kintoneplugin-table-td-control">
                            <div class="kintoneplugin-table-td-control-value">
                                   <div class="kintoneplugin-input-outer">
                                   <input class="kintoneplugin-input-text appid" type="textd">
                            </div>
                     </div>
              </div>
              </td>
              <td>
                     <div class="kintoneplugin-table-td-control">
                            <div class="kintoneplugin-table-td-control-value">
                                   <div class="kintoneplugin-input-outer">
                                   <input class="kintoneplugin-input-text feildCode" type="text">
                                   </div>
                            </div>
                     </div>
                     </td>
              <td class="kintoneplugin-table-td-operation">
                     <button type="button" class="kintoneplugin-button-add-row-image addRow" title="Add row"></button>
                     <button type="button" class="kintoneplugin-button-remove-row-image deleteRow" title="Delete this row"></button>
              </td>
              
              </tr>
              </tbody>
       </table>
     
      
     
       <div class="block">
              <button type="button" id="check-plugin-submit" class="kintoneplugin-button-dialog-ok"> 保存する </button>
              <button type="button" id="check-plugin-cancel" class="kintoneplugin-button-dialog-cancel"> キャンセル </button>
       </div>
</div>
config.js
/*
    kintone updatelookup plugin
 */
    jQuery.noConflict();

    (function($, PLUGIN_ID) {
      'use strict';
    
      // プラグインIDの設定
      var config = kintone.plugin.app.getConfig(PLUGIN_ID);
      // 既に値が設定されている場合はフィールドに値を設定する]
      console.log(config);
      if (config.lookup) { 
        $("#lookup_field").val(config.lookup);

        //オブジェクトの長さ
        const keysLength = Object.keys(config).length;
        //行数はオブジェクトの長さからlookupを引き、2で割ると行数になる
        const rows = (keysLength-1)/2;
        let index = 0;
        while(index < rows) {
          if(index !== 0){
            $("#plugin-table tbody tr:first-child").clone(true).appendTo("#plugin-table tbody");
            $("#plugin-table tbody tr:last-child input").val("");
          }
          $($(".appid")[index]).val(config["appid"+index]);
          $($(".feildCode")[index]).val(config["code"+index]);
          index++;
        }  
      }
        
      //ドロップダウンリストを作成する
      async function setDropDownForDate() {
        try {
          const resp = await KintoneConfigHelper.getFields(["SINGLE_LINE_TEXT","NUMBER"]);
          const $dateDropDown = $('#lookup_field');
          for (var i = 0; i < resp.length; i++) {
            var $option = $('<option></option>');
            $option.attr('value', resp[i].code);
            $option.text(resp[i].label);
            $dateDropDown.append($option);
          }
          if (config.user) {
            $dateDropDown.val(config.user);
          }
        }catch(error) {
          alert("フィールド情報の取得に失敗しました。");
        }
      }
      
      setDropDownForDate();
    
      // 「行追加」ボタン押下時
      $('.addRow').click(function() {
        $("#plugin-table tbody tr:first-child").clone(true).appendTo("#plugin-table tbody");
        $("#plugin-table tbody tr:last-child input").val("");
      });
      // 「行削除」ボタン押下時
      $('.deleteRow').click(function() {
        $(this).closest("tr").remove(); // クリックした削除ボタンを指定する→指定した要素の直近のtr要素を取得する
      });
    
      // 「保存する」ボタン押下時に入力情報を設定する
      $('#check-plugin-submit').click(function() {
        let obj = new Object;
        obj.lookup = $("#lookup_field").val();
        let tr = $("#plugin-table tbody tr");
        for(let i = 0; i < tr.length; i++){
          obj["appid"+ i] = $(".appid")[i].value;
          obj["code"+ i] = $(".feildCode")[i].value;
        }
        kintone.plugin.app.setConfig(obj);
      });
    
      // 「キャンセル」ボタン押下時の処理
      $('#check-plugin-cancel').click(function() {
        history.back();
      });
    
    })(jQuery, kintone.$PLUGIN_ID);

備忘録

テーブルに行追加

// 「行追加」ボタン押下時
$('.addRow').click(function() {
	$("#plugin-table tbody tr:first-child").clone(true).appendTo("#plugin-table tbody");
	$("#plugin-table tbody tr:last-child input").val("");
});

追加するときは、まず最初の行データ(tr)をcloneメソッドで複製してからtbodyにappendToメソッドで追加します。
appendToメソッドは要素の末尾に追加することができます。
これだけだと、最初の行データの内容がコピーされてしまうので、値を空にする処理も併せて行います。
末尾に追加するので、trオブジェクトの末尾のinputの値を削除します。

テーブルの行削除

// 「行削除」ボタン押下時
$('.deleteRow').click(function() {
	$(this).closest("tr").remove();
});

clickファンクションでクリックされた要素が削除されるように$(this)で要素をし、closest()メソッドで親要素のtrまで遡って取得しremove()で削除します。

保存ボタン実行時(設定情報の保存)

https://developer.cybozu.io/hc/ja/articles/203661160#step2

テーブルの情報を保存したいので、引数のconfigオブジェクトに、オブジェクトの配列を設定しようと思っていました。
がしかし、ドキュメントをみると、

キーは 64 文字以下の ASCII 文字で指定します。値は 65535 文字以下の文字列で指定します。

値は文字列でなければならないということがわかりました。
ということはconfigオブジェクトの長さ自体がテーブルの長さによって変わるという仕組みにするしかないようです。(多分)

 $('#check-plugin-submit').click(function() {
        let obj = new Object;
        obj.lookup = $("#lookup_field").val();
        let tr = $("#plugin-table tbody tr");
        for(let i = 0; i < tr.length; i++){
          obj["appid"+ i] = $(".appid")[i].value;
          obj["code"+ i] = $(".feildCode")[i].value;
        }
        kintone.plugin.app.setConfig(obj);
});

最初にルックアップフィールドの情報をセットしたら、ループ処理でオブジェクトに入れていきます。
プロパティはセットすることを考えると数字が入っていた方がやりやすいかなと思い、0~採番して番号を持たせました。

値のセット

すでに設定データが保存されている場合に設定画面に登録内容をセットするところです。

// プラグインIDの設定
var config = kintone.plugin.app.getConfig(PLUGIN_ID);
// 既に値が設定されている場合はフィールドに値を設定する
//必須項目にしているlookupに値があれば他もあるためそこで判断する
if (config.lookup) { 
$("#lookup_field").val(config.lookup);

//オブジェクトの長さ
const keysLength = Object.keys(config).length;
//行数はオブジェクトの長さからlookupを引き、2で割ると行数になる
const rows = (keysLength-1)/2;
let index = 0;
while(index < rows) {
  if(index !== 0){
    $("#plugin-table tbody tr:first-child").clone(true).appendTo("#plugin-table tbody");
    $("#plugin-table tbody tr:last-child input").val("");
  }
  $($(".appid")[index]).val(config["appid"+index]);
  $($(".feildCode")[index]).val(config["code"+index]);
  index++;
}  
}

配列の長さは

Array.length

で求められますが(Arrayが変数名)、オブジェクトの場合は

Object.keys(obj).length;

このように求められます。(objが変数名)
今回はテーブルの列数が2、テーブル以外にlookupプロパティがあるので、

//行数はオブジェクトの長さからlookupを引き、2で割ると行数になる
const keysLength = Object.keys(config).length;
const rows = (keysLength-1)/2;

これで何回ループ処理したら良いか判断しています。
あとは行追加して値をセットの繰り返しです。

所感

基本的なことなんだろうと思いますが、わからないことが多かったです。
次はメインの処理の内容になります。

Discussion