LoginSignup
4
1

More than 3 years have passed since last update.

kintoneで相対日付のバリデーションを行う

Last updated at Posted at 2020-03-04

先日kintoneで宣言的にフィールド値の検証を行うという記事を投稿しました。Tynderというライブラリを使い、型宣言を書くことで、(手続き的ではなく)宣言的に入力値の検証を行いました。

今回はその応用編として、日付や日付時刻型のフィールドを相対日付(例えば、今月、来月、今年、今年度)で検証します。
さらに、フィールドのエラーに合ったカスタムエラーメッセージを表示するようにします。

kintone-custom-dt-validation.png

コード

// アプリのレコード型を定義します
// interfaceの各フィールドは、kintoneアプリのフィールドコードと一致させてください
const definition = `
/** サブテーブル */
interface Table {
    itemName: string;
    itemValue: number;
}

/** アプリ */
interface App {
    /** 名称 */
    @minLength(2) @maxLength(16)
    @match(/^[A-Z][0-9]{3}-.+/)
    name: string;

    /** 数量 (非必須) */
    amount?: number;

    /** 期日 */
    @stereotype('lcdate') // ローカルタイムゾーン日付
    @range('=today first-date-of-mo', '=today last-date-of-mo')
    @msg({
        valueRangeUnmatched: '当月の日付を入力してください',
    })
    dueDate: string;

    /** 最終接点日時 */
    @stereotype('lcdatetime') // ローカルタイムゾーン日付時刻
    @minValue('=today first-date-of-mo') @lessThan('=today last-date-of-mo +1day')
    @msg({
        valueRangeUnmatched: '当月の日付時刻を入力してください',
    })
    contactDt: string;

    /** サブテーブル */
    table: Table[];
}
`;

// イベントハンドラ
kintone.events.on([
    'app.record.create.submit',
    'mobile.app.record.create.submit',
    'app.record.edit.submit',
    'mobile.app.record.edit.submit',
    'app.record.index.edit.submit',
    ], function(event) {
    event.record = removeBlankTableRow(event.record, 'table');

    // スキーマ検証を行います
    const schema = tynder.compile(definition);
    const ctx = {
        checkAll: true,
        schema,
        stereotypes: new Map(tynder.stereotypes),
        // 共通のカスタムエラーメッセージ
        errorMessages: {
            required:             '必須です',
            valueLengthUnmatched: '値は%{minLength}から%{maxLength}の長さで入れてください',
            valueRangeUnmatched:  '値は%{minValue}から%{maxValue}の間で入れてください',
            typeUnmatched:        '値の形式が間違っています',
        },
    };

    const unknownInput = mapRecord(event.record);
    const validated = tynder.validate(unknownInput, tynder.getType(schema, 'App'), ctx);
    if (! validated) {
        const errText = JSON.stringify(ctx.errors, null, 2);
        console.error(errText);

        // エラーを表示します
        displayValidationErrorMessages(event, ctx);
    }
    return event;
});

日付時刻数式

  • 今月(日付)
    • @range('=today first-date-of-mo', '=today last-date-of-mo')
  • 今月(日付時刻)
    • @minValue('=today first-date-of-mo') @lessThan('=today last-date-of-mo +1day')
  • 来月(日付)
    • @range('=today first-date-of-mo +1mo', '=today @1day +1mo last-date-of-mo')
  • 来月(日付時刻)
    • @minValue('=today first-date-of-mo +1mo') @lessThan('=today @1day +1mo last-date-of-mo +1day')
  • 今年(日付)
    • @range('=today first-date-of-yr', '=today last-date-of-yr')
  • 今年(日付時刻)
    • @minValue('=today first-date-of-yr') @lessThan('=today last-date-of-yr +1day')
  • 来年(日付)
    • @range('=today first-date-of-yr +1yr', '=today @1day +1yr last-date-of-yr')
  • 来年(日付時刻)
    • @minValue('=today first-date-of-yr +1yr') @lessThan('=today @1day +1yr last-date-of-yr +1day')
  • 今年度(date)
    • @range('=today first-date-of-fy(4)', '=today first-date-of-fy(4) +1yr -1day')
      • 4月始まり
  • 今年度(datetime)
    • @minValue('=today first-date-of-fy(4)') @lessThan('=today first-date-of-fy(4) +1yr')
      • 4月始まり
  • 来年度(日付)
    • @range('=today first-date-of-fy(4) +1yr', '=today first-date-of-fy(4) +2yr -1day')
      • 4月始まり
  • 来年度(日付時刻)
    • @minValue('=today first-date-of-fy(4) +1yr') @lessThan('=today first-date-of-fy(4) +2yr')
      • 4月始まり

詳しくは https://github.com/shellyln/tynder#date--datetime-stereotypes を参照してください。

型宣言のテストについて

記述した型宣言が文法的に正しいかどうかは以下のサイトで確認できます。
https://shellyln.github.io/tynder/playground2.html

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1