ブラウザ標準ダイアログ(alert・confirm・離脱警告)の置き換え
プリザンター本体は、エラー通知や確認にブラウザ標準の alert()・confirm() を、未保存時の離脱警告に beforeunload を使っています。ブラウザ標準のダイアログは見た目を変えられません。このページは、これらを本体の他のダイアログと同じ見た目に揃えるための設計メモです。本体の標準機能ではありません。
拡張スクリプトだけで使える確認ダイアログは モーダルダイアログのラッパー にあります。
使用箇所(1.5.8.1)
ファイルは Implem.PleasanterFrontend/wwwroot/src/scripts/ 配下です。
alert()
| ファイル | 箇所 | 表示内容 |
|---|---|---|
| generals/clipboard.js | URL のコピー完了 | DirectUrlCopied |
| generals/fieldselectable.js | 列の移動(ダイアログ外の操作) | 固定文字列 outsideDialog |
| generals/fieldselectable.js | 必須の列を外そうとしたとき | 画面上のメッセージ要素の値 |
| generals/_ajax.js | $p.ajax の失敗(400・403) | BadRequest・UnauthorizedRequest |
| generals/_ajax.js | 2 つ目の送信関数の失敗(400・403) | BadRequest・UnauthorizedRequest |
| generals/passkey.ts ほか 9 か所 | パスキーが使えない・操作の中断・タイムアウトなど | PasskeyNotAvailable など |
_ajax.js では、接続エラー・502〜504・その他のサーバーエラーはすでに $p.setErrorMessage で画面上部に表示しています(_ajax.js)。alert() が残っているのは 400 と 403 だけです。
confirm()
| ファイル | 箇所 | 表示内容 |
|---|---|---|
| generals/_ajax.js | ボタンの data-confirm 属性(送信前の確認) | 属性値 |
| generals/lockevents.js | レコードのロック解除 | ConfirmUnlockRecord |
| generals/sitesettings.js | ダッシュボードのパーツのビューのリセット(タイムライン・カレンダー・かんばん・一覧) | ResetTimeLineView など 4 種 |
| generals/confirm.js | $p.confirmReload(未保存のまま画面内で移動する) | ConfirmUnload |
| modules/editorColumns/toastmenubuttons.ts | エディタの列のリセットと無効化 | ConfirmResetAndDisable |
data-confirm はサーバー側の HtmlAttributes.DataConfirm で付きます(HtmlAttributes.cs)。コメントの削除(ConfirmDelete)、テナント・ユーザーの切り替え(ConfirmSwitchTenant・ConfirmSwitchUser)、confirm 引数を受け取る汎用のボタン(HtmlControls.cs)で使われ、履歴の「復元」「削除」などもこの仕組みです。$p.send 側を変えると、これらすべてに影響します。
beforeunload
| ファイル | 内容 |
|---|---|
| generals/confirmevents.js | $p.formChanged が true なら離脱警告を出す |
| generals/jqueryui.js | テーブルの管理のシンプルモード切り替え中に、元の onbeforeunload を退避する |
Implem.Pleasanter/wwwroot/components/ のビルド済みバンドル | スマートデザイン(Svelte)の画面が window.onbeforeunload を設定・解除する |
置き換え先
| 置き換え先 | テーマ | 用途 |
|---|---|---|
$p.setMessage・$p.setErrorMessage(message.js) | 共通 | 通知。画面上部の #Message か、ダイアログ内の .message-dialog に出し、操作を止めない |
jQuery UI Dialog($p.openDialog、dialog.js) | 1 世代目 | 確認。テーマの配色に合う |
<ui-modal>(ui-modal.ts) | 2 世代目 | 確認。<dialog> 要素を使う Web Component で、header・既定・footer のスロットを持ち、表示中は body のスクロールを止める。id を付けると $p.modal[id] で参照でき、open プロパティで開閉する |
テーマの世代は Context.ThemeVersion() が決めます。cerulean・green-tea・mandarin・midnight が 2.0、それ以外が 1.0 です(Context.cs)。
図を読み込み中…
通知(alert)の置き換え
// 置き換え前
alert($p.display('DirectUrlCopied'));
// 置き換え後
$p.clearMessage();
$p.setMessage('#Message', JSON.stringify({
Css: 'alert-success',
Text: $p.display('DirectUrlCopied')
}));確認(confirm)の置き換え
confirm() はその場で true/false を返しますが、独自のダイアログは結果があとで返ります。呼び出し元を Promise(async/await)に書き換える必要があります。
// ui-modal で確認して結果を返す例
function showConfirm(message) {
return new Promise(function (resolve) {
var modal = $p.modal.ConfirmModal;
document.getElementById('ConfirmModalBody').textContent = message;
document.getElementById('ConfirmOk').onclick = function () {
modal.open = false;
resolve(true);
};
document.getElementById('ConfirmCancel').onclick = function () {
modal.open = false;
resolve(false);
};
modal.onClosed = function () { resolve(false); };
modal.open = true;
});
}<ui-modal id="ConfirmModal">
<div slot="header"><h3>確認</h3></div>
<div id="ConfirmModalBody"></div>
<div slot="footer">
<button type="button" id="ConfirmOk">OK</button>
<button type="button" id="ConfirmCancel">キャンセル</button>
</div>
</ui-modal>$p.send の data-confirm は return false で送信を止めているので(_ajax.js)、確認後に送信を続ける形に作り替えることになります。
未保存時の離脱警告
現行の仕組み
.confirm-unload内の入力が変わると$p.setFormChangedが$p.formChanged = trueにします。not-set-form-changedクラスの要素は対象外です(confirmevents.js)。- 保存に成功すると、サーバーの応答の
SetMemory("formChanged", false)でフラグが戻ります(_dispatch.js)。 - ブラウザの操作で離れるときは
beforeunload、画面内の移動では$p.confirmReload()のconfirm()で警告します。
$p.confirmReload() を呼んでいるのは次の 3 か所です。
| ファイル | 操作 |
|---|---|
| item.js | $p.get(前へ・次へ、再読み込みなど) |
| grid.js | $p.editOnGrid(一覧上で直接編集をやめる) |
| gridevents.js | 履歴の一覧の行クリック(版の切り替え) |
置き換えられる範囲
| 操作 | 現行 | 独自 UI |
|---|---|---|
| ブラウザの戻る・進む、タブを閉じる、再読み込み、URL の入力、ブックマーク | beforeunload | できない |
| 前へ・次へ、履歴の版の切り替え、直接編集の終了 | $p.confirmReload() | できる(呼び出し元の非同期化が必要) |
| 画面内のリンクのクリック | beforeunload | できる(クリックを横取りして確認してから遷移する) |
beforeunload ではブラウザが決めた文言のダイアログしか出せず、ハンドラー内で独自のダイアログを出して待つこともできません。ブラウザ操作による離脱まで含めて完全に独自の UI にすることはできません。
画面内のリンクを横取りする場合、本体の anchorevents.js が a のクリックで stopPropagation() しているので、イベントの登録先と順番に注意します。遷移を決めたら $p.formChanged = false にしてから移動し、beforeunload の警告が重ねて出ないようにします。
| 方法 | 本体改修 | 範囲 |
|---|---|---|
$p.confirmReload を非同期化 | 必要(3 か所の呼び出し元も) | 前へ・次へ、履歴の切り替え、直接編集の終了 |
| リンクのクリックを横取り | 拡張スクリプトでも可 | 画面内のリンク |
| 何もしない | 不要 | ブラウザ操作はどの方法でも標準のまま |
関連ページ
- モーダルダイアログのラッパー
- 編集画面のカスタマイズ(誤って閉じたページの入力データを復旧する)
- スクリプトのイベント