(著者: KADOYA Ryo)
代替ライブラリのひとつ Luxon については、kintone カスタマイズでの導入方法の紹介記事があります。
Index
はじめに
こんにちは。門屋です。
今回は Cybozu CDN に掲載されているMoment.js を使用して、
日付フィールドを「年/月/日」にしたり、日時フィールドを Twitter のように「分前、日前」というような表示にする方法をご紹介します。
JavaScriptでは標準で日時のフォーマットを扱う関数があまりありませんが、
Moment.js を使うと柔軟に日付データを整形したり、そのデータを使って計算したりすることができます。
デモ環境
デモ環境で実際に動作を確認できます。
https://dev-demo.cybozu.com/k/36/
ログイン情報はcybozu developer network デモ環境で確認してください。
Moment.js について
Moment.js は日付データの整形、バリデーション、計算、表示を行うためのJavaScript ライブラリです。
github でソースコードが公開されています。
Moment.js の基本の使い方
このように、Moment.js を使えば、標準の関数にはない柔軟な日付データの操作を行うことが可能になります。
さらに詳しい使い方については、Moment.js のマニュアルを参照してください。
kintone で Moment.js を使ってみる
Cybozu CDN にアップロードされている Moment.js を使うと簡単に kintone から Moment.js を利用することができます。
2020年8月1日現在、最新のMoment.js のURLは以下です。
https://js.cybozu.com/momentjs/2.27.0/moment.min.js
https://js.cybozu.com/momentjs/2.27.0/moment-with-locales.min.js
上のURLをkintoneの「アプリの設定」「JavaScript / CSSでカスタマイズ」画面の、「PC用のJavaScriptファイル」に設定します。
通常はmoment-with-locales.min.jsのみ追加します。
kintone カスタマイズでの実用例
では実際に、kintoneカスタマイズでの実用例を紹介します。
日付フォーマットを「YYYY/MM/DD」に変更
kintoneの日付フィールドのフォーマット、デフォルトでは「YYYY-MM-DD」という表示になっていますが、
「YYYY/MM/DD」のような、ほかのフォーマットに変更させることは可能です。
今回は、「標準機能で変更する」「JavaScriptカスタマイズで変更する」の2つの方法をご紹介します。
- 標準機能で変更する
日付の表示フォーマットを変更するには、実は標準機能だけで変更する方法があります。
手軽にできる方法なので、Moment.js を使った「JavaScriptカスタマイズで変更する」方法を紹介する前に、まずはそちらをご紹介します。
具体的には、計算フィールド/文字列(1行)フィールドの計算式でDATE_FORMAT関数を使用する、という方法になります。
下記のように、文字列(1行)フィールド「年/月/日」を一つ追加し、
「自動計算する」の「計算式」の欄に「DATE_FORMAT(日付, "YYYY/MM/dd", "Asia/Tokyo")」を設定することで、
文字列(1行)フィールドの「年/月/日」に、変更されたフォーマットで日付を表示させることができます。
完成イメージ
より詳しく知りたい方はそちらをご参照ください。
- JavaScriptカスタマイズで変更する
標準機能のみでフォーマットを変更する方法を紹介しましたが、その場合、
「計算式」が使えるフィールドを一つ追加し、変更したフォーマットの日付をそちらのフィールドで表示させる必要があります。
元の「日付」フィールドのフォーマットを書き換える、という運用にしたい場合、
Moment.js を使った、こちらの「JavaScriptカスタマイズで変更する」方法があります。
完成イメージ
サンプルプログラム
レコード詳細画面でカスタマイズを行う場合、JavaScriptコードは以下のようになります。
他のフォーマットに指定したい場合は、下記「'YYYY/MM/DD'」の部分を変更してください。
Moment.jsが対応しているフォーマットはこちらをご参照ください。
日時フォーマットを現在からの経過時間(相対表示)に変更
Moment.jsを使ったカスタマイズでは、基本的なフォーマット変更だけではなく、
日時フィールドのデータを「何分前」「何時間前」というような形で表示させることもできます。
完成イメージ
サンプルプログラム
レコード一覧画面でカスタマイズを行う場合、JavaScriptコードは以下のようになります。
Moment.jsを使ったカスタマイズ実例を2つ紹介しましたが、実はcybozu developer network で紹介されている Tipsに、
入社年月日フィールドから入社してからの経過年月を計算する「経過年数を表示する Tips 」や、
期限フィールドの値を使って、「期限が過ぎているか」などを計算する「ログインユーザーが担当しているレコードに背景色をつける Tips 」の活用例もあります。
ご興味のある方はぜひそちらも確認してみてください。
おわりに
日付や時刻のフォーマットを自分で行うのは意外と面倒なものです。その点で、Moment.js は便利なライブラリです。
また、Moment.js には Moment Timezone というライブラリもあり、これを使うことで JavaScriptから異なるタイムゾーンを扱うことができます。
国際化が必要なカスタマイズなどで効果を発揮します。
このTipsは、2022年10月版 kintone で確認したものになります。
カスタマイズのJavaScriptコードを以下のように変更してアップしたところ、フィールドの中央ではなく、左上に文字が偏ってしましました。
直し方がわかる方はいますか。
(function () {
"use strict";
// ロケールを初期化
moment.locale('ja');
kintone.events.on('app.record.index.show', function(e) {
// レコード一覧画面表示イベント
var elements = kintone.app.getFieldElements('日付_0');
for (var i = 0; i < e.records.length; i++) {
var date = e.records[i]['日付_0'].value;
elements[i].innerText = moment().format('MM/DD dddd');
}
});
})();
nakayama様
私もそこ、気になっていましたので、
elements[i].innerText = moment(date).fromNow();
の下に、
elements[i].style.verticalAlign = 'middle';
を足して、直しました。
ご参考になりましたら幸いです。
ファイルの書き出し時には適用されませんが適用する方法はあるのでしょうか?
Suguru Inoueさん
ご質問いただきありがとうございます。cybozu developer network運営事務局です。
ご要望にお応えできず申し訳ないのですが、現状kintoneのカスタマイズを適用できる範囲として、ファイル書き出しは含まれておりません。
show#record=12&l.view=5312713&l.q&l.sort_0=f5312689&l.order_0=DESC&l.sort_1=f5312696&l.order_1=DESC&l.next=11&l.prev=0:1 Refused to apply style from 'https://js.cybozu.com/momentjs/2.22.0/moment-with-locales.min.js' because its MIME type ('application/javascript') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
のエラーが表示され、書式の変更ができないのですが、解決方法をご教示いただけますでしょうか?
yamatami様
お世話になっております。cybozu developer network 事務局です。
'https://js.cybozu.com/momentjs/2.22.0/moment-with-locales.min.js' が「PC用のCSSファイル」項目に設定されていないでしょうか?
JavaScript / CSSでカスタマイズ の設定をご確認ください。
設定イメージ
!!仰るとおり、PC用のCSSファイルにも設定されておりました。
お騒がせし、申し訳ありませんでした。
中央揃えにするために以下を追記しました。
elements[i].innerText = moment(date).fromNow();
の下に、
elements[i].style.verticalAlign = 'middle';
しかし、中央揃えになりません。
どなたか、助言をいただけたら幸いです。
verticalAlignは、縦方向の位置を指定するものです。
横方向の位置指定はtextAlignですね。このあたりはCSSの知識です。
左に寄りすぎるのが気持ち悪い、他の列と同じようにしたいだけということでしたら
という方法もあります。
たまご様
ありがとうございます。
うまくいきました。
また、よりよい方法まで教えていただいて
ありがとうございます!
曜日を表示させたいのですがご指導お願いします。
"水曜日"
この記述に差し換えた後、フォームの計算式 DATE_FORMAT(日付, "YYYY/MM/dd", "Asia/Tokyo") この部分を DATE_FORMAT(日付, "dddd", "Asia/Tokyo") [ Asia/Tokyo ] これは何を記入すればいいのでしょうか
yama さま
お世話になっております。cybozu developer network 事務局です。
DATE_FORMAT 関数 を利用した記述方法は、kintone の標準機能のみで日時フィールドのフォーマットを行いたいときに使用いたします。
DATE_FORMA 関数についてのくわしい使い方についてはこちらのヘルプページをご覧ください。
本記事で紹介しております JavaScript カスタマイズを行い、
Moment.js で曜日を表示する際には、サンプルコードにあるように以下の記述でフォーマットすることができます。
また、Moment.js はメンテナンスモードになり、日付処理できる代替ライブラリへの移行が推奨されています。
代替ライブラリのひとつ Luxon については、kintone カスタマイズでの導入方法の紹介記事があります。
あわせてご確認いただけると幸いです。
初心者ですいません。
サンプルプログラム(2020/08/04にする分)をJSEdit for kintoneにコピーして保存しました。
つぎに日付の設定 のフィールド名 フィールドコードを日付に変えました
表示されません。さらにレコードの編集の所で保存もききません。
どうしたらいいですか?
赤松大史 様
お世話になっております。cybozu developer network 運営でございます。
この記事の内容をさらにカスタマイズされたいとお見受けします。
恐れ入りますが、こちらのコメント欄は記事内容のフィードバック目的となっているため、
記事から派生した技術的なご質問はcybozu developer コミュニティをご活用ください。
よろしくお願い致します。
お世話になっております。
日時フォーマットを現在からの経過時間(相対表示)に変更
にて更新日の表示を変えたのですが英語表記となってしまっています。
https://js.cybozu.com/momentjs/2.29.1/moment-with-locales.min.js
デモサイトでは日本語表記となっているため
でもサイトのmomentのjsを同じものにしましたが改善されませんでした。
アドバイスあればご教示いただけます。
よろしくお願いいたします。
青山昌司 様
お世話になっております。cybozu devloper network 事務局です。
記事に掲載しているサンプルコードにて動作確認をしたところ、日本語表記であることを確認いたしました。
日時フォーマットを現在からの経過時間(相対表示)に変更 のサンプルコードの 12 行目のとおり、
「ロケールの初期化」は行っていますでしょうか。
こちらのコメント欄は記事内容のフィードバック目的となっているため、
サンプルコードをもとにカスタマイズをするなど、記事から派生した技術的な質問は
cybozu developer コミュニティをご活用ください。
お世話になっております。
「ロケールの初期化」は行っています。
下記プラグインをインストールしている影響でしょうか?
下記プラグインを無効にしたところ正しく表示されました。
以上ご確認のほどよろしくお願いします
青山昌司 様
お世話になっております。cybozu developer network 運営でございます。
プラグインやJavaScriptカスタマイズの兼合いでそのようになる可能性はございます。
毎回Localeを指定する(具体的には当記事のコードでいうとレコード詳細表示イベントハンドラ内で行う)ようにすると改善されるかもしれませんが、
恐れ入りますが、こちらのコメント欄は記事内容のフィードバック目的となっているため、
記事から派生した技術的なご質問はcybozu developer コミュニティをご活用ください。
よろしくお願い致します。
お世話になっております。
一部変更をし、JSEdit for kintone にコピーしたところ4行目にて moment is not defined とエラーが出てしまっております。
エラー箇所は変更していないのですが、何が問題なのでしょうか。
変更後のコード
nekoko 様
お世話になっております。cybozu developer network 事務局です。
恐れ入りますが、こちらのコメント欄は記事内容のフィードバック目的となっているため、
記事から派生した技術的なご質問は cybozu developer コミュニティをご活用ください。
ご質問新規投稿の際「良い質問をするためのガイド」というものが表示されますので、
それに沿ってエラーの詳細などを記載いただくと回答がつきやすくなると存じます。
よろしくお願い致します。