テーブルデータを指定した条件で並び替えて行番号も振り直す
やりたいこと
Kinotneアプリでテーブル内データを指定した条件で何回でも並び替え出来るフォームとボタンを作成してみました。
これは、テーブル内の入力データを後から並び替え表示したいという要望が色々な条件で次々と出て来るため、フォーム上の条件指定で任意に並び替え出来る機能を実装したモノです。
デモ画面
デモ画面では、テーブル内のデータ(日付、金額、メモ)を任意で指定し、ソート順も昇進/降順を選択して[並び替え実行]ボタンをクリックすれば、テーブル内のデータを指定の条件で並び替え表示します。
更に「No」フィールドを追加して行番号を昇順では1から順番に、降順では最大行数からー1で連番を振る様にしました。
レコード新規登録と編集画面で動作します。
以前に「アプリのテーブル内のデータを日付順で並び替える」という事例を掲載しましたが、前回の内容よりも汎用性の高いカスタマイズ事例です。
フォームの設定
フォームの設定では、フィールド名(フィールドコード):フィールド型を以下の様に設定して下さい。
フィールド名は自由に指定可能ですが( )内のフィールドコード名は、Javascriptコードの「初期設定」のフィールドコード設定内容と合わせる必要があります。
明細テーブル(明細テーブル):テーブル
No(No):数値型・・・テーブルの行番号表示用
日付(日付):日付型
金額(金額):数値型
メモ(メモ):文字列1行
並び替えキー(並び替えキー):ドロップダウン※
ソート順(ソート順):ラジオボタン
スペース(要素ID=Button_Space)
※並び替えキーのドロップダウン設定項目は、明細テーブル内のフィールドコード名と合わせる必要があります。
サンプルのJavascriptコード
初期設定の/ フィールドコードを、kintoneフォームのフィールドコード名と合わせる様にして下さい。
エラーになる原因は、初期設定のフィールドコードがフォームの設定内容と異なるケースがほとんどです。
ボタンの名前を変更したい場合は、以下の行を修正して下さい。
sortButton.innerText = '並び替え実行';
その他の部分は、修正する必要はありません。
/* テーブル内データを指定した条件で並び替えて行番号も振り直す */
(function() {
'use strict';
// 初期設定
const SORT_KEY_FIELD = '並び替えキー';
const SORT_ORDER_FIELD = 'ソート順';
const DETAIL_TABLE_FIELD = '明細テーブル';
const BUTTON_SPACE = 'Button_Space';
// <------ 初期設定ここまで ------>
// ソート順の定義
const SORT_ORDER = {
ASCENDING: '昇順',
DESCENDING: '降順'
};
// フォームフィールド情報を取得
let formFields;
kintone.api(kintone.api.url('/k/v1/app/form/fields', true), 'GET', { app: kintone.app.getId() }, function(resp) {
formFields = resp.properties;
});
// ボタンの作成と設置
kintone.events.on('app.record.create.show', addButton);
kintone.events.on('app.record.edit.show', addButton);
function addButton(event) {
if (document.getElementById('sortButton')) {
return;
}
const sortButton = document.createElement('button');
sortButton.id = 'sortButton';
sortButton.innerText = '並び替え実行';
sortButton.onclick = sortTable;
sortButton.style.marginTop = '30px';
kintone.app.record.getSpaceElement(BUTTON_SPACE).appendChild(sortButton);
return event;
}
// テーブルをソートして連番を振る関数
function sortTable() {
const record = kintone.app.record.get();
const tableData = record.record[DETAIL_TABLE_FIELD].value;
const sortKey = record.record[SORT_KEY_FIELD].value;
const sortOrder = record.record[SORT_ORDER_FIELD].value;
// フィールド情報を取得
const fieldInfo = formFields[DETAIL_TABLE_FIELD].fields[sortKey];
// ソートキーに基づいてテーブルデータをソート
tableData.sort((a, b) => {
let valueA = a.value[sortKey].value;
let valueB = b.value[sortKey].value;
// フィールドの型に基づいて適切な比較を行う
let comparison = 0;
switch (fieldInfo.type) {
case 'NUMBER':
case 'CALC':
valueA = Number(valueA);
valueB = Number(valueB);
comparison = valueA - valueB;
break;
case 'DATE':
case 'DATETIME':
valueA = new Date(valueA);
valueB = new Date(valueB);
comparison = valueA.getTime() - valueB.getTime();
break;
default:
comparison = String(valueA).localeCompare(String(valueB));
}
return sortOrder === SORT_ORDER.ASCENDING ? comparison : -comparison;
});
// 連番を振る
tableData.forEach((row, index) => {
row.value.No.value = sortOrder === SORT_ORDER.ASCENDING ? index + 1 : tableData.length - index;
});
// 更新されたデータを再設定
kintone.app.record.set(record);
}
})();
カスタマイズした感想
本カスタマイズを実装した経緯は、テーブル入力が終了した後に、上長から「新しい日付順に並べて」、「金額の大きい順番に表示して」等のリクエストが頻繁に発生し、現場の入力担当者が半切れ状態wだったので、ボタン一発で自由に並び替え出来るように対応したものです。
工夫した点としては、フォームのフィールド情報を取得して、並び替えキーに指定されたテーブル内フィールドの型(文字型、数値型、日付型)に応じて比較対象フィールドの値を適切な型に変換するロジックを組み入れたことです。このロジック無しではフィールドを文字型で比較ソートしてしまうため、数値型では期待したソート結果にならないという問題がありました。
実装後に現場のユーザーから、明細テーブルの下に並び替え条件(並び替えキーとソート順序)が表示されるのも、分かり易くて良いとの感想を頂きました。
一番喜んでいたのは「テーブルの入力順序を並び替え表示して」と指示するたびに、部下から嫌そうな顔をされていた上長様かもしれませんw
今回も最後まで読んで頂いて、ありがとうございました。
よろしければサポートお願いします! いただいたサポートは、note記事制作の活動費に使わせていただきます!