動的なアルファベット順のナビゲーション
-
08-06-2019 - |
質問
使っています ColdFusion
SQL データベースから結果セットを返し、それをリストに変換します。
そのリストのアルファベット順のナビゲーション バーを生成する何らかの方法が必要です。ColdFusion と jQuery ライブラリを利用できます。
次のようなものを生成しようとしています:
A | B | C | ...
- A
- A
- B
- B
- B
- C
- D
いずれかの文字をクリックすると、ページがその文字の最初の項目に移動します。アルファベット 26 文字すべてが必ずしも使用されているわけではありません。
解決 4
ということで、良い提案はたくさんありましたが、私が望んでいたものを正確に実現するものはありませんでした。幸いなことに、私はそれらを使用して、自分が本当にやりたいことを理解することができました。以下の唯一のことは、最後のいくつかの未使用の文字 (存在する場合) を出力することです。これが私が使用する最後の文字である「W」をチェックする cfif ステートメントを備えている理由です。それ以外の場合は、Z をチェックする必要があります。
<cfquery datasource="#application.dsn#" name="qTitles">
SELECT title, url, substr(titles,1,1) as indexLetter
FROM list
ORDER BY indexLetter,title
</cfquery>
<cfset linkLetter = "#asc('A')#">
<cfoutput query="titles" group="indexletter">
<cfif chr(linkLetter) eq #qTitles.indexletter#>
<a href="###ucase(qTitles.indexletter)#">#ucase(qTitles.indexletter)#</a>
<cfif asc('W') neq linkLetter>|</cfif>
<cfset linkLetter = ++LinkLetter>
<cfelse>
<cfscript>
while(chr(linkLetter) != qTitles.indexletter)
{
WriteOutput(" " & chr(linkLetter) & " ");
IF(linkLetter != asc('W')){WriteOutput("|");};
++LinkLetter;
}
</cfscript>
<a href="###ucase(qTitles.indexletter)#">#ucase(qTitles.indexletter)#</a>
<cfif asc('W') neq linkLetter>|</cfif>
<cfset linkLetter = ++LinkLetter>
</cfif>
</cfoutput>
<ul>
<cfset currentLetter = "">
<cfoutput query="qTitles" group="title">
<cfif currentLetter neq #qTitles.indexletter#>
<li><a name="#ucase(qTitles.indexletter)#">#ucase(qTitles.indexletter)#</a></li>
</cfif>
<cfset currentLetter = #qTitles.indexletter#>
<li><a href="#url#">#title#</a></li>
</cfoutput>
</ul>
他のヒント
ナビゲーション バーを生成するには、次のようなことを行うことができます。
<cfoutput>
<cfloop from="#asc('A')#" to="#asc('Z')#" index="i">
<a href="###chr(i)#">#chr(i)#</a>
<cfif asc('Z') neq i>|</cfif>
</cfloop>
</cfoutput>
(CFLOOP は文字に対しては機能しないため、ASCII コードに変換したり、逆に変換したりする必要があります。)
クエリ内の項目を表示するには、次のようなことを行うことができます。
<cfset currentLetter = "">
<cfoutput query="data">
<cfif currentLetter neq left(data.name, 1)>
<h3><a name="#ucase(left(data.name, 1))#">#ucase(left(data.name, 1))#</a></h3>
</cfif>
<cfset currentLetter = left(data.name, 1)>
#name#<br>
</cfoutput>
レコードのクエリでクエリ グループ化機能を使用できます。明らかに、データに応じてクエリ フィールドを変更する必要があり、left() 関数の構文はデータベース エンジンによって異なる場合があります。以下のクエリは MSSQL で動作します。
<cfquery datasource="#application.dsn#" name="qMembers">
SELECT firstname,lastname, left(lastname,1) as indexLetter
FROM member
ORDER BY indexLetter,lastName
</cfquery>
<p id="indexLetter">
<cfoutput query="qMembers" group="indexLetter">
<a href="###qMembers.indexLetter#">#UCase(qMembers.indexLetter)#</a>
</cfoutput>
</p>
<cfif qMembers.recordCount>
<table>
<cfoutput query="qMembers" group="indexLetter">
<tr>
<th colspan="99" style="background-color:##324E7C;">
<a name="#qMembers.indexLetter#" style="float:left;">#UCase(qMembers.indexLetter)#</a>
<a href="##indexLetter" style="color:##fff;float:right;">index</a>
</th>
</tr>
<cfoutput>
<tr>
<td><strong>#qMembers.lastName#</strong> #qMembers.firstName#</td>
</tr>
</cfoutput>
</cfoutput>
</table>
<cfelse>
<p>No Members were found</p>
</cfif>
まずリストを返す SQL 結果セットを取得します。必要な項目の最初の文字とカウントを取得するだけで簡単にできます。最も簡単な方法は、26 文字のテーブルで結合を実行することです (その方が文字列操作が少なくなります)。
CF では、カウント値を使用して、結果がない場合に文字のみを (標準テキストとして) 表示するか、まったく表示しないかを確認します。
もっと良い方法があるかもしれないので、何行作業するつもりですか。たとえば、挿入時に必要なリンク フィールドの最初の文字を別の列に保存すると、選択時のオーバーヘッドが軽減されます。