自動ポストバックでのセクション表示切り替え
サーバースクリプトで siteSettings.Sections[i].Hide を変えても、自動ポストバックでは画面に反映されません。このページは、本体を改修して反映させるための設計メモです。本体の標準機能ではありません。
改修せずに回避する方法(context.AddResponse、スクリプトの ajax_after_done)と、反映されない理由は セクション(見出し)の制御 にまとめています。
前提にした現行実装
1.5.8.1 のソースで確認した内容です。
- 初期描画の
Fieldsは、Hideがtrueのセクションを HTML に出力しません(IssueUtilities.cs)。 - 自動ポストバックの応答を作る
EditorFieldsは、FieldResponseで項目の値を返すだけで、セクションには触れません(IssueUtilities.cs)。 - 応答コマンド
Toggleはすでにあり、ブラウザ側で jQuery の.toggle(value === '1')を実行します(ResponseCollection.cs、_dispatch.js)。 IssueUtilities.csとResultUtilities.csは CodeDefiner がテンプレートから生成するコードです。セクションの描画はModel_Utilities_EditorItem_Body.txt(L667)、EditorFieldsはModel_Utilities_EditorResponse_Tables_Body.txt(L60)が元です。- Wiki は自動ポストバックでも
#MainContainerを丸ごと描き直すので、改修は不要です(WikiUtilities.cs)。
改修方針
2 つの変更を組み合わせます。
- 初期描画:
Hideがtrueのセクションもdisplay:noneを付けて出力する。出力しないままだと、あとで表示に切り替える要素が画面に存在しない。 - 自動ポストバック:
EditorFieldsの応答に、セクションごとのToggleを足す。
図を読み込み中…
1. 初期描画で非表示セクションも出力する
section.Key.Hide != true の条件を外し、HtmlAttributes.Style("display:none;", _using: section.Key.Hide == true) をコンテナの Div に付けます。
| 改修前 | 改修後 | |
|---|---|---|
Hide = true のセクション | 出力しない | display:none 付きで出力する |
| セクション内の項目 | 画面に存在しない | 存在する(非表示) |
| 送信データ | 含まれない | 含まれる |
非表示のセクションの項目も送信されるようになります。既存レコードは保存済みの値がそのまま送られ、新規作成では既定値が送られます。
2. 自動ポストバックの応答に Toggle を足す
Libraries/Responses/ に拡張メソッドを新しく作り、EditorFields の .FieldResponse(...) の直後で呼びます。
csharp
public static class ResponseSections
{
public static ResponseCollection SectionToggleResponse(
this ResponseCollection res, SiteSettings ss)
{
ss.Sections?.ForEach(section => res.Toggle(
name: $"#SectionFields{section.Id}Container",
value: section.Hide != true));
return res;
}
}Section.Hide | 送る値 | 結果 |
|---|---|---|
null・false | 1 | 表示 |
true | 0 | 非表示 |
改修するファイル
| ファイル | 内容 | 種類 |
|---|---|---|
Libraries/Responses/ResponseSections.cs | SectionToggleResponse を新しく作る | 手で追加 |
App_Data/Definitions/Definition_Code/Model_Utilities_EditorResponse_Tables_Body.txt | EditorFields に .SectionToggleResponse(ss: ss) を足す | テンプレート |
App_Data/Definitions/Definition_Code/Model_Utilities_EditorItem_Body.txt | セクションの出力条件を Style("display:none;") に変える | テンプレート |
Models/Issues/IssueUtilities.cs・Models/Results/ResultUtilities.cs | 上のテンプレートから CodeDefiner で生成する | 生成 |
CodeDefiner との関係
生成済みの .cs を直接直すと、CodeDefiner を実行し直したときに上書きされることがあります。選択肢は 3 つです。
| 方法 | 内容 | 注意点 |
|---|---|---|
| テンプレートを直す | _Body.txt を修正し、CodeDefiner で生成し直す | 本体を更新するときにテンプレートの差分を取り込み直す |
| 生成コードを直して保護する | メソッドのドキュメントコメントに /// Fixed: を書く。CodeDefiner はこのメソッドをマージしない(Parser.cs) | メソッド単位でしか保護できない |
| 新しいファイルだけ足す | ResponseSections.cs は生成対象外なので安全 | EditorFields の呼び出し 1 行と描画条件の変更は、結局生成コードに入れる必要がある |
制約
- 追加タブ内のセクションも同じ
Fieldsで描画されるので、どのタブのセクションにも効きます。 Toggleはセクション全体(#SectionFields{ID}Container)の表示だけを切り替えます。折りたたみの状態(#SectionFields{ID}のhiddenクラス)は変わりません。- 「自動ポストバック時に返却する列」(
ColumnsReturnedWhenAutomaticPostback)で返す列を絞っていても、セクションは列ではないのでToggleは常に送られます。