FileMaker に仕込むオリジナル検索窓についての続編です。入力に応じてリアルタイムに絞り込むタイプ。
オリジナル検索窓 その2 リアルタイム風
以前 FileMaker オリジナル検索窓 という自家製検索窓について書きました。今回はその2、少し挙動が異なる別パターンです。
テキストを入力するごとにリアルタイム(的に)絞り込んでいくタイプで、完成品はこんな感じです。
検索窓に入力すると、一文字ごとに検索され結果が表示されます。リターンキーも検索実行ボタンも使いません。リアルタイム風に絞り込まれていく様子がムービーで分かりますでしょうか。
以前の記事では、入力を完了してリターンキーなり検索ボタンで検索する仕組みでした。今回は完了を待ちません。手早く検索します。
この仕組みを取り入れるのは、「検索実行の動作が早い場合」に限られます。そうじゃないと一文字ずつ検索されたらたまったものじゃありません。パッと検索が実行できるような状況でのみ便利に使えます。
作り方
では作っていきましょう。ものすごく簡単です。
材料
- 検索窓フィールド … グローバルなテキストフィールド ・・・ 1個
- スクリプト … トリガに仕込む検索スクリプト ・・・ 1個
検索窓のフィールド
検索窓として使用するのはテキストフィールドで、グローバルです。単なる入れ物として使います。このフィールドをレイアウトに配置し、スクリプトトリガを仕込みます。
スクリプト
検索するスクリプトを一個だけ作ります。それ以外には何も必要ありません。
検索窓フィールドのトリガ
検索窓フィールドをレイアウトに配置して、スクリプトトリガ OnObjectModify にスクリプトをセットします。OnObjectModify ですから、内容が変更される度に発動します。一文字増やしたり減らしたりするだけで間髪を入れず発動するのです。
検索窓用のスクリプト
スクリプトの内容は次の通りです。検索窓の内容で検索するだけですが、ちょっと IF があります。
if [ IsEmpty ( table::検索用フィールド ) ] 全レコードを表示 現在のスクリプト終了 Else 変数を設定 [ $item ; 値: Get( アクティブフィールド内容 ) ] エラー処理 [ オン ] 検索実行 [ 記憶する ] フィールドへ移動 [ table::検索用フィールド ] End If
もし検索フィールドが空なら全レコードを表示してスクリプトを終了します。検索文字をデリートして消していって最後に何もなくなったときに全レコードされます。
フィールドが空でなければ、設定済みの検索を実行します。ここでは記憶させた検索を実行させていますが、クイック検索でも検索モードでも、なんでもいいので普通に検索させます。何ら難しいことはしていません。ですが秘密の隠し味がぴりりとあります。
それは最後の「フィールド移動」です。何をしているかというと、検索実行された後にすぐさま検索用フィールドに戻るのです。このちょっとした工夫により、検索窓内にカーソルが留まっているかのような挙動となります。
ステップ「フィールドへ移動」では「選択/実行」を選択しません。
検索窓フィールドは、くれぐれも「フィールドに入るときに全内容を選択」にチェックしないようお願いしますね。意味なくなります。
検索条件
検索条件は、ある程度絞っておくのがいいと思います。この検索窓ではテキスト1文字でも検索が発動しますから、それでも成り立つような使い方に限定されます。長文のテキストや、あまりにもあっちこっちのフィールドを検索対象にするのには向いていません。
ムービーの例では 「拡張子」と「Type」のフィールドを検索対象としています。フィールド内容そのものがシンプルですから、例えば「j」と入るだけで jpeg や jpg がヒットすることになります。「p」と入れば pict picture png などがヒットします。こういう単純なのが今回の仕組みに向いています。
汎用的に使うなら
汎用的に作るなら検索条件を記憶させず、その都度フィールドを指定します。その都度フィールドを指定するには、例えばスクリプト引数に検索対象のフィールドを書いておいたりします。 “tableName::fieldName” と指定し、検索の際は検索モードにした後「フィールドを名前で設定」を使います。
ポータルで検索窓を使いたい
実際の活用ではポータルで使いたいことがあります。ポータルにレコードを表示した状態で、検索窓のリアルタイム風検索を行います。
ポータル内で検索することは面倒なことです。どうしましょう。こうします。ポータル設定「ポータルレコードのフィルタ」で計算させます。
ポータルのフィルタに、検索窓フィールドを含めます。検索窓の内容が目的フィールドに含まれていることを条件にフィルタする計算を書きます。
ポータルのフィルタ
検索窓が空かどうかでまず分岐させましょう。
if ( isEmpty ( 検索窓フィールド ) ; )
検索窓が空ならすべて表示したいので、すべてを表示できるフィルタを設定します。データがあるフィールドを指定しておきましょう。ここで何も指定しなければ、どういうわけかポータルに何も表示されませんでした。結果がすべて表示になる条件を必ず書いておきましょう。
if ( isEmpty ( 検索窓フィールド ) ; not IsEmpty ( 目的フィールド ) )
条件として「目的フィールドが空ではない」にしておきました。
次、空でない場合です。検索窓の内容が目的フィールドに含まれるかどうかで判断してみましょう。
if ( isEmpty ( 検索窓フィールド ) ; not IsEmpty ( フィールド ) ; PatternCount ( 目的フィールド ; 検索窓フィールド ) )
検索対象フィールドが複数ある場合には or で繋げましょう。
上のムービーの例なら、こんな感じでした。
If ( not IsEmpty ( FileType::GLB検索用 ) ; PatternCount ( FileType::拡張子 ; FileType::GLB検索用 ) or PatternCount ( FileType::Type ; FileType::GLB検索用 ) ; not IsEmpty ( FileType::拡張子 ) )
ポータルフィルタの知られざる事実
ちょっとここで追記。ポータルのフィルタを計算で書くときのスゴいコツを初めて知りました。
フィルタに if で条件を書きますね。どの条件も与えない場合、つまり else でデフォルト値にしたい場合、これまでは「デフォルトっぽいフィルタ」を苦心して書いていました。上記にもそう書いていますが、でもそんな必要ありませんでした。「 1 」と書くんですって!
if ( 条件 ; 結果 ; 1 )
これだけで良かったんです。こんなの何十年も知らんかった!!
スクリプト
検索窓フィールドのトリガ OnObjectModify に仕込むスクリプトは、次のような動作をさせます。
1 確定(レコード/検索条件確定)
一文字入力したりデリートしたり、変更する度に間髪入れず確定させます。
2 ポータルの更新
ポータルには名前を付けておいてくださいね。確定されたのでポータルの更新を行います。ポータルの条件が発動して表示まで成されます。
3 フィールドへ移動
そしてこれが肝心。検索窓フィールドに移動します。選択/実行は選ばない、全内容を選択を選ばないのは同じです。
これにより、検索窓フィールドに留まっているかのような挙動となります。
ポータルで検索するのは面倒なことですね。ソートはもっと面倒ですので考えるのを辞めてとりあえず放棄しました。
ということで、ファイルメーカー自作検索窓の続編、リアルタイム風の検索でした。以前の検索窓の記事はこちらです。