Kintoneの一覧画面で、IPアドレスでソートを行いたい。
普通にソートするとどうなるか
下の画像のように、IPアドレスだけを持つアプリを作成した。
「IPアドレス」ヘッダーをクリックしてソートすると、
このようにソートされる。
できれば192.168.1.1
→192.168.2.1
→192.168.10.1
の順でソートする方法が欲しい。
IPアドレスを0パディングする
足りないケタを0で埋めれば思った通りにソートできそうだ。つまり、
-
192.168.1.1
→192.168.001.001
-
192.168.2.1
→192.168.002.001
-
192.168.10.1
→192.168.010.001
のようにする。
Kintoneアプリに0パディング用のフィールドを新たに追加して、0で埋めた値を保存してみた。
新たに追加した方のフィールドでソートすると、
期待した通りの順番になった。
IPアドレスを0パディングで表記すると8進数として扱われるケースがあるようです。例えば192.168.010.001
の第3オクテット010
は、8進数の10
、10進数の8
と解釈されることがあります。0パディングはKintone上のソートでの使用に限った方が良いと思われます。
面倒くさい
期待通りのソートは実現できたが、全レコード分、値を更新しなければならない。
元のIPアドレスは自分で入力するとして、0パディングは自動で補完されてほしい。
というわけで、JavaScriptでのカスタマイズを使って、レコードの追加時や編集時に元のIPアドレスを変更したら、0パディング用のフィールドに自動で入力されるようにする。
(前準備)アプリのフィールドコードを設定
先にJavaScript上で指定できるように、各フィールドにフィールドコードを設定する。
今回は、元のIPアドレスを入力するフィールドにはip_address
、
0パディングしたIPアドレスが入力されるフィールドにはip_address_0padding
と設定した。
実際のコード
というわけで、全文は下記の通りになった。
(() => {
"use strict";
// 0パディング用のフィールドを自動的に補完する
kintone.events.on(
[
// IPアドレスのフィールドの値が変更されたとき
"app.record.create.change.ip_address",
"app.record.edit.change.ip_address",
],
(event) => {
// レコード
const record = event.record;
// 0パディング用のフィールドを初期化
record.ip_address_0padding.value = "";
// IPアドレス用のフィールドに今入力された値
const ip = record.ip_address.value;
// 今入力されたのが空文字なら終わり
if (!ip?.trim()) {
return event;
}
// 今の入力されたのがIPアドレスかどうか判定する
if (ip.match(
/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/
)) {
// 0埋めに変換する
record.ip_address_0padding.value = ip.replace(/\d+/g, m => m.padStart(3, '0'));
}
return event;
}
);
// 0パディング用のフィールドは編集禁止にする
kintone.events.on(
[
"app.record.create.show",
"app.record.edit.show",
"app.record.index.edit.show",
],
(event) => {
event.record.ip_address_0padding.disabled = true;
return event;
}
);
})();
解説
レコードの追加画面、編集画面で、IPアドレスのフィールド(フィールドコード:ip_address
)が更新されたときに実行してほしいので、イベントハンドラを紐づけるイベントのタイプは下記のように記述した。
kintone.events.on(
[
"app.record.create.change.ip_address",
"app.record.edit.change.ip_address",
],
(event) => {
// ここに処理を書く
}
);
また、入力されたのがIPアドレスの場合のみ処理したかったので、正規表現を使ってIPアドレスかどうか判断している。正規表現はこちらを参考にしました。
if (ip.match(
/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/
)) {
// IPアドレス!
} else {
// IPアドレスではない
}
あとはIPアドレスを.
で区切った配列を取得して、配列の各要素に対して足りない分は0で埋めて、また.
区切りでくっつける、という処理を行った。
あとはreplace()
を使い、IPアドレスの数値部分を0埋めで置き換える。
※コメントで教えていただきました!ありがとうございます!
record.ip_address_0padding.value = ip.replace(/\d+/g, m => m.padStart(3, '0'));
当初書いていたコード
// IPアドレスを.で区切る
const ip_array = ip.split(".");
// 0埋めした値を入れ直す
for (let i = 0; i < ip_array.length; i++) {
ip_array[i] = ip_array[i].padStart(3, '0');
}
// .区切りで連結
record.ip_address_0padding.value = ip_array.join(".");
↑当初書いていたコード終わり。
さらに、0パディングしたIPアドレスを入れるフィールド(フィールドコード:ip_address_0padding
)は自動入力のみ受け付け、人間に編集して欲しくないので、編集禁止にしておく。
kintone.events.on(
[
"app.record.create.show",
"app.record.edit.show",
"app.record.index.edit.show",
],
(event) => {
event.record.ip_address_0padding.disabled = true;
return event;
}
);
アプリに適用する
アプリの設定からJavaScriptファイルをアップロードして、レコードを追加してみる。
下の画像のように0パディング用のフィールドは編集できなくなっている。
また、IPアドレスを入力して、フィールド外などをクリックしてフォーカスが外れると、
下の画像のように自動的に0パディング用のフィールドが更新された。