タブコントロールで作るパンくずリスト

数年前にFileMakerで「パンくずリスト」を作ろうとしたことがありますが、見た目の酷さとメンテナンス性の低さに自分自身で閉口してしまいました。今回紹介する方法を使えば、完璧なソリューションを作ることができそうです。


digital fusion

Better Breadcrumbs

(元記事はこちら)

Daniel Wood
2018/10/4
breadcrums hero

はじめに

パンくずリストはとても便利です。アプリケーションの階層のどこにいるかについて、ユーザに多くの情報を提供してくれます。また必要な場合には、階層を上下にすばやく簡単に移動する方法を提供してくれます。FileMakerの世界では、今までにいろいろな形のパンくずリストが作られてきました。最も一般的な実装では、繰り返しフィールド、ボタンバー、あるいはリストを縦に表示する場合はポータルを使用しました。

これらの方法はすべて正しく機能しますが、2つの面で限界があります。リストの見た目と、機能のカスタマイズ性および拡張性です。具体的にはどういうことでしょうか? ではまず、ボタンバーを使用して作られたパンくずリストの例を示し、いくつかの制限事項について説明します。次に、タブコントロールオブジェクトを使用した代替案を示します。

お約束のサンプルファイルです!

説明を最後まで読んでからデモをチェックするのではなく、サンプルファイルをダウンロードして、実際に触りながら読み進めることを強くおすすめします。それによって記事についていきやすくなり、内容を理解するのに役立ちます。

BetterBreadcrumbs.zip

典型的なパンくずリスト

下に示したのが標準的なパンくずリストの例です。これは位置に基づいたリストで、リスト内の項目はユーザが移動できるソリューション内の場所になっています。

breadcrumbs-1

ユーザは今、リストの右端の位置にいます。左側に進むと、階層を上がってホーム画面までの経路を戻ることができます。それぞれの項目はクリック可能で、ユーザは任意のポイントまで階層を自由に戻って移動することができます。

これをFileMakerで実現する

多くの人々が最初に思いつくのは、ボタンバーを使用してパンくずリストを作る方法です。ボタンバーにはパンくずリストに適したいくつかの特性があります。

  • 複数のセグメントを持ち、それぞれが階層の一つ一つに対応させることができる
  • 各セグメントは元々ボタンなので、クリック可能
  • 各セグメントに表示されるテキストを計算式で設定することが可能

しかし、ここで一つ問題があります。ボタンバーは幅が固定で、ボタンバー内のボタンはすべて、バー全体を等分割した同じ横幅になります。したがって、100ptの幅のボタンバーに10個のボタンがある場合、各ボタンの幅は10ptになります。バーの幅を200ptに広げると、各ボタンの幅は20ptになります。ボタンの幅を個別に制御することはできません。

これは実際の開発の場面ではどうなるでしょう?

breadcrumbs-2

ボタンバーでパンくずリストを作る場合の技を紹介します。ここでの問題は、各ボタンには長さの違うテキストが入りますが、ボタンは全体で1種類の幅しか持てないということです。これに加えて、典型的なパンくずリストは各要素間に区切り記号が入ります。その結果、平均的な見た目のリストになります。

breadcrumbs-3

これはレイアウトモードでの見え方ですが、これでおおよその仕組みはわかるでしょう。

そこで、この固定幅ボタンの問題を回避しようとする試みがいくつか考えられました。その中には、計算に基づいてボタンバーのボタン部品を作成するものがありました。各ボタン内のテキストにスペースを埋め込んで一定の幅にしたり、何百もの小さなボタンを準備して、計算で一部のセグメントを取り除いて残りの幅を調整したりしました。はっきり言えることは、これらはすべて複雑で作業が非常に苦痛であり、それでありながら、本当に美しい結果を得られていないということです。

タブコントロールではどうでしょう?

