Skip to content

日付項目の入力モードと表示形式の拡張 ​

第1版作成 最終更新 (日本時間)
確認バージョン1.5.8.1

日付項目について、次の 3 つを本体に足す設計メモです。本体の標準機能ではありません。

追加するもの現行改修の規模
年月だけ・年だけを選ぶ入力モード無い(エディタの書式は年月日・日時(分)・日時(秒)の 3 つ)年月: 中、年: 大
入力できる日付の範囲(今日から N 日前まで など)無い小
一覧の表示形式に任意の書式を指定する決まった選択肢だけ小

拡張機能だけで年月モードを付ける方法は 日付項目に年月モードを追加する にあります。

前提にした現行実装 ​

日付ピッカーの切り替え ​

日付項目は、General.json の UseOldDatepicker が false(既定)でテーマが 2 世代目なら <date-field> カスタム要素(flatpickr)、それ以外は従来の jquery.datetimepicker で描画されます(HtmlControls.cs)。スマートデザインの画面では、別に Svelte の日付コンポーネントが flatpickr を使います。

<date-field> は input の data-* 属性から flatpickr のオプションを組み立てます(datefield.ts)。

属性使い道出力する場所
data-format書式。:s を含めば秒も入力HtmlAttributes.DataFormat(HtmlAttributes.cs)
data-timepicker1 なら時刻も入力HtmlAttributes.DataTimepicker
data-step分の刻みHtmlAttributes.DataStep
data-hide-current「現在」ボタンを隠すHtmlAttributes.DataHideCurrent

minDate・maxDate を渡す属性はありません。flatpickr の月選択プラグイン(monthSelectPlugin)はバンドルに含まれていません。

エディタの書式(EditorFormat) ​

Column.DateTimeFormat() は EditorFormat が Ymdhm・Ymdhms ならその書式、それ以外は Ymd の書式を返します(Column.cs)。テーブルの管理の選択肢も Ymd・Ymdhm・Ymdhms の 3 つです(SiteUtilities.cs)。

一覧の表示形式(GridFormat) ​

一覧の書式の選択肢は、App_Data/Displays/ の Type が 120(日付)の表示名すべてです(SiteUtilities.cs)。1.5.8.1 では次の 8 つです。

GridFormat表示名(日本語)書式(日本語)
Ymd年月日yyyy/MM/dd
Ymda年月日曜yyyy/MM/dd ddd
Ymdhm日付と時刻(分)yyyy/MM/dd HH:mm
Ymdhms日付と時刻(秒)yyyy/MM/dd HH:mm:ss
Ymdahm日付と曜日と時刻(分)yyyy/MM/dd ddd HH:mm
Ymdahms日付と曜日と時刻(秒)yyyy/MM/dd ddd HH:mm:ss
Ym年月yyyy/MM
Md月日MM/dd

表示するときは、GridFormat の値に Format を付けた ID(YmdFormat など)の表示名を .NET の書式文字列として使います(FormatExtension.cs、Column.cs)。Displays.Get は ID が見つからないとき ID の文字列をそのまま返します(Displays.cs)。

数値項目のカスタム書式(参考) ​

数値項目の「書式」は、ドロップダウン FormatSelector(送信しない)とテキストボックス Format(送信する)の 2 段です。選択肢に「カスタム」(キーはタブ文字 \t)があり、選ぶとテキストボックスが表示されます。定義済みの選択肢に無い値が入っていればカスタムとみなします(SiteUtilities.cs、L9267-L9276、sitesettingsevents.js)。

1. 年月だけを選ぶモード ​

flatpickr の monthSelectPlugin を使うと、カレンダーの代わりに 12 か月の一覧が出て、年月だけを選べます。

図を読み込み中…

  • 保存する値は、選んだ月の 1 日 0 時にします。サーバーは文字列を DateTime として解析するので、日を 01 に固定した形(Y/m/01)で input に入れれば、サーバー側を変えずに保存できます。
  • datefield.ts で data-format が年月の書式なら plugins: [monthSelectPlugin({ dateFormat: 'Y/m/01', altFormat: 'Y/m' })] を渡します。
  • プラグインは flatpickr のパッケージに含まれているので、package.json の変更は要りません。ビルドに取り込むための import を足します。
ファイル内容
Libraries/Settings/Column.csDateTimeFormat()・DateTimepicker() に Ym を足す
Models/Sites/SiteUtilities.csDateTimeOptions(editorFormat: true) に Ym を足す
App_Data/Displays/YmDatePickerFormat.json年月の書式
Implem.PleasanterFrontend/wwwroot/src/scripts/modules/datefield.tsmonthSelectPlugin を適用する
スマートデザインの Svelte コンポーネント同上

