2

I want to generate a select list that should look like the following-

<select name="isActive">
   <option value="True">Yes</option>
   <option value="False">No</option>
</select>

For this I am using select() HTML helper in ColdBox.

#html.select(
                options=qActiveOptions,
                nameColumn="value", 
                name="isActive",
                label="Active:",
                required="required",
                title="Active",
             )#

Where qActiveOption is the query that I created using the code below-

<cfset qActiveOptions=queryNew('name,value', "VarChar,VarChar")>
<cfset queryAddRow(qActiveOptions,2)>
<cfset querySetCell(qActiveOptions,'name','yes',1)>
<cfset querySetCell(qActiveOptions,'value','True',1)>
<cfset querySetCell(qActiveOptions,'name','no',2)>
<cfset querySetCell(qActiveOptions,'value','False',2)>

This generates the desired result but as you can see I have to create a new query object just for that. I read the documentation of the select HTML helper and found that we can also provide array of objects to populate it.
Is there any other option to populate a select list such as by providing a structure with name and value pair.

Adam Cameron
  • 29,677
  • 4
  • 37
  • 78
Pankaj
  • 1,731
  • 1
  • 13
  • 15
  • 1
    I have to admit I don't know ColdBox from a bar of soap, but if you want a ` – Adam Cameron Jan 06 '15 at 12:52
  • @AdamCameron Yes you are right. We should always go for simple solutions. The question was just for getting it done in a simple way using ColdBox helper function. – Pankaj Jan 06 '15 at 13:08
  • Did you try an array of structures? – Dan Bracuk Jan 06 '15 at 15:21
  • Which version of ColdFusion, btw? – Adam Cameron Jan 06 '15 at 15:22
  • @danbracuk yes I tried. But no success. – Pankaj Jan 06 '15 at 16:01
  • The ColdBox HTMLHelper generates HTML5 markup, including "data-" attributes and other custom attributes. It's just way of abstracting the HTML output so that instead of changing tons of HTML, you just change the HTML that these functions output. – Adrian J. Moreno Jan 06 '15 at 16:38
  • 2
    OK, in that case you don't need six statements to populate a query: you only need one. `q = queryNew(cols,types,data)` where `data` is an array of arrays (rows x columns). – Adam Cameron Jan 06 '15 at 16:49

2 Answers2

3

Dan was right, you can just pass in an array of structs. First though, I'll point out if you're ok with the name and value being the same string, the simplest form is just to use a comma-delimited list:

#html.select(
    options="Yes,No"
)#

This is what the array of structs looks like using an object literal.

#html.select(
    options=[
        {name:'Yes', value: 'true'},
        {name:'No', value: 'false'}
    ], 
    name="isActive",
    label="Active:",
    required="required",
    title="Active"
)#

And the HTML that produces is:

<label for="isActive">
    Active:
</label>
<select name="isActive" required="required" title="Active" id="isActive">
    <option value="true">
        Yes
    </option>
    <option value="false">
        No
    </option>
</select>
Brad Wood
  • 3,863
  • 16
  • 23
  • That's a struct not an object literal, still in ColdFusion. – Busches Jan 07 '15 at 02:33
  • Well technically it's an array literal of struct literals, but I didn't feel like typing that so I just used "object" in the sense of a generic name for data structures, not a reference to JavaScript "objects" (associative arrays). If you like, I can really annoy you can call it an "implicit struct" :) – Brad Wood Jan 07 '15 at 03:31
3

The documentation for HTMLHelper is lacking an entry for html.select(), but if you go directly to the source code, you'll see that this function can take a query object, a list or an array of objects as the value for the options argument.

<cfargument 
   name="options"
   type="any"
   required="false" 
   default="" 
   hint="The value for the options, usually by calling our options() method"/>

The options() function is also missing from the documentation, but the source code is commented quite well.

So here's your code, using a query object for the options (I changed nameColumn to column in order to get the output you entered above):

<cfset qActiveOptions=queryNew('name,value', "VarChar,VarChar")>
<cfset queryAddRow(qActiveOptions,2)>
<cfset querySetCell(qActiveOptions,'name','yes',1)>
<cfset querySetCell(qActiveOptions,'value','True',1)>
<cfset querySetCell(qActiveOptions,'name','no',2)>
<cfset querySetCell(qActiveOptions,'value','False',2)>

<cfoutput>
#html.select(
    name="isActive",
    options= qActiveOptions,
    column="value", // renders the option tag's value attribute
    label="Active:",
    required="required",
    title="Active"
)#
</cfoutput>

The rendered HTML:

<label for="isActive">Active:</label>
<select name="isActive" required="required" id="isActive" title="Active">
    <option value="yes">yes</option>
    <option value="no">no</option>
</select>

Now with an array of objects for data, using html.options() to handle the option rendering. I removed the nameColumn attribute as it defaults to the value key.

<cfset foo = [
    {"name"= "yes", "value"= "True"}
    , {"name"= "no", "value"= "False"}
] />

<cfoutput>
#html.select(
    name="isActive",
    options= html.options(foo),
    label="Active:",
    required="required",
    title="Active"
)#
</cfoutput>

Which produces the same rendered HTML:

<label for="isActive">Active:</label>
<select name="isActive" required="required" id="isActive" title="Active">
    <option value="True">yes</option>
    <option value="False">no</option>
</select>
Adrian J. Moreno
  • 14,350
  • 1
  • 37
  • 44
  • Funny, we must have been typing at the same time :) You can also just pass the array straight into the options arg and it will internally pass it off to the options() method as I showed in my example. – Brad Wood Jan 06 '15 at 20:34
  • 2
    If the documentation was updated to cover select(), I would have known that. *cough*gettowork*cough* :) – Adrian J. Moreno Jan 06 '15 at 20:37