「それ何?」というあなたの声が聞こえてきます。タブコントロール? 確かにパンくずリストを作るときにタブを使うということは普通は考えもしないでしょう。ですが実際には、タブコントロールはパンくずリストを作るのに最適なレイアウトオブジェクトで、パンくずリストレイアウトオブジェクトという名前にしてもいいくらいです。

タブコントロールがこの用途に非常に優れている理由は、各タブコントロール名の幅が可変であるという単純な事実によります。これは、各タブ名にどのような長さのテキストが入っても、すべてが同じ幅にはならないということです。

breadcrumbs-4

これはタブコントロールをパンくずリストに見えるように作ったものです。見た目はかなりいいです。区切り記号と項目の間のすべての間隔が一貫している点に注目してください。これはどのように作られているのでしょうか?

breadcrumbs-5

これは同じタブコントロールオブジェクトをレイアウトモードで表示したものです。オブジェクト全体の高さを小さく設定して、タブパネルの本体部分は表示せずに、タブ名部分のみの高さになっています。タブパネル上に他のオブジェクトは配置せず、名前部分のみを利用します。

次にタブコントロールの設定を見てみましょう。

breadcrumbs-6

面白い! ここでわかるのは、タブコントロール内の奇数の位置にリスト内の項目の名前が設定されていることです。偶数の位置は区切り記号に使用されます。これはリストを構築するためのテクニックの重要な考え方です。奇数の位置には項目が入り、偶数の位置には区切り記号が入ります。

上記の設定は項目名がハードコードされているので、実際のソリューションでは役に立ちません。理想的にはリストを動的にし、ソリューションのナビゲーション階層を上下に移動するときに要素を追加/削除するようにしたいですが、ここでは単純にリストの構造の構成要素を示すことにします。

タブ幅は「ラベル幅 + 余白:」を選択します。これによって、項目と区切り記号の間隔を均等に保ちながら、テキストを追加するにつれてタブを大きくすることができます。区切りには、ASCII文字の右矢印を使用しています。

項目の書式設定

リストの最初の3つの項目には下線がついています。これは、クリック可能であることをユーザに視覚的に知らせるためです。一番右側の要素には下線がなく、現在表示されている画面であることを示していて、リンクはクリックできません。

視覚的なデザインは、個々のタブコントロールの条件付き書式によります。この基本的なサンプルでは、最初の3つの項目の条件は単に「true」で、書式は下線付きに設定されています。実際には条件付き書式はもう少し動的にしたほうがいいですが、それについては後で説明します。

ナビゲーション用のパンくずリストであれば、上記のようなハードコードされたものを表示し、各レイアウトに合わせて表示を調整するだけで、最も簡単に実装できてしまいます。その他の実装方法のためには、ハードコードよりも動的なアプローチが必要です。

簡単な例

サンプルファイルは、簡単なウィザードの例から始めています。ここでは、パンくずリストを使用して、ステップウィザードの現在位置を示しています。

breadcrumbs-7

このウィザードには5つのステップがあり、ユーザはウィザードを実行し、ボタンをクリックして次のセクションに進みます。リスト自体はクリックできません。ウィザードでの進行状況をユーザに知らせるだけです。

リストの表示にはタブコントロールを使用して、ウィザードの下にはスライドコントロールを使用しています。スライドコントロールには5つのパネルがあり、各パネルの名前はWizard_1からWizard_5です。

下の図はタブコントロールの設定です。

breadcrumbs-8

とてもシンプルです。ここでも奇数位置は項目、偶数位置は区切り記号です。このウィザードの画面数はあらかじめわかっているので、各ステップごとのタブを必要な数だけ追加します。

ウィザードのナビゲーションは、スクリプトの実行によって行われます。スクリプトは引数として方向(forwardまたはback)を取ります。どちらの方向かに応じてグローバル変数$$WIZARD_POSITIONの値を更新します。このグローバル変数を参照することでウィザードのどのステップを実行しているかがわかります。スクリプトは単純に前後のスライドパネルに移動するだけです。

