动态字母导航

时间:2020-03-05 18:40:47  来源:igfitidea点击:

我正在使用ColdFusion从SQL数据库返回结果集并将其转换为列表。

我需要某种方式来为该列表生成一个字母导航栏。我有ColdFusion和jQuery库可用。

我正在寻找生成这样的东西:

A | B | C | ...  ? ??
- A
- A
- B
- B
- B
- C
- D

在其中一个字母上单击可以将我们带到该字母的第一项。并非所有26个字母都必须使用。

解决方案

回答

我将获得SQL结果集以首先返回列表,我们可以轻松地获取所需项目的首字母和一个计数。最快的方法是在26个字符的表上进行联接(以这种方式减少字符串操作)。

在CF中,使用计数值来确保如果没有结果,则仅显示字母(作为标准文本)或者根本不显示字母。

我们将要处理多少行,因为可能会有更好的方法来执行此操作。例如,将所需链接字段的首字母存储在insert上的单独列中会减少选择时的开销。

回答

要生成导航栏,我们可以执行以下操作:

<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>

回答

因此,有很多好的建议,但没有一个完全符合我的要求。幸运的是,我能够使用它们找出我真正想做的事情。以下唯一不做的是打印最后几个未使用的字母(如果有的话)。这就是为什么我要在cfif语句中检查" W",因为这是我使用的最后一个字母,否则应检查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>