コンテンツにスキップ

$p.events.after_validate

概要

バリデーションチェックを行った後に実行するメソッドの指定方法を説明します。項目に入力した値が正しいかをチェックするときに使用してください。

制限事項

  1. 複数のスクリプトを作成し各スクリプトの内容に本関数を記述すると、スクリプトが上書きされるため、最新のもの以外は動作しません。回避策は以下FAQを参照してください。

構文

JavaScript

$p.events.after_validate = function (args) {
    //処理内容
}
または
$p.events.after_validate_{data-action属性の値} = function (args) {
    //処理内容
}

※イベントを発生させるボタンのdata-action属性の値を明示的に記述したい場合は取得してください。

使用例

以下のサンプルコードをプリザンターのスクリプトへ設定し出力先は「編集」にした後、編集画面で数値Aに100を入力して「更新」ボタンを押したときのみ更新されます(当例ではdata-action属性の値であるUpdateを明示的に記載してます)。

JavaScript
$p.events.after_validate_Update = function (args) {
    return ($p.getControl('NumA').val() != 100
        ? false //falseのときは処理が止まり、更新されない
        : true  //trueのときは更新される
    );
}

サンプルコード

1. 予約を確定するとき、同じ設備の確定済みの予約と時間帯が重なれば止める

設備予約の編集画面で、プロセス「予約確定」のボタンを押したとき、標準の入力検証を通ったあとに、同じ設備の確定済みの予約と時間帯が重なっていないかを$p.apiGetで調べます。重なりがあれば相手の予約の件名・ID・時間帯を表示して確定を止め、無ければそのまま確定します。仮予約としての保存(通常の保存)では何もしません。

実務での使いどころ

会議室・社用車・貸出機器などの予約で、二重予約を防げます。標準の「重複禁止」は1つの項目の値が同じかどうかしか見ず、プロセスの条件や入力検証でも、ほかの予約との時間帯の重なりは判定できません。確定のボタンを押したその場で、どの予約と重なっているかを見せて、直してもらえます。仮予約どうしは重なってもよい運用にできます。

事前準備

1:「設備予約」テーブル(期限付きテーブル)で、以下の項目を設定してください。

項目コード 内容
分類A(ClassA) 設備(会議室A・会議室Bなど)
開始(StartTime) 書式を「日付と時刻(分)」にする。入力必須
完了(CompletionTime) 書式を「日付と時刻(分)」にする。入力必須
状況(Status) 100 仮予約、200 確定

開始・完了の書式は、運用を始める前に設定してください。書式が「年月日」のままだと時刻を比べられません。また、「年月日」で保存した完了は、あとで書式を変えると1日後の日時で表示されます。

2:「テーブルの管理 > プロセス」で、プロセス「予約確定」(現在の状況:仮予約、変更後の状況:確定、アクション種別:保存)を作成してください。このサンプルは、最初に作成したプロセス(ボタンのIDがProcess_1)を前提にしています。

3:スクリプトを登録します。

3-1:「テーブルの管理 > スクリプト」タブで「新規作成」を選択する。
 3-2:タイトル: 任意の名前(例:checkBookingOverlap)
 3-3:スクリプト: 下記サンプルコードを貼り付け
 3-4:出力先:「すべて」のチェックを外し、「編集」にチェック

JavaScript
/**
 * ================================================================
 * サンプル  予約を確定するとき、同じ設備の確定済みの予約と時間帯が重なれば止める
 * ================================================================
 *
 * 【概要】
 *   設備予約の編集画面で、プロセス「予約確定」のボタンを押したとき、標準の入力検証を
 *   通ったあとに、同じ設備の確定済みの予約と時間帯が重なっていないかを調べます。
 *   重なりがあれば相手の予約を表示して確定を止め、無ければそのまま確定します。
 *   仮予約としての保存(通常の保存)では何もしません。
 *
 * 【使い方】
 *   出力先:編集
 *   開始・完了の書式は「日付と時刻(分)」にしてください(年月日のままだと時刻を比べられません)。
 * ================================================================
 */

// 設備の項目と、「確定」の状況の値
const FACILITY_COLUMN = 'ClassA';
const CONFIRMED_STATUS = 200;
// 重なりを確かめ終えて、プロセスを実行し直すときに立てる印
let overlapChecked = false;

function showError(text) {
    $p.clearMessage();
    $p.setMessage('#Message', JSON.stringify({ Css: 'alert-error', Text: text }));
}

// API の日時(2026-10-20T10:00:00)を「2026/10/20 10:00」にする
function formatDateTime(value) {
    return value.replace('T', ' ').replace(/-/g, '/').slice(0, 16);
}

// プロセス「予約確定」(Process_1)のボタンを押し、標準の入力検証を通ったときに呼ばれる
$p.events.after_validate_Process_1 = function (args) {
    if (overlapChecked) {
        // 確かめ終えて実行し直したときは、そのまま通す
        overlapChecked = false;
        return true;
    }
    const $button = args.$control;
    const start = new Date($p.getValue('StartTime'));
    const end = new Date($p.getValue('CompletionTime'));
    // 同じ設備で確定済みの予約を取得する(分類項目は配列形式+ExactMatchMultipleで完全一致)
    $p.apiGet({
        id: $p.siteId(),
        data: {
            View: {
                ColumnFilterHash: {
                    [FACILITY_COLUMN]: JSON.stringify([$p.getValue(FACILITY_COLUMN)]),
                    Status: JSON.stringify([String(CONFIRMED_STATUS)]),
                },
                ColumnFilterSearchTypes: { [FACILITY_COLUMN]: 'ExactMatchMultiple' },
            },
        },
        done: function (data) {
            // 自分以外で、開始が相手の完了より前、かつ完了が相手の開始より後なら重なり
            // (ちょうど接するだけの予約は重なりにしない)
            const overlaps = data.Response.Data.filter((item) => item.IssueId !== $p.id()
                && start < new Date(item.CompletionTime)
                && end > new Date(item.StartTime));
            if (overlaps.length > 0) {
                const list = overlaps
                    .map((item) => `${item.Title}(ID:${item.IssueId}、${formatDateTime(item.StartTime)}〜${formatDateTime(item.CompletionTime)})`)
                    .join('、');
                showError(`同じ設備の確定済みの予約と時間帯が重なっています:${list}`);
                return;
            }
            overlapChecked = true;
            $p.execProcess($button);
        },
        fail: function () {
            showError('確定済みの予約を確認できませんでした。');
        },
    });
    // 検索は非同期のため、いったん送信を止める(重ならなければ、done の中で実行し直す)
    return false;
};

注記

  • $p.events.after_validate_Process_1のように、関数名の末尾にはプロセスのボタンのIDも付けられます。そのボタンを押したときのみ動きます。
  • 標準の入力検証(入力必須など)でエラーになったときは、after_validateは呼ばれません。
  • 検索は非同期のため、いったんfalseを返して送信を止め、重なりが無ければ$p.execProcessでプロセスを実行し直します。実行し直したときは、印(overlapChecked)を見てそのまま通します。
  • 画面での確認のため、APIや一括更新で状況を変えた場合は止められません。また、確認している間に別の人が同じ時間帯を確定することは防げません。必ず止めたい場合は、サーバスクリプトのcontext.Errorで同じ判定を行ってください。

関連情報

FAQ:$p.events.on_editor_loadを複数設定できるようにしたい