Banny
Banny

Reputation: 841

nesting "cfloop" tags to loop through pairs

I'm currently trying to create a <select> dropdown list which will choose which <option> is selected based on the URL variable (or default value). However, I don't want my option list to look like;

name_az, name_za, newest, oldest

As that isn't very user friendly, but i also don't want to be using these in my code;

Name A-Z (Default), Name Z-A, Newest Bands, Oldest Bands

Because obviously that is making MUCH more work for myself.

I could manually create each option list and do a <cfif> check on each set of options to select the desired option. However, as any designer will know, this creates a lot of extra, unneeded work when you can create a loop list and simply add two values to that list.

Below is the code i currently have;

<select>
    <cfset sortlist = "name_az|Name A-Z (Default),name_za|Name Z-A,newest|Newest Bands,oldest|Oldest Bands">
    <cfoutput>
        <cfloop list="#sortlist#" delimiters="," index="sortpair">
            <cfloop list="#sortpair#" delimiters="|" index="sortphrase">
                <option value="#sortphrase#">#sortphrase#</option>
            </cfloop>
        </cfloop>
    </cfoutput>
</select>

I want it to return this:

<select>
    <option value="name_az">Name A-Z (Default)</option>
    <option value="name_za">Name Z-A</option>
    <option value="newest">Newest Bands</option>
    <option value="oldest">Oldest Bands</option>
</select>

However, obviously I am asking it to return sortphrase wherever it is listed, so it will return as this:

<select>
    <option value="name_az">name_az</option>
    <option value="Name A-Z (Default)">Name A-Z (Default)</option>
    <option value="name_za">name_za</option>
    <option value="Name Z-A">Name Z-A</option>
    etc..
</select>

Is there a way of perhaps creating a <cfloop> where I can loop x amount of values in a list?

Upvotes: 1

Views: 290

Answers (1)

duncan
duncan

Reputation: 31912

Your idea of using a nested loop seems wrong to me. It's ok to treat it as a | separated list, but why loop over it? You'll just end up with twice as many option tags as you need. Try

<cfloop list="#sortlist#" delimiters="," index="sortpair">
    <option value="#listFirst(sortpair, '|')#">#listLast(sortpair, '|')#</option>
</cfloop>

Also, generally arrays perform quicker than lists in Coldfusion. For something small like this it doesn't really matter, but I would usually use an array instead of a list, at least for the looping over (but probably still using |-delimited list for the two separate parts).

Alternatively you could use a struct for each key-value pair. e.g. here's an alternative way of doing it using associative array notation:

<cfset sortarray = [
    {name = "name_az", value = "Name A-Z (Default)"},
    {name = "name_za", value = "Name Z-A"},
    {name = "newest", value = "Newest Bands"},
    {name = "oldest", value = "Oldest Bands"}
]>

<cfloop array="#sortarray#" index="sortstruct">
    <option value="#sortstruct['name']#">#sortstruct['value']#</option>
</cfloop>

OR using struct notation:

<cfloop array="#sortarray#" index="sortstruct">
    <option value="#sortstruct.name#">#sortstruct.value#</option>
</cfloop>

Upvotes: 5

Related Questions