Skip to content

検索条件を出す ​

検索欄に並べる条件と、比較のしかた(等値・部分一致・範囲)。

検索欄に並べる条件は search.filters に書く。並べた順に画面に出る。

yaml
page:
  type: search
  id: product_search
  title: 商品照会
  repository: productRepository

  search:
    layout: { columns: 3 }
    filters:
      - { field: name, label: 商品名, type: text, operator: contains }
      - field: category
        label: カテゴリ
        type: select
        operator: equals
        options:
          - { value: food,  label: 食品 }
          - { value: drink, label: 飲料 }

field がデータ側の項目名、type が入力欄の種類、operator が比較のしかた。

operator を省くと部分一致になる ​

既定は contains。名前や住所を探す欄はそれでいいが、コードや区分を探す欄では意図と違う。「A001」で検索したら「A0012」も出てくる。コードや選択肢は equals を明示する。

日付や金額の範囲は between、複数選択で絞るなら in。

yaml
- { field: orderDate, label: 受注日, type: date,   operator: between }
- { field: status,    label: 状態,   type: select, operator: in, options: [...] }

検索でしか使えない演算子、条件でしか使えない演算子 ​

operator は検索条件(filters)と表示条件(visibleWhen / enabledWhen)の両方に出てくるが、使える演算子が違う。

検索条件表示条件
between startsWith endsWith使える使えない
isEmpty isNotEmpty使えない使える

値を2つ取る(between)ものは入力欄が2つ必要なので検索専用、値を取らない(isEmpty)ものは検索欄として置き場がないので条件専用、と考えると覚えやすい。

検索条件を組み立てるのは Framework、実行するのは Repository ​

入力された値は「項目・演算子・値」の組として Repository へ渡る。それを SQL や API のクエリにするのは Repository 側。バックエンド(Java / TypeScript)には同じ組を受け取ってクエリを組む道具が用意されている。

select には options が要る ​

select radio multiSelect は options を書かないと選ぶものが無い。値はデータに入る値、ラベルは画面に出る文字。マスタにある選択肢は optionsSource で引く(選択肢の連動)。

最初から絞って始める(defaultValue) ​

「一覧は既定で在籍者だけ」「今月の受注から」のように、開いたときから絞ってある画面は defaultValue で書く。検索欄がその値で埋まって始まり、最初の一覧もその条件で読む(欄だけ埋まって一覧は全件、にはならない)。利用者は外せる。

yaml
search:
  filters:
    - { field: employmentStatus, label: 在籍, type: select, operator: equals, defaultValue: active,
        options: [{ value: active, label: 在籍 }, { value: retired, label: 退職 }] }
    - { field: orderDate, label: 受注日, type: date, operator: between, defaultValue: $thisMonth }

日付は相対の語で書ける。開いた日で解く。

語意味
$today今日
$startOfMonth / $endOfMonth今月の1日 / 末日
$startOfYear / $endOfYear今年の1月1日 / 12月31日
$thisMonth / $thisYear範囲(between)だけ。今月・今年のはじめからおわりまで

範囲は [from, to] でも書ける([$startOfMonth, $today]、片方は null でよい)。形の合わない書き方(範囲の語を範囲でない条件に書いた、など)は既定値が付かないので、npx -p @hatake-fw/api hatake validate が言う。

画面から外させない条件(fixed) ​

「取消は刷らない」「退職者は出さない」のように、利用者に外させたくない決めごとは fixed に書く。画面には出ない。

yaml
search:
  filters: [ … ]
  fixed:
    - { field: cancelled, operator: notEquals, value: true }

足すのは**サーバの buildQuery(TS / Java)**で、毎回の問い合わせに必ず付く。画面は送ってこないので、API を直接叩いても外せない。Repository を自分で直接実装した Flutter アプリ(buildQuery を通らない)は、同じ条件を自分で当てる。

どこに書くか ​

filters は search の中。ページ直下に書いても効かない(下の「よくある間違い」参照)。search を持てるのは crud master search dashboard report の5種別で、form や detail には検索欄という概念がない。

書けるキー ​