パンくずリスト自体もユーザの現在位置を視覚的に反映するよう更新する必要があります。ユーザの現在位置はグローバル変数の数値によって1から5のいずれであるかがわかります。視覚的な更新は、下の図のように条件付き書式で行います。

breadcrumbs-9

とても簡単です。これは2番目の位置にある”Your Details”の条件付き書式の設定ルールです。ユーザがこのポジションにいる、あるいはすでにこの位置を過ぎている場合は、色を付けます。

breadcrumbs-10

ここでユーザはステップ4の“Interests”にいるので、1から4の項目の条件付き書式はtrueと評価され、太字と緑色に設定されます。

区切り記号はこの例では特に重要ではないので、簡単に条件付き書式を常にtrueにしていくつかのプロパティ(この場合は灰色)を割り当てるか、または条件付き書式を未設定のままにしてタブコントロールオブジェクトの既定の書式設定を継承させます。

この例ではテキストは黒色、区切り記号は灰色になっていて、タブの書式設定が2種類あります。単純にするため、デフォルトのタブテキストを黒色にし、すべての区切り記号に条件付き書式を適用して灰色に変更するようにしました。

ナビゲーション項目にアクションを追加する

ナビゲーションメニューの項目をユーザがクリックしてそれに応じてスクリプトを実行させるという場合は多いでしょう。これをOnPanelSwitchオブジェクトトリガを使用してタブコントロールで実現できます。

ブbreadcrumbs-11

先ほどと同じウィザードですが、今回はすべてのセクションからどこにでも移動できます。

まずすべてのオブジェクトの書式を変更して下線をつけ、クリックできることを示します。その他の条件付き書式のプロパティは前の例と同じです。ユーザがある位置にいる場合、またはその位置がユーザがいる場所の左にある場合、テキストを太字かつ緑色にします。

OnPanelSwitchトリガをタブコントロールオブジェクトに適用すると、どのタブが選択されてもスクリプトが実行されます。スクリプトで使用する重要な情報は、ユーザがクリックしたタブの位置です。これは、Get( トリガターゲットパネル )関数の1つ目の値を評価することで確認できます。

ここでは2つの状況がありえます。1つ目は、ユーザが区切り記号をクリックするケースです。スクリプトはこの場合も実行されるので、これを処理する必要があります。すべての偶数位置が区切り記号なので、クリックした位置が偶数かどうかを確認します。偶数であれば、スクリプトはFALSEを返し、区切りのタブにはナビゲートされません。

もう1つのケースは、ユーザがナビゲートできる実際の項目をクリックする場合です。これは奇数のときです。この数字を実際のウィザード位置に変換する必要があります。区切り記号が間にあるのでそれを考慮してクリックされた項目を計算でずらします。

これを説明するために、 すぐ隣の項目をクリックする場合を考えてみます。これはウィザードでは3番目の位置ですが、実際にはタブコントロールの5番目の位置にあります。したがって、選択した位置をウィザード位置に翻訳する処理が必要になります。これは単純で、Ceiling ( $PositionClicked / 2 )で求められます。サンプルでは、これは 5/2 = 2.5 となり、さらにこの値のCeilingでウィザードの位置は3になります。

ウィザードの位置が求められたので、あとは現在位置をその値に設定し、そのスライドパネルのオブジェクトに行くだけです。

どのような目的にリストを使用するかにかかわらず、リスト内のどの位置でのクリックにも対応するように独自のスクリプトを書くことができます。

項目名をテーブルに抽象化する

多くの場合ウィザードやリスト項目は、カスタマイズしやすくするため、またはさまざまな目的で異なるリストを作成できるようにするため、テーブル内のレコードとして保持します。この例では、パンくずリストがこの方法でも使用できることを示します。

breadcrumbs-12

breadcrumbs-13

上の表はパンくずリストのセクションのレコード一覧です。下の図は表示されるパンくずリストです。テーブル内の2つの重要な情報は、項目名とリスト内の位置です。

