The ability to distinguish visited links from those not yet visited is a great feature and one that can be extended to form select elements (also known as "dropdown boxes") in some situations.

For the purposes of this example, we'll be using ColdFusion and a database of projects (a portfolio). The intention of this article is to get the opinions of CF experts (as I am not one), and discover a perfect way of implementing this idea, for the eventual benefit of all developers. My initial attempt is just to get people thinking - so expect to find problems. ;)

That said, we'll need a few things - an Application.cfm, a project.cfm, and a project database (project.mdb). And we'll add in a linked stylesheet too (styles.css). You'll find portions of the code for these throughout the article, and they'll all be available to download also.

The code works in the following way: in the Application.cfm, a list is created, full of zeros, and has a length equal to the number of projects found in the database. As each project is visited/viewed, it's corresponding position in the list is changed from a zero to a one. In this way, the code that builds the select box can tell whether each project has been visited (or not), and set the appearance appropriately.

Firstly, the Application.cfm:

<cfapplication name="project" clientmanagement="yes" sessionmanagement="yes" sessiontimeout=#createtimespan(0, 2, 0, 0)#>

<cfset data = "project">

<cfquery name="getall" datasource="#data#">

   select projectid, projectname

   from project

   order by projectid;

</cfquery>

<cfparam name="session.visit" default="#repeatstring("0,","#getall.recordcount#")#">

It's the last line here that's important - it's setting a default session variable (session.visit). The function repeatstring() will repeat "0" by the recordcount of the getall query. So, if at this stage, we have 15 projects in our database, the value of session.visit will be:

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

Next, the stylesheet. I'm only going to include the part that's critical, but the file itself can be downloaded later.

.visited {

   font-family : verdana, arial, sans-serif;

   color : #999999;

   font-size : 10pt;}

.unvisited {

   font-family : verdana, arial, sans-serif;

   color : #000000;

   font-size : 10pt;}

These two classes will be applied to the select box's option tags depending on their visited status. The only difference is the colour - unvisited options remain black, but those that have been visited "fade" to grey.

Finally, the project.cfm file itself. You can download it in its entirety at the end of this article, but for now, here's the first important section which sits at the top of the file:

<cfparam name="url.projectid" default="1">

<cfquery name="getem" datasource="#data#" maxrows=1>

    select projectid, projectname, projectdescription

    from project

    where projectid = #url.projectid#;

</cfquery>

<cfif getem.recordcount is "0"><cfinclude template="project.cfm"><cfabort></cfif>

<cfset session.visit = "#listsetat(session.visit, "#url.projectid#", 1)#">

The last line in this part is what changes the required zero to a one. It uses the function listsetat() to change the character at the position (#url.projectid#) of the project to "1".

The select box code itself is what causes the options to fade when they've been visited:

<form action="project.cfm" method="post" name="selectproject">

<select name="projectname" size="1" class=unvisited onChange="location.href = this[this.selectedIndex].value">

<cfoutput query=getall>

<option class="<cfif #getem.projectid# is #projectid#>unvisited<cfelseif #listgetat(session.visit, "#projectid#")# is "1">visited<cfelse>unvisited</cfif>" value="project.cfm?projectid=#projectid#" <cfif #getem.projectid# is #projectid#>selected</cfif>>

&nbsp;&nbsp;

<cfif #listgetat(session.visit, "#projectid#")# is "1">&nbsp;<cfelse>-</cfif>

&nbsp;#projectname#&nbsp;&nbsp;&nbsp;</option>

</cfoutput>

</select>

</form>

In this section, there are five important sections. The first, "unvisited" ensures that the currently selected option is given the "black" style, and does not appear faded until the next selection.

The second, #listgetat(session.visit, "#projectid#")#, grabs the value (from the list) at the position of the project in the select box. The next two show the application of the visited and unvisited styles, depending on the value. If the value is one, the project has been visited, and the visited style is applied. If the value is zero, then it is unvisited, and the style is set accordingly.

The final item enables this select box to show the "visited" projects based on a non-CSS method. If the project is unvisited, add a hyphen. If it's been visited, leave the hyphen out. This ensures that non-stylesheet enabled browsers can still get at least some feedback from the dropdown.

Last of all, download a zip of the files you'll need, and/or visit the simplified code in action.

If you spot any errors in the code, or can suggest major improvements, please post below, or email me so that I can update the article. Thanks.

isaac