AdobeStock_455007340

CFSELECT Query Positioning

Home » CFSELECT Query Positioning

This is a little one, but it has bugged me for years, and I am pleased that Blackstone fixes it. When you use you can populate the list with a query and also insert your own options using

22 responses to “CFSELECT Query Positioning”

  1. Devin Avatar
    Devin

    Two other things that bug me about cfselect…
    required="true" works only for multi-select. It "should" work for single select lists and fail if the option value is an empty string.
    okay, so then use onValidate attribute to work around that… oh wait!! there is no onValidate for cfselect!

  2. tony petruzzi Avatar
    tony petruzzi

    Here’s something that always has bothered me about CFSELECT, why people use it. Seriously I have yet to come to a situtation where it would be better to use CFSELECT than just a SELECT tag and a CFOUTPUT nested in it.
    Can someone prove me wrong and give me an example of a good use of CFSELECT?

  3. Devin Avatar
    Devin

    Just like everything in cfml, it’s a convience thing. less code == greater productivity. Isn’t that why you use CFML?

  4. Ben Forta Avatar
    Ben Forta

    Exactly, instead of a SELECT in an OUTPUT loop (and needing an inline CFIF to set SELECTED on the right OPTION in edit forms), CFSELECT does it all. It’s all about convenience.

  5. Tjarko Avatar
    Tjarko

    Nothing bothers me about that tag…. because i don’t use it. 🙂 Just as CFINPUT, CFFORM etc etc… see you next monday in Amsterdam!

  6. Tom Avatar
    Tom

    Currently I don’t use cfselect/cfform/cfinput since they didn’t offer enough incentive to be used. In fact I don’t know to many CF programmers that use it . However, I will re-evaluate their usage when we switch to Blackstone.

  7. Ben Forta Avatar
    Ben Forta

    Actually, I think you’ll be surprised at how many do use CFFORM and CFINPUT. Here is one of the best current reasons to, no need for CFOUTPUT tags around your form fields, you can just use VALUE="#var#", that makes the code much cleaner. I *only* use CFFORM, no downside (if you don’t like the validation code don’t use it) and some upside, so why not?

  8. Devin Avatar
    Devin

    You dont have to type method="post". PreserveData attribute is great! many people complain about about the lack of flexibility, particularly with the validation code and validate values. But that’s what the pattern attribute is for. And anything that needs validation beyond regex, you still have the onValidate attribute to use your own .js function while still integrating with cfinput’s message attributes.
    Even though it’s rare, it’d be nice to specify a GET method with cfform for when you need it.
    When you use onSubmit() with cfform, it’d be nice to nave to type the full paths to arguments to pass to the function.
    I’ve already mentioned my two dislikes about cfselect that make it difficult to require a selection (when the SELECT BELOW shouldn’t be an allowed selection).
    And not having to surround form fields with cfoutput tags is great, but it’s still annoying that it has to be done with input of type hidden and textareas.

  9. Ben Forta Avatar
    Ben Forta

    TYPE="hidden" TYPE="submit" etc. are all in Blackstone, as is TEXTAREA.

  10. Devin Avatar
    Devin

    that’s good to know. But I also forgot to mention the xhtml incompatibility (which i’m guessing will be fixed in blackstone with xforms support), the crazy amount of source code whitespace it generates, and the that passthrough attribute. It should just automatically passthrough all attributes/values without having to use the passthrough attribute with funky quotes or switching them around.

  11. Mike Kaminsky -- ICF Consulting Avatar
    Mike Kaminsky — ICF Consulting

    This tag bothered me at first, but I discovered how to get around the two problems discussed in the orginal post which started this thread.
    The first problem was figuring out how to insert a blank record into the dropdown list. Before Blackstone, if I were to insert an empty option …
    <cfquery name="QUERY_CarParts" datasource="ds_MAM">
    SELECT id, description
    FROM car_parts
    ORDER BY description
    </cfquery>
    <cfselect name="CarPartsList"
    required="Yes"
    message="CAR Part is a required field."
    size="1"
    multiple="No"
    query="QUERY_CarParts"
    value="id"
    display="description"
    selected="#QUERY_CarParts.id#">
    <option value=""></option>
    </cfselect>
    And it would appear at the bottom of the list. After Blackstone, as was mentioned, we can now insert ‘queryposition="below"’ and all options between the tags will appear first and then the query results below that. This is fine for those who have switched to Blackstone, but for those who haven’t, I recommend this strategy … simply add the blank option via the query itself.
    <cfquery name="QUERY_CarParts" datasource="ds_MAM">
    SELECT ” AS id, ‘ ‘ AS description
    FROM car_parts
    UNION
    SELECT id, description
    FROM car_parts
    ORDER BY description
    </cfquery>
    To make this work, you must have the ORDER BY clause and whichever field is being ordered, the blank option must be sorted such that it appears above all other rows. I chose a ‘space’ since I know all other ‘description’ fields will hold a non-empty string. If the ‘id’ field was a number instead of a string, you could also do the following without using an ORDER BY …
    <cfquery name="QUERY_CarParts" datasource="ds_MAM">
    SELECT -1 AS id, ” AS description
    FROM car_parts
    UNION
    SELECT id, description
    FROM car_parts
    </cfquery>
    OK, so first problem solved now for either version of CF. My next problem was getting the validation to work when the size of the CFSELECT is set to ‘1’ or is not included. Unfortunately, I do not know why the designers decided to not include this functionality on single-item dropdown lists. Even in Blackstone this situation is not corrected. So, here’s how I got around it. The CFSELECT tag performs its validation using javascript. I simply found the source of the javascript and modified the file.
    C:CFusionMX7wwwrootCFIDEscriptscfform.js
    Inside this file, modify line #73 this way:
    ORIGINAL:
    else if (obj_type == "SELECT")
    {
    for (i=0; i < obj.length; i++)
    {
    if (obj.options[i].selected)
    return true;
    }
    return false;
    }
    MODIFIED:
    else if (obj_type == "SELECT")
    {
    for (i=0; i < obj.length; i++)
    {
    if (obj.options[i].selected &&
    obj.options[i].value != "")
    return true;
    }
    return false;
    }
    NOTE: if you use ‘-1’ as your blank option identifier, you’ll need to modify the code above to look for that value instead of the empty string. Or you could add both identifiers to catch both number and string values.

  12. Mike Kaminsky -- ICF Consulting Avatar
    Mike Kaminsky — ICF Consulting

    By the way, this code is from the function:
    _CF_hasValue(obj, obj_type, obj_trim)
    So the code above checks for a selected value and returns true/false. If false, the validation fires off the ‘Required’ error message from the CFSELECT tag.
    P.S. — sorry about all the HTML literals, I didn&quott know my post would look like that.

  13. Scott Jibben Avatar
    Scott Jibben

    There is still a problem with cfselect if the values that you are using to determine the selected state contain embedded commas. cfselect treats selected="the company, inc." as a comma delimited list and will break apart one value into multiple values even if multiple="false". I had hoped that multiple="false" would have forced the tag to treat selected as a string vs. a list but it didn’t as of CFMX 7.02.
    So, I had to revert to using standard select/option tags with a cfoutput to get this to work as it needed to.
    Also, the cffrom preservedata="true" flag did not help with this problem.
    If there is a better solution to this problem, post it here.

  14. Max Ethos VII Avatar
    Max Ethos VII

    Try http://landofcoldfusion.blogspot.com
    look for "CF_Select vs. the Iron Evangelist"

  15. Jim Priest Avatar
    Jim Priest

    FYI – the comma in the CFSELECT seems to still be an issue in ColdFusion 8
    🙁

  16. Ted Avatar
    Ted

    Ben,
    I’ve gotten a version of the cfselect working fine on a test page with just the cfselect code. But now I’m using it in a form with several other form elements. I use the exact same code as the test page, but am adding several cfinput type=text boxes. I’m now getting an error message that the second cfselect element won’t bind on the id of the first element (error:bind: Bind failed, element not found: newspaper_num).
    Any suggestions?
    Thanks, Ted.

  17. Steven C Avatar
    Steven C

    You do not have to modify the C:CFusionMX7wwwrootCFIDEscriptscfform.js.
    Just use this simple and easy javascript: (I provide sample)
    <script type="text/javascript">
    function validateMyCFSelect() {
    if (document.myform.myselect.value != "")
    {
    return true;
    }
    else
    {
    alert("You did not make your selection");
    return false;
    }
    }
    </script>
    <cfform action="…whatever…"
    method="post"
    name="myform"
    onsubmit="return
    validateMyCFSelect()">
    <cfselect name="myselect"
    size="1"
    queryPosition="below"
    multiple="no"
    required="yes">
    <option value="">Please Select<option>
    <option value="">Male<option>
    <option value="">Female<option>
    </cfselect>
    Has been working great for me! I welcome suggestions and comments.

  18. Steven C Avatar
    Steven C

    OOPS! Sorry everyone!
    I made an error to the cfselect. Need to add "Male" and "Female" to the cfselect option value in the sample I gave above.

  19. Dave Markle Avatar
    Dave Markle

    So, what do we do now with CF8 when we bind the cfselect to a CFC but still want to have an additional field, like ‘ALL’?
    Queryposition is out. The additional OPTION tags get overwritten when the cfc binding results come back.
    I’ve forced the extra row in at the CFC using QueryAddRow, but the code feels forced and it produces uncomfortable interactions between my CFC code and my cfselect box. I have to send awkward parameters around and I don’t like it. I’d prefer to put that ‘ALL’ in where it belongs, which is with the cfselect.
    Any ideas?

  20. HLHarkins Avatar
    HLHarkins

    CFSELECT’s flaws have irked me for years. Due to its limitations, I’ve never really used CFFORM extensively, but I thought I’d give it a go for a new project and hit this immediately.
    The fix provided at http://livedocs.macromedia.com/coldfusion/5.0/CFML_Reference/Tags91 (see also http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:211914) is great – if you control your own CF Server, but if you’ve got a client who’s on a shared box, then you need another work-around.
    My charming husband has a solution (see SCRIPT below).
    So, you take the SERIOUSLY FLAWED CFSELECT-generated validation function (called _CF_hasValue) and set it to a new variable, called _CF_hasValue_old.
    Then, you run through your NEW function, now called by the original one’s name.
    If the function finds a select box of size 1 on the form, it will loop through the values until it finds one that is not only SELECTED but also has a VALUE (the latter little tidbit is NOT something that CF validation checks for. Ridiculous!). If it finds one, it breaks out of the function. Otherwise, it continues on and will returns false.
    On the other hand, if the field in question isn’t a single-select, then the old CF Validating function will run.
    ** Caveat: this assumes that Adobe’s not going to be changing the names of any functions with newer versions… ?? So use at your own risk.
    So, for example, I configured my form like this (note the use of queryposition to order my dummy valueless <OPTION> tag above the ones generated by the query output).
    <CFFORM… blah blah>
    <CFSELECT name="ThingID" required="Yes" size="1" queryposition="below"
    message="Please make a Thing selection." value="ThingID" query="qThingTypes" display="Things">
    <OPTION>Please select a Blast Type</OPTION>
    </CFSELECT>
    <[SUBMIT]>
    </CFFORM>
    <SCRIPT>
    var _CF_hasValue_old = _CF_hasValue;
    _CF_hasValue=function(_b,_c,_d)
    {
    if (_b.type == ‘select-one’)
    {
    var bSelected = false;
    for (var i=0; i<_b.options.length; i++)
    {
    if (_b.options[i].selected == true && _b.options[i].value != ”)
    {
    bSelected = true;
    break;
    }
    }
    return bSelected;
    }
    else
    return _CF_hasValue_old(_b,_c,_d);
    }
    </SCRIPT>

  21. Dave Ostrander Avatar
    Dave Ostrander

    Thanks so much, that Selected tag was kicking my butt 🙂 Very helpful!

  22. HLHarkins Avatar
    HLHarkins

    You’re welcome — this is how my husband ensures our marital bliss 😉

Leave a Reply