columns の内部構造と適用範囲
サーバースクリプトの columns.項目名(columns['ClassA'] のようにも書けます)で変更できるのは、ラベル・一覧の表示値・読み取り専用・非表示・必須・CSS・前後の HTML・選択肢の 15 種類だけです。正規表現チェック、数値の最小値・最大値、入力ガイド、説明文などは変更できません。 ServerScriptModelColumn にプロパティがなく、反映処理も存在しません。
また、columns と model.ExtendedRowCss による一覧のスタイル指定が効くのは、一覧とリンクテーブル(レコードの行を描く画面)だけです。カレンダー・クロス集計・ガントチャート・時系列チャート・カンバンでは「行表示の前」のスクリプトが呼ばれないので反映されません。
行全体と項目単位の違い
一覧の 1 レコードは行(tr)、その中の各項目はセル(td)として描かれます。model はレコード値と行全体の設定、columns.項目名 はその項目の表示・入力設定を扱います。公式マニュアルの columns にはプロパティ、使用例、Hide と RawText の優先関係が載っています。このページでは、実行条件によって設定がどこまで伝わるか、代入が反映されない境界、CSV など画面以外への影響を追います。
| 変更したい範囲 | 指定する値 | 反映先 |
|---|---|---|
| 行全体 | model.ExtendedRowCss | 行の <tr> の CSS クラス |
| 特定の項目の一覧セル | columns.ClassA.ExtendedCellCss | ClassA のセルの CSS クラス |
| 特定の項目の一覧表示内容 | columns.ClassA.RawText | ClassA の表示内容 |
| 特定の項目の入力欄 | columns.ClassA.ReadOnly など | 項目の描画・入力チェック |
| 項目の値そのもの | model.ClassA | レコードモデルの項目値 |
一覧の行は model.ExtendedRowCss を <tr> に付け、各セルは項目ごとの設定を読んで描画します(行の生成、セルの生成)。columns の設定は項目の値を代入するものではありません。値を変える場合は model を使います。
// 条件: 行表示の前
if (model.Status === 900) {
model.ExtendedRowCss = 'completed-row';
columns.ClassA.ExtendedCellCss = 'completed-cell';
columns.ClassA.RawText = '完了';
}.grid tr.completed-row td { background-color: #e8f5e9; }
.grid td.completed-cell { font-weight: bold; }この例では行の背景と ClassA セルの太字を別々に指定します。RawText は一覧の表示を差し替えるための値であり、model.ClassA の保存値は変更しません。
仕組み
columns は「項目名 → ServerScriptModelColumn」という形です。対象名は、参照先テーブルの定義にある項目名と、サイト設定の一覧項目名から集められます。各項目の初期値には、サイト設定のラベルや読み取り専用などの値が入ります。スクリプト実行後はサイト設定の ColumnHash にある項目だけが反映対象になります(Columns()、SetColumns())。
項目名の作り方は次の連結です。エディタに見えている項目だけを走査しているわけではありません。
.Where(definition => definition.TableName == ss?.ReferenceType)
.Select(definition => definition.ColumnName)
.Concat(ss.GridColumns)
.Distinct()ServerScriptUtilities.Columns() の抜粋です。
columns の各項目は ServerScriptModelColumn クラスのインスタンスです。プロパティごとに「変更されたか」のフラグを持ち、スクリプトで代入するとフラグが立ちます(ServerScriptModel.cs#L192-L335)。実行後、フラグが 1 つでも立っている項目だけが結果(ServerScriptModelRow.Columns)に残ります(ServerScriptUtilities.cs#L701-L722)。
if (serverScriptColumn.Changed())
{
scriptValues[datam.Key] = serverScriptColumn;
}SetColumns() の抜粋です。これにより、読み取っただけの項目は結果へ渡りません。
図を読み込み中…
画面やチェックの側は、Column.GetReadOnly()・GetHide()・GetValidateRequired() のように「スクリプトで変更されていればその値、されていなければサイト設定の値」を返すメソッドを通して値を読みます(Column.cs#L971-L1010)。ラベル・拡張 HTML・フィールド CSS・コントロール CSS は、HTML 生成時にスクリプトの値が空ならサイト設定の値へ戻ります(ラベルと拡張 HTML、フィールドとコントロールの CSS)。セル CSS は後述のとおり、サイト設定の値へ追加する別の処理です。この仕組みを通らないプロパティは、スクリプトから変えられません。
ページ単位と行単位の実行
「画面表示の前」の結果は SiteSettings.GetServerScriptModelRow() にキャッシュされ、ページの組み立てに使われます。一覧の「行表示の前」は対象レコードごとに実行されます(ページのキャッシュ、行ごとの実行)。項目ラベルやエディタの設定を変える場合と、一覧の各セルをレコード値で装飾する場合では、実行条件と画面要素が生成される時点を分けて考えます。
SetServerScriptModelColumns() は、変更した項目の ServerScriptModelColumn をサイト設定の Column に結び付けます。選択肢は ChoiceHash へ別に変換します(反映処理)。
column.ServerScriptModelColumn = scriptColumn.Value;この代入のあと、HTML の生成や入力チェックが Column を通してスクリプト結果を読みます。
| 実行条件 | itemModel | columns の結果の行き先 | 用途 |
|---|---|---|---|
| サイト設定読み込み時 | null | SiteSettings の Column | サイト設定を読み込む経路での項目変更 |
| 画面表示の前 | 一覧では実レコードなし(空のモデル)、エディタでは対象レコード | SiteSettings の Column と画面表示前の結果 | ページの項目表示・入力欄 |
| レコード読み込み時 | 読み込んだレコード | レコードモデルの ServerScriptModelRow | 後続の処理に渡す値 |
| 行表示の前 | 一覧の対象レコード | 行ごとの結果と SiteSettings の Column | 行ごとのセル表示 |
「サイト設定読み込み時」は ItemModel.SetSite() から呼ばれ、itemModel: null で実行して SetServerScriptModelColumns() へ渡します。ただし対象サイトと現在の ID が同じで、アクションが edit・update・copy・delete などの場合は実行せず戻ります(呼び出し、除外条件)。
レコード読み込み時の変更が行表示前へ渡る経路
課題を DataRow から組み立てる処理は「レコード読み込み時」を呼び、その後、一覧が同じ IssueModel で「行表示の前」を呼びます(レコード読み込み、行表示前)。ServerScriptUtilities.Columns() は、レコードモデルの ServerScriptModelRow.Columns に同名の項目があれば、それを初期値として再利用します(Columns())。
図を読み込み中…
これが「レコード読み込み時に書いた設定が、次の行表示前の columns で見える」経路です。レコード読み込み時の実行だけでは SetServerScriptModelColumns() を呼ばないので、その結果がサイト設定の Column に結び付くのは、行表示の前などの後続の実行を通ったときです。途中の実行条件に該当するスクリプトが無い場合は結果が作られないため、各段階でスクリプトが実行されるかも確認します。
値を消す代入が効くとは限らない
- 変更フラグは 14 のプロパティすべてにありますが、効き方は読む側で決まります。
ReadOnly・Hide・ValidateRequiredの 3 つは、画面側のGetReadOnly()などが変更フラグを見て判定するので、falseの代入もサイト設定の値を上書きします(Column.cs#L971-L1009)。ReadOnly = falseはステータス制御による読み取り専用(StatusReadOnly)も上書きします。一方、ValidateRequired = falseはcolumn.Requiredやステータス制御の必須条件まで消しません(エディタの required 判定)。 LabelTextや拡張 HTML はStrings.CoalesceEmpty()で空文字を飛ばし、元の設定を使います。RawTextも空なら通常のセル描画に戻ります(HtmlFields.cs、TdExtensions.cs)。ChoiceHashのプロパティ setter 自体は変更フラグを立てません。ChoiceHashだけを直接差し替えても、ほかのプロパティを変えていなければChanged()は偽のままで、結果の辞書から落ちます。選択肢を変えるときは、変更フラグを立てるAddChoiceHash()・ClearChoiceHash()を使います(ServerScriptModel.cs、SetColumns())。
セル CSS と RawText の出力
ExtendedCellCss は Column.CellCss() でサイト設定のセル CSS と文字揃えクラスに追加されます。サイト設定の CSS を置き換える動作ではありません(Column.cs)。
RawText が空でなければ、一覧の通常のセル表示を差し替えます。課題・結果の一覧とリンクテーブルは RawText を HTML としてそのまま出すので、入力値を無加工で連結しないでください(IssueUtilities.TdValue())。CSV 出力でも、行表示前のスクリプトが設定した RawText が空でなければ出力値に採用されます(GridData.cs)。
CSV への経路は ExportUtilities.Export() → ExportUtilities.Csv() → GridData.Csv() → レコードごとの「行表示の前」→ RawText の採用、という順番です。CSV 側は RawText だけを見て、Hide は見ません。JSON 形式のエクスポート(ExportUtilities.Json() → GridData.Json())は「行表示の前」を実行しないので、RawText の影響を受けません。例えば columns.NumA.RawText = '<b>10</b>' とすると、一覧では太字の 10 ですが、CSV 側は RawText の文字列をそのまま出力値に使います。見た目だけを変えたいなら ExtendedCellCss を使い、値の置換が必要なときだけ RawText を使うと出力への影響を分けられます。
課題の一覧セルでは、Hide = true の場合に空の td を返し、RawText や ExtendedCellCss の処理へ進みません。Hide でなければ、非空の RawText、GridDesign、通常の項目値の順に描画経路を選びます(IssueUtilities.TdValue())。複数のプロパティを同時に設定したときは、この分岐順が優先順位になります。
変更できるプロパティ
1.5.8.1 の ServerScriptModelColumn にあるのは次のとおりです(ServerScriptModel.cs#L224-L292)。
| プロパティ | 型 | 内容 |
|---|---|---|
LabelText | string | 項目名(ラベル)。入力ガイドが空のときはプレースホルダーにも使われる |
LabelRaw | string | ラベルを HTML で指定 |
RawText | string | 値の表示を HTML で指定 |
ReadOnly | bool | 読み取り専用 |
Hide | bool | 非表示 |
ValidateRequired | bool | 入力必須 |
ExtendedFieldCss | string | フィールドの CSS クラス |
ExtendedControlCss | string | コントロールの CSS クラス |
ExtendedCellCss | string | 一覧のセル(td)の CSS クラス |
ExtendedHtmlBeforeField | string | フィールドの前の HTML |
ExtendedHtmlBeforeLabel | string | ラベルの前の HTML |
ExtendedHtmlBetweenLabelAndControl | string | ラベルとコントロールの間の HTML |
ExtendedHtmlAfterControl | string | コントロールの後の HTML |
ExtendedHtmlAfterField | string | フィールドの後の HTML |
ChoiceHash | 辞書 | 選択肢。AddChoiceHash(key, value)・AddChoiceHash(value)・ClearChoiceHash() で操作 |
AddChoiceHash を値だけで呼べる形については サーバースクリプトのメソッドを拡張する を参照してください。
// 項目名の変更と、条件付きの必須・読み取り専用
columns.ClassA.LabelText = '取引先コード';
if (model.Status === 900) {
columns.DescriptionA.ReadOnly = true;
} else {
columns.DescriptionA.ValidateRequired = true;
}変更できないプロパティ
次のようなプロパティは ServerScriptModelColumn に無く、画面やチェックは Column(サイト設定)の値を直接読みます。サーバースクリプトで条件によって切り替えることはできません。
| 分類 | プロパティ(サイト設定の項目) | 参照している箇所の例 |
|---|---|---|
| 正規表現チェック | ClientRegexValidation(クライアント)、ServerRegexValidation(サーバー)、RegexValidationMessage(エラーメッセージ) | HtmlFields.cs#L521、IssueValidators.cs#L1363 |
| 型・文字数のチェック | ValidateNumber、ValidateDate、ValidateEmail、ValidateEqualTo、ValidateMaxLength、MaxLength | HtmlFields.cs |
| 入力補助 | Description(説明)、InputGuide(入力ガイド)、DefaultInput(既定値) | HtmlFields.cs#L151-L173 |
| 数値 | Min、Max、Step、DecimalPlaces、Unit | HtmlFields.cs |
| 重複禁止 | NoDuplication、MessageWhenDuplicated | IssueValidators.cs・ResultValidators.cs |
| 表示 | NoWrap、TextAlign、AutoPostBack、Section、FieldCss(サイト設定のフィールド CSS)、GridFormat・EditorFormat・ExportFormat | 一覧のセル、HtmlFields.cs |
代わりにできること
- 必須にしたいだけなら
ValidateRequiredで切り替えられます。 - 入力値の形式を条件によって変えたい場合は、作成前・更新前のスクリプトで
modelの値を調べ、合わなければcontext.Error('メッセージ')で保存を止めます。 - 説明文や注意書きを変えたい場合は、
ExtendedHtmlAfterControlなどで HTML を差し込めます。
変更できないプロパティをスクリプトで変えられるようにする改修案は、columns で変更できるプロパティを増やす にまとめています。
スタイルが反映される画面
columns.項目名.ExtendedCellCss や model.ExtendedRowCss は、行表示の前(BeforeOpeningRow)のスクリプトで行ごとに設定し、行を描くときに読まれます。1.5.8.1 で SetByBeforeOpeningRowServerScript を呼び、その結果を使っているのは次の画面と出力です。
| 画面 | 行表示の前のスクリプト | 根拠 |
|---|---|---|
| 一覧 | 行ごとに実行し、行の CSS・セルの CSS に反映 | HtmlGrids.cs#L346-L379 |
| リンクテーブル(編集画面の下の子・親レコード一覧) | 行ごとに実行し、行の CSS と項目別のセル設定に反映 | 課題、結果 |
| CSV エクスポート | 行ごとに実行し、空でない RawText を出力値に使う(CSS は関係しない) | GridData.cs#L532-L573 |
| カレンダー・クロス集計・ガントチャート・時系列チャート・カンバン | 呼ばれない | HtmlCalendar.cs・HtmlCrosstab.cs・HtmlGantt.cs・HtmlTimeSeries.cs・HtmlKamban.cs に呼び出しがない |
カレンダーなどの各ビューが使う要素クラス(CalendarElement・GanttElement・KambanElement など、ViewModes)にも、CSS クラスを持つプロパティがありません。これらのビューでアイテムの見た目を変えるには、スクリプト(クライアント側の JavaScript)やスタイルで、表示された要素に対して CSS を当てる方法になります。
ビューごとにサーバースクリプトからスタイルを指定できるようにする改修案は、ビューごとのスタイルをサーバースクリプトで指定する にまとめています。