キー書く場所型必須既定値有効なページ種別説明
searchcrudPageobject → search任意—crudThe search area: filters plus their layout.
searchdashboardPageobject → search任意—dashboardFilters applied to every card's query.
searchmasterPageobject → search任意—masterThe search area: filters plus their layout.
searchreportPageobject → search任意—reportOutput conditions, passed to the repository as filters.
searchsearchPageobject → search任意—searchThe search area: filters plus their layout.
filtersdashboardItemobject → dashboardItem.filters任意—dashboardFixed filter values merged into the query.
filterssearcharray → filter任意—crud dashboard master report search—
operatorconditionstring (equals / notEquals / gt / gte / lt / lte / contains / in / isEmpty / isNotEmpty ほか)任意—crud dashboard detail form master report search wizardBuilt-ins: equals, notEquals, gt, gte, lt, lte, contains, in, isEmpty, isNotEmpty.
operatorfilterstring (equals / notEquals / contains / startsWith / endsWith / gt / gte / lt / lte / between / in ほか)任意"contains"crud dashboard master report searchMatch operator (open string). Built-ins: equals, notEquals, contains, startsWith, endsWith, gt, gte, lt, lte, between, in.
operatorfixedConditionstring任意"equals"crud dashboard master report searchMatch operator (same open vocabulary as a filter's operator).
optionsfieldarray → option任意—crud dashboard detail form master report search wizard—
optionsfilterarray → option任意—crud dashboard master report searchOptions for select-style filters.
optionsvocabularyarray → option必須—すべて—
layoutdashboardPageobject → layout任意—dashboardCard grid width. Defaults to 2 columns.
layoutsearchobject → layout任意—crud dashboard master report search—
layoutsectionobject → layout任意—crud detail form master—
layoutwizardStepobject → layout任意—wizard—
defaultValuefield`stringnumberbooleannull`任意
defaultValuefilterany (active / $today / $startOfMonth,$today / $thisMonth ほか)任意—crud dashboard master report searchInitial value of this filter (the first list is loaded with it too; the user can clear it). A between filter takes [from, to]. Dates may use relative words resolved on the client's today: $today, $startOfMonth, $endOfMonth, $startOfYear, $endOfYear, and for between only $thisMonth / $thisYear (a whole range). Not applied by the server.
fixedsearcharray → fixedCondition任意—crud dashboard master report searchConditions always applied to this page's query and not shown on screen. The server's buildQuery (TS / Java) adds them to every query, so the screen cannot remove them. A Flutter app that implements Repository directly (no buildQuery) must apply them itself.

この表は spec/reference.json から生成している(JSON Schema が正)。手元では npx -p @hatake-fw/api hatake reference <キー名> で同じものが引ける。

近い例 ​

例は丸ごと写して直すのが一番速い。以下は CI で検証済み(そのまま動く形)。

ファイル種別画面どういうときに使うか
customer_master.yamlcrud顧客マスタ検索して一覧に出して、その場で登録・修正・削除まで面倒を見る画面が欲しい
product_search.yamlsearch商品照会検索して一覧を見るだけ(登録も更新もさせない)画面が欲しい
customer_form.yamlform顧客入力一覧を持たない単票の入力画面が欲しい(新規と編集を1枚で)
customer_wizard.yamlwizard顧客登録項目が多いので入力をステップに分けて、1ステップずつ検証したい
sales_dashboard.yamldashboard売上ダッシュボード件数・金額・グラフのカードを並べて、まず数字を見せたい
order_lines.yamlapp受注明細受注番号だけでは1件に決まらない表を出したい(明細・履歴・年度別の実績)

よくある間違い ​

ページ直下に filters を書く ​

なぜ駄目か 検索条件は search の持ち物。ページ直下の filters は無い(ダッシュボードのカードの filters は「固定の絞り込み値」で別物)。

こう直す search.filters に入れる。

yaml
page:
  type: search
  id: order_search
  title: 受注照会
  repository: orderRepository
  filters:
    - { field: status, label: 状態 }
yaml
page:
  type: search
  id: order_search
  title: 受注照会
  repository: orderRepository
  search:
    filters:
      - { field: status, label: 状態 }

spec/pitfalls.json から生成。各項目は CI で検証済み(間違いは本当に落ち、正しい方は本当に通る)。手元では npx -p @hatake-fw/api hatake pitfalls <キー名>。

実物を見る ​

デモアプリの「受注照会」がこれを使っている。 デモを開く