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 multiSelectoptions を書かないと選ぶものが無い。値はデータに入る値、ラベルは画面に出る文字。マスタから引いてくる選択肢は、いまは定義に書けないのでプラグインで足す。

どこに書くか

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

書けるキー

キー書く場所必須既定値有効なページ種別説明
searchcrudPageobjectsearch任意crudThe search area: filters plus their layout.
searchdashboardPageobjectsearch任意dashboardFilters applied to every card's query.
searchmasterPageobjectsearch任意masterThe search area: filters plus their layout.
searchreportPageobjectsearch任意reportOutput conditions, passed to the repository as filters.
searchsearchPageobjectsearch任意searchThe search area: filters plus their layout.
filtersdashboardItemobjectdashboardItem.filters任意dashboardFixed filter values merged into the query.
filterssearcharrayfilter任意crud dashboard master report search
operatorconditionstringequals / 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.
operatorfilterstringequals / 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.
optionsfieldarrayoption任意crud dashboard detail form master report search wizard
optionsfilterarrayoption任意crud dashboard master report searchOptions for select-style filters.
layoutdashboardPageobjectlayout任意dashboardCard grid width. Defaults to 2 columns.
layoutsearchobjectlayout任意crud dashboard master report search
layoutsectionobjectlayout任意crud detail form master
layoutwizardStepobjectlayout任意wizard

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

近い例

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

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

よくある間違い

ページ直下に 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 hatake pitfalls <キー名>

実物を見る

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