Copy link to clipboard
Copied
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7afe.html
I read content of the page that I linked to above and I'm gathering that cfselect now has a working required attribute. However I cannot get it to work using a very simple example.
I am running cf9 on my server but can't figure out how to get the following code to show the required message.
<cfform name="switch_this" method="post" action="switch.cfm">
<cfselect name="switch" required="yes" message="Please select an activity">
<option value=""></option>
<option value="Swimming"></option>
<option value="Running"></option>
<option value="Biking"></option>
</cfselect>
</cfform>
What I want to happen is that if the user does not select either Swimming, Running, or Biking, the form will not submit and the message "Please select an activity" will display.
Ok I followed the instructions on the cfsearching site and tweeked the cfform-src javascript. Here's what I put into the SELECT section...
else if (obj_type == "SELECT") | |||
{ | |||
var idx = obj.selectedIndex; | |||
var isValid = false; | |||
var _defaultValue = ""; | |||
// use the supplied default value | |||
if ( document.getElementById && obj.getAttribute("noSelection") ) { | |||
_defaultValue = obj.getAttribute("noSelection").toLowerCase();} | |||
if ( obj.type == "select-one" ) { | |||
// something other than the default value is selected | |||
isValid |
Copy link to clipboard
Copied
Is that the exact code from your CFML file?
Is it true that none of the options have a 'selected' parameter?
If any of them have a 'selected' parameter then the required parameter is fulfilled and the message will never be displayed.
Copy link to clipboard
Copied
Also do you have a mapping for cfide? To check, view source, see that there
is a js file listed in there at /cfide see if you can bring up that file on
the web server.
Copy link to clipboard
Copied
I played with this a bit. The trouble is that the broswer is automatically selecting the first (empty in your example) option if the user does nothing with the control. That aslo means the 'required' paramter has been met and that the message will not fire.
Copy link to clipboard
Copied
I added multiple="yes" to the <cfselect...> tag. This changes the behavior of the browser so that it does not automatically select any of the options. Now if a user does not interact with the control, the error message will be displayed.
<html>
<head>
<title>CFSelect</title>
</head>
<body>
<cfform name="switch_this" method="post" action="switch.cfm">
<cfselect name="switch" required="yes" message="Please select an activity" multiple="yes">
<option value="test"></option>
<option value="Swimming">Swimming</option>
<option value="Running">Running</option>
<option value="Biking">Biking</option>
</cfselect>
<input type="submit">
</cfform>
<cfdump var="#form#">
</body>
</html>
Try with and without the multiple option and you will see the difference in behavior.
Copy link to clipboard
Copied
But I don't want them to be able to select multiple...
Copy link to clipboard
Copied
If you read link you posted it says:
"(required)
Note: This attribute has no effect if you omit the size attribute or set it to 1, because the browser always submits the displayed item. "
The mentioned "fix" only applies to flash forms. If you are using an html form, with a size 1 select list, you will need to write your own validation function.
-Leigh
Copy link to clipboard
Copied
Then, unfortunatly, you need to go beyond "not selected' to something that check's that the default (first) value is what has been selected.
I'm not sure how to do that with <cfselect...> as I seldom use the <cfform...> features, but rather, usually roll my own with my own JavaScript. But, I seem to recall that there is ways to add more sophisticated validation options to the <cfform...> elements.
Copy link to clipboard
Copied
I'm not sure how to do that with <cfselect...> as I seldom use the <cfform...> features, but rather, usually roll my own with my own JavaScript. But, I seem to recall that there is ways to add more sophisticated validation options to the <cfform...> elements.
I do not either. But since someone just asked me the same question, not one hour ago, here is what we came up with:
<script type="text/javascript">
function isNonEmptySelected(frm, list, value) {
return (value == "" ? false : true);
}
</script>
<cfform name="switch_this" method="post" action="switch.cfm">
<cfselect name="switch" onValidate="isNonEmptySelected" message="Please select an activity">
<option value=""></option>
<option value="Swimming">Swimming</option>
<option value="Running">Running</option>
<option value="Biking">Biking</option>
</cfselect>
<input type="submit">
</cfform>
Copy link to clipboard
Copied
Yeah, I thought that you could add custom validation with something, but didn't have the impetus to look at the documentation myself to find the "onValidate" parameter.
But I just do want to say: I find your JavaScript boolean logic a bit cruel.
return (value == "" ? false : true);
If true that the value is an empty string return false, else if false return true!
IF anybody is as OCD as I might be, that could be rewritten.
return (value != "" ? true : false);
But a computer will not care either way and will do either of them just fine!
Copy link to clipboard
Copied
But I just do want to say: I find your JavaScript boolean logic a bit cruel.
Yes, I cannot fault you for that. Your version is more intuitive. My only excuse is too many distractions.
( Though I confess I was tempted to write a terse and ugly: return value != ""; )
Copy link to clipboard
Copied
The REQUIRED attribute is only useful for CFSELECT if you allow multiple selections. Otherwise, there will always be some item selected. By default, that will simply be the first item.
To get what you really want here, you'll need to write some JavaScript:
<script>
function checkSelect(mySelect) {
if (mySelect.selectedIndex == 0) {
window.alert("You must select an option!");
return false;
}
}
</script>
<form action="..." method="..." onsubmit="return checkSelect(this.switch)">
<select name="switch">
<option value=""></option>
<option value="Swimming">Swimming</option>
<option value="Running">Running</option>
<option value="Biking">Biking</option>
</select>
<input type="submit"/>
</form>
Copy link to clipboard
Copied
That's what I was using before. All my validation is utilizing cf's built in cfform vals except for cfselect.
Oh well... I'll just go back to the old way.
I was hoping to get more consistent.
Copy link to clipboard
Copied
Well, the REQUIRED attribute pretty much does what it says on the tin. If you have a selected option, it's not going to do anything for you.
Dave Watts, CTO, Fig Leaf Software
http://www.figleaf.com/
http://training.figleaf.com/
Fig Leaf Software is a Veteran-Owned Small Business (VOSB) on
GSA Schedule, and provides the highest caliber vendor-authorized
instruction at our training centers, online, or onsite.
Read this before you post:
http://forums.adobe.com/thread/607238
Copy link to clipboard
Copied
Well, the REQUIRED attribute pretty much does what it says
on the tin. If you have a selected option, it's not going to
do anything for you.
True. But honestly I have always thought the cfform implementation for this was wrong, in the sense of being counter-intuitive. While the behavior may be technically correct, it does not match how most people use single option select lists.
Just my $0.02
-Leigh
Copy link to clipboard
Copied
-==cfSearching==- wrote:
True. But honestly I have always thought the cfform implementation for this was wrong, in the sense of being counter-intuitive.
But is it a problem with the <cfform...> implementation or browser implementation. The issue isn't that <cfform...> is not getting a value, the issue is that at least some (but all?) browsers will automatically select a value for the user. I would guess that if we could count that each and every browser in the world did this AND each and every developer would use an empty string for the first default option, then ColdFusion could build logic that would rely on that.
But once you spell out those two requirments, I can see how it might make sense to NOT do that. What if a browser does not send the first option, what if developers choose to use other NULL options?
Copy link to clipboard
Copied
But is it a problem with the <cfform...> implementation or browser implementation. The issue isn't that <cfform...> is not getting a value, the issue is that at least some (but all?) browsers will automatically select a value for the user.
Personally, I think it is a lacking in the cfform implementation. My understanding is all browser _do_ automatically select the first list option. I am not 100% on that, but ... assuming for the momement that is true (or even if it is not), it seems like CF could provide a "noSelection" attribute. The value could be an empty string, zero "0" or whatever you wish. Then CF could check that value against the currently selected option when the form is submitted to determine if "something" is selected.
There may well be simpler options, but IMO this would at least be closer to developer expectation. BTW: I am not disputing the fact that the current behavior is technically correct. But it is also totally contrary to how most people use and validate single option select lists. Since one goal of cfform is to simplify validation, this certainly seems like an area where behavior should match user expectations if at all possible.
Message was edited by: -==cfSearching==-
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Ok I followed the instructions on the cfsearching site and tweeked the cfform-src javascript. Here's what I put into the SELECT section...
else if (obj_type == "SELECT") | |||
{ | |||
var idx = obj.selectedIndex; | |||
var isValid = false; | |||
var _defaultValue = ""; | |||
// use the supplied default value | |||
if ( document.getElementById && obj.getAttribute("noSelection") ) { | |||
_defaultValue = obj.getAttribute("noSelection").toLowerCase();} | |||
if ( obj.type == "select-one" ) { | |||
// something other than the default value is selected | |||
isValid = ( obj.options[idx].value.toLowerCase() != _defaultValue );} | |||
else { | |||
// multiple list: at least one item is selected | |||
isValid = ( idx >= 0 ); | |||
} | |||
return isValid; |