2. 年だけを選ぶモード ​

flatpickr には年だけを選ぶ公式のプラグインがありません。

方法内容難しさ
flatpickr の DOM を書き換えるonReady で日付の一覧や月の選択を隠し、onYearChange で値を確定する大。flatpickr の内部構造に依存する
<select> にする年の一覧を出すドロップダウン小。年の範囲を決める必要がある
数値項目で年を持つ日付項目を使わない小

保守を考えると、日付項目で年だけを選ばせるより、<select> や数値項目で年を持つほうが現実的です。

3. 入力できる日付の範囲 ​

flatpickr の minDate・maxDate で、選べる日付を制限できます。'today' や Date を渡せ、flatpickr が足す Date.prototype.fp_incr(n) で「今日から n 日後(負なら前)」を作れます。

設定値(案)意味
today今日
+7今日から 7 日後
-30今日から 30 日前
2026/01/01固定の日付
ts
private parseDateConstraint(value?: string) {
    if (!value) return undefined;
    if (value === 'today') return 'today';
    const n = parseInt(value, 10);
    if (/^[+-]?\d+$/.test(value) && !isNaN(n)) return new Date().fp_incr(n);
    return value;
}
// initDatePicker のオプションに追加
// minDate: this.parseDateConstraint(this.inputElm.dataset.minDate),
// maxDate: this.parseDateConstraint(this.inputElm.dataset.maxDate),
ファイル内容
Libraries/Settings/Column.cs範囲の設定値を持つプロパティ
Libraries/Html/HtmlAttributes.csdata-min-date・data-max-date を出すメソッド
Libraries/HtmlParts/HtmlControls.cs日付の入力欄に属性を出す
datefield.ts・Svelte コンポーネント属性を読んで flatpickr に渡す

ピッカーでの制限は入力補助です。手入力や API で範囲外の値が入るのを防ぐには、サーバー側の入力チェックも別に必要です。特定の日や曜日を選べなくする disable も flatpickr にありますが、サーバーから一覧を渡す仕組みが別に要ります。

4. 一覧の表示形式に任意の書式を指定する ​

数値項目のカスタム書式と同じ 2 段の UI にします。

csharp
if (column.TypeName == "datetime")
{
    var options = DateTimeOptions(context: context);   // 末尾に "\t"(カスタム)を足す
    var custom = !column.GridFormat.IsNullOrEmpty()
        && !options.Keys.Contains(column.GridFormat);
    hb
        .FieldDropDown(
            context: context,
            controlId: "GridFormatSelector",
            controlCss: " not-send",
            labelText: Displays.GridFormat(context: context),
            optionCollection: options,
            selectedValue: custom ? "\t" : column.GridFormat)
        .FieldTextBox(
            fieldId: "CustomGridFormatField",
            controlId: "GridFormat",
            fieldCss: custom ? string.Empty : " hidden",
            labelText: Displays.Custom(context: context),
            text: custom ? column.GridFormat : string.Empty);
}

sitesettingsevents.js に #GridFormatSelector の change を足し、#FormatSelector と同じくテキストボックスの表示と #GridFormat の値を切り替えます。

表示側の FormatExtension.Display は、{GridFormat}Format が表示名に無ければ(Displays.Get が ID をそのまま返したら)GridFormat を書式文字列として使うようにします。

csharp
var id = format + "Format";
var resolved = Displays.Get(context: context, id: id);
var pattern = resolved == id ? format : resolved;
  • GridFormat は文字列なので、Column と SiteSettings の変更は要りません。
  • 不正な書式文字列だと DateTime.ToString が FormatException を投げるので、保存時の検証と表示時の try-catch を入れます。
  • yyyy'年'MM'月'dd'日' のように引用符で任意の文字を入れられます。
ファイル内容
Libraries/Extensions/FormatExtension.csカスタム書式のフォールバック
Models/Sites/SiteUtilities.csDateTimeOptions にカスタムを足し、一覧の書式の UI を 2 段にする
Implem.PleasanterFrontend/wwwroot/src/scripts/generals/sitesettingsevents.js#GridFormatSelector のイベント

関連ページ ​

変更履歴

第1版履歴タブと復元・数値項目の通貨記号・画像プレビューモーダルの解説と、編集画面まわりの改修・設計メモを追加