カナダ出身の4D開発者、Chris Belangerがゲスト執筆しました。
リストボックスのタイプアヘッド (漸進的に検索する方法)は、リストボックスのネイティブ機能ではありません。しかし、工夫次第でこの機能を簡単に実装することができます。このブログ記事では、データベースの例と、ステップごとに詳細を説明する徹底的なドキュメントとともに、このテクニックを紹介します。
最終的な結果は、以下のGIFにまとめられています。一つはE-L-L-I-O-Tで、もう一つは(列のソートをした後)H-A-N-N-A-Hである。
どうすればいいのでしょうか?
リストボックスにフォーカスがあるとき(ただし「入力モード」ではない)、いくつかの文字を入力すると、リストボックスがスクロールして、「ソート列」に従って最も近いものを選択できるようにしたいのです。例えば、会社名でソートされている場合、会社名を入力し始めると、リストボックスの中でその会社名が検索され、ハイライトされるようにしたいのです。しかし、リストボックスがフォーカスされたオブジェクトである場合、キーストロークに反応することはできません。
では、キーストロークを収集する方法がないようなので、この問題を解決するにはどうしたらよいでしょうか。
リストボックスをサブフォームに配置する
まず、リストボックスをサブフォームに配置します(サンプルデータベースでは、このフォームをLBと呼びます)。さて……、でも、どうやってキーストロークを収集するのでしょうか?ショートカット」を割り当てた不可視のボタンを使用します。
そして、すべてのショートカットは、検索テキストを決定し、リストボックスの中で検索テキストを見つけ、ユーザーのためにハイライトするメソッドを呼び出すのです。Listbox ClairvoyanceデータベースのLB フォームを開けば、この説明に従うことができます。
リストボックスは、LB_Browserというオブジェクト名を持っています。そのプロパティは以下の通りです。
エンティティ選択は、Form.esという名前です(LB Subformのコンテキスト内)。
LB フォームの下部には、ボタンのコレクションがあります。それぞれには、ショートカットキーが割り当てられています。一番下の列はよくわからないかもしれませんが、SPACEキー、-キー、_キーを扱っています。必要であれば、さらに追加することができます。
これらの各ボタンのプロパティを、「A」キーを例に説明します。
Object Nameは、それが生成するLETTER、NUMBER、SYMBOLで終わります。SPACEは例外で、Ⓐの記号を使い、SPACEに「変換」されます。
タイトルは分かりやすくするためだけで、Horizontal Sizingは Move、ショートカットはキーストロークです。チェックすべきイベントは On Clicked.
ユーザーがショートカットキーを押すと、そのボタンのスクリプトに On Clicked Form event code.
各ボタンのスクリプトは
LB_SEARCH_DO ( ; )Form OBJECT Get name
キーストロークを解釈する
が実行されます。 LB_SEARCH_DOプロジェクト・メソッドは、キーストロークを処理します。処理するキーストロークを知るために、Object Name の最後の文字を使用します。
$chaR:=$2[[Length($2)]
]。 // get the last character in the object’s name.
この文字は、最後のキー操作からの時間の長さに応じて、検索文字列に追加されるか、検索文字列を置き換えます。サンプルデータベースでは、1.5秒以上の “wait “があると、新しい検索が開始されます。
$now //add to .searchFor:=Milliseconds
If (($now-$obj_Search.lastMillisecond)>1500)//allow up to 1.50 seconds between keystrokes.
$obj_Search. searchFor :=$char //reset .searchFor
Else
$obj_Search.searchFor :=$obj_Search.searchFor +$char
End if
$obj_Search .lastMillisecond:=$now
検索カラム」の検索は、エンティティセレクションのどのレコードが最初にマッチするかを決定し、そのレコードをエンティティセレクションの中から探し出すことによって行われます(”.es“)。
C_OBJECT($es_GreaterEqual)// the entity selection of the >= group that match the searchFor string.
$es_GreaterEqual :=$1.es.query($attrName+" >= :1";$obj_Search.searchFor).orderBy($attrName+" ASC")
エンティティ選択内の$itemPosition は、次のように決定されます。
If ( . >0) :=$es_GreaterEqual[0] := [0].( . )+1 := . .$es_GreaterEquallength // if there was at least one match
$match // $match = the FIRST RECORD in the collection
$itemPosition$es_GreaterEqualindexOf$1es // location of the matching entity within the selection
Else
$itemPosition$1eslength
End if
ここで、リストボックスの行の選択とスクロールを更新し、ユーザーが結果を見ることができるようにします。リストボックスの5行目に表示することで、文脈がわかるようにしています。
C_LONGINT($show)// used to cause the ITEM POSITION to show in the 5th line (or higher, if it is < 5).
LISTBOX SELECT ROW (*;$lbName;$itemPosition;lk replace selection)
$show :=Choose($itemPosition<4;1;$itemPosition-4)// it will be line 5, or closer to the top
OBJECT SET SCROLL POSITION (*;$lbName;$show;*)
最後に、デモのために、選択されたエンティティを親フォームがアクセスできるオブジェクトにロードします。
Form.en_edit:=Form.es[$itemPosition-1].
// for the parent form’s use
その他
上記のHDIをダウンロードして、このコンセプトをより詳しく見てください。さらに、リストボックスを操作するための親フォームの設定や、ユーザーインターフェイスを設計してユーザーエクスペリエンスを向上させるためのヒントなどを説明した詳細なドキュメントが付属しています。
あなたの次の4Dプロジェクトのお役に立てれば幸いです。