このようにテーブルに抽象化したリストを使用するとき、タブコントロールを使用する方法の美しさが際立ちます。リスト項目は可変長テキストにそのまま対応して横幅が変わります。ここで物事をスムーズに機能させるために、留意すべきことが2つあります。

  • タブオブジェクト全体の初期幅を、最悪の場合の長さに合わせて十分長くとる
  • 十分な数のタブコントロールオブジェクトを追加して、リストに入る可能性のあるすべての項目を処理するのに十分な位置数を確保する

ブレッドクラム14

これは抽象化されたリストのタブコントロールの設定です。面白くなってきました! ここでは@BREADCRUMBという名前のカスタム関数が使われています。この関数は2つの引数をとります。1つ目は、取得するウィザード設定テーブルのレコードを識別するキーワードで、2つ目は並び順です。テーブル中の5レコードが、タイプが”Abstracted”であり、1から5の並び順が付いています。

breadcrumbs-15

これがそのカスタム関数です。シンプルなexecuteSQLクエリで、タイプと並び順に基づいて項目の名前を取得します。ここでも魔法は一切使っていません。標準のFileMakerの機能だけです。

残りの実装は、他のサンプルと同じです。項目に条件付き書式を、そしてナビゲーションにスクリプトトリガを使っています。

名前と書式設定の抽象化

この最後の例では、リスト内の個々の項目の書式設定と名前をカスタマイズする方法を示します。これはすでに説明したように条件付き書式でもおこなうことができますが、特定の項目に特定の書式を設定したい場合は、タブ項目に直接設定するのではなく、実際の項目に基づいてテーブルレコードに抽象化する方法があります。

これは上の例と非常によく似ていますが、リスト項目に書式を設定するためのRGB関数を保持するフィールドが、テーブルに追加されています。

breadcrumbs-16

この例のタブコントロールの設定を以下に示します。

breadcrumbs-17

ここでは9種類のタブを追加しました。実際には、必要な時のために余分にタブを準備しておきます。項目はすでにリストとして抽象化されているので、あらかじめ余分にタブを準備しておくことで、あとでタブを一々追加する必要はありません。

ここで注目すべきもう一つの興味深い点は、偶数位置に区切り記号を追加していないことです。これには、@BREADCRUMB_Formattedというカスタム関数を呼び出すことで対応しています。この関数は以前の関数と同じですが、追加でいくつかのことを行います。

  • 渡された並び順が偶数の場合は、区切り記号を返す
  • 渡された並び順が奇数の場合は、対応するレコードからその項目の名前を取得する
  • 合わせてレコードから書式プロパティを取得し、Evaluate関数を使用して項目名に適用する
  • 合わせてウィザードの位置$$WIZARD_POSITIONを使用して、項目の書式を設定するかしないかを決定する

したがってこの場合、条件付き書式を使用して項目を書式設定するかどうかを判断するのではなく、すべてはカスタム関数内で行われます。使用する書式プロパティはレコードから取得することになります。

breadcrumbs-18

結果として、項目だけにテキストを表示しているため、テキストフォーマット関数を使って見た目をどのようにするかを完全に制御できます。ここでは項目ごとに若干異なる色を使用しています。

タブはすばらしい

タブコントロールオブジェクトは、いろいろな機能を提供してくれるとても便利なオブジェクトの1つです。我々はこのパンくずリストがとても気に入っていて、ソリューション中で重要な役割を担っていると感じています。また、プロフェッショナルな見た目とパンくずリストの本来の機能をそのまま実現でき、カスタマイズや書式設定も簡単です。

再度サンプルファイルです!

他のすべての記事と同じように、今回も詳細なサンプルファイルを用意しています。説明を読むだけでは不十分です。以下のサンプルファイルを参照して、実際に動作するところを見て、自分自身で仕組みをさぐってください。

Breadcrumbs.zip

謝辞

この方法を思いついたDigital FusionのGreig Jacksonに感謝します。素晴らしい成果です!

 

 

 

 

 

 

 

Leave a Reply