一覧の「モーダルで開く」を新規作成にも使う
テーブルの管理の「一覧の編集方式」を「モーダルで開く」(GridEditorType = Dialog)にすると、一覧の行をクリックしたときに編集画面がモーダルで開きます。ただしモーダルになるのは既存レコードの編集だけで、「新規作成」は通常どおり別画面に遷移します。このページは、新規作成もモーダルで行うための本体改修の設計メモです。本体の標準機能ではありません。
前提にした現行実装
1.5.8.1 のソースで確認した内容です。
一覧の編集方式
GridEditorType は None = 0(別画面)、Grid = 10(一覧上で直接編集)、Dialog = 20(モーダルで開く)の 3 つです(SiteSettings.cs)。Dialog のとき、一覧画面に #EditorDialog とその中の #EditInDialogBody が出力されます(HtmlEditor.cs)。
既存レコードをモーダルで編集する流れ
図を読み込み中…
- 行クリックのハンドラは
#EditorDialogがあればEditInDialog = trueを付けて Ajax で送ります(gridevents.js)。 - サーバーは
EditInDialogを見て、#EditInDialogBodyに HTML を入れてopenEditorDialogを呼ぶ応答を返します(ResultUtilities.cs)。 - モーダル内のフォーム
#DialogEditorFormにはIsDialogEditorForm = 1の hidden があり、ボタンは「更新」と「キャンセル」だけです。「作成」ボタンはありません(HtmlEditor.cs)。 - フォームの送信先は
referenceIdが0ならsiteIdになるので、新規作成の送信先としてはそのまま使えます(HtmlEditor.cs)。 - 更新時は
IsDialogEditorFormを見て、一覧の該当行を描き直してダイアログを閉じます(ResultUtilities.cs)。
新規作成が別画面になる理由
- ナビゲーションメニューの「新規作成」は
<a href="Items/{SiteId}/New">で、GridEditorTypeを見ていません(HtmlNavigationMenu.cs)。 - 作成後の動作(
AfterCreateActionType)は、既定(作成したレコードの編集画面)・一覧に戻る・新規作成画面を開く、のどれもHrefによる画面遷移です(ResponseCollection.cs)。
「一覧上で直接編集」(Grid)には一覧に入力行を足す NewOnGrid があります(ResultUtilities.cs)が、モーダルとは別の仕組みです。
改修箇所
図を読み込み中…
1. ダイアログに「作成」ボタンを出す
DialogEditorForm に MethodType を渡せるようにし、新規なら action: "Create"・method: "post" のボタン、編集なら現行の「更新」ボタンを出し分けます。呼び出し元(ResultUtilities.cs・IssueUtilities.cs・WikiUtilities.cs)の引数も合わせて変えます。
2. 新規ボタンからモーダルを開く
#EditorDialog があるときは新規ボタンのクリックでページ遷移を止め、EditInDialog = true を付けて Items/{SiteId}/New に Ajax で送ります。href は残しておけば、モーダルを使わない設定ではそのまま遷移します。
$(document).on('click', '#NewMenuContainer a', function (e) {
if ($('#EditorDialog').length !== 1) return;
e.preventDefault();
$p.ajax($(this).attr('href'), 'post', { EditInDialog: true });
});EditorResponse は ResultId が 0 なら MethodType を New にするので(ResultUtilities.cs)、EditInDialog の分岐はそのまま新規でも通ります。フォルダ(サイト一覧)の新規作成はテンプレート選択になるので、この分岐から外します。
3. Create の応答をモーダル向けにする
Create の成功時に IsDialogEditorForm を見て、AfterCreate の画面遷移の代わりにモーダル向けの応答を返します。ページングやソートがあるので、行を 1 行足すより一覧全体を再読み込みするほうが安全です。
| AfterCreateActionType | モーダルでの動作 |
|---|---|
| 既定(編集画面) | 作成したレコードの編集フォームをモーダル内に読み込み直す |
| 一覧に戻る | モーダルを閉じて一覧を再読み込みする |
| 新規作成画面を開く | モーダル内を空の新規フォームにする |
プロセス機能で作成時に動くアクションがある場合も、モーダル向けの応答で扱う必要があります。
4. 新規レコードで ID を前提にしている処理
モーダル内では #EditorInDialogRecordId を使ってレコード ID を取る処理があります。新規では ID が 0 なので、サイト ID にフォールバックする処理を足します。
| ファイル | 処理 |
|---|---|
generals/video.js | カメラ画像のアップロード先の URL |
generals/dropdownsearch.js | ドロップダウン検索の送信先 |
generals/_controllevents.js | 自動ポストバックの送信先(ダイアログ内ではフォームと ID を差し替える) |
改修するファイル
| ファイル | 内容 |
|---|---|
Libraries/HtmlParts/HtmlEditor.cs | DialogEditorForm に MethodType を渡し、作成・更新ボタンを出し分ける |
Libraries/HtmlParts/HtmlNavigationMenu.cs または新規 JS | 新規ボタンのクリックでモーダルを開く |
Models/Results/ResultUtilities.cs・Models/Issues/IssueUtilities.cs | Create にモーダル向けの応答を足す(CodeDefiner のテンプレートも) |
Libraries/Responses/ResponseCollection.cs | AfterCreate のモーダル向けの分岐 |
generals/video.js・generals/dropdownsearch.js | ID が 0 のときのフォールバック |