Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Find value of SELECT if VALUE attribute is missing

0 views
Skip to first unread message

Matt Kruse

unread,
Jan 8, 2007, 1:45:30 PM1/8/07
to
According to standards, if an option is selected and it has no VALUE
attribute, the contents of the option tag is to be submitted.
So:

<select name="sel">
<option selected>Value</option>
</select>

will submit as "sel=Value".

Unfortunately, IE says that sel.options[sel.selectedIndex].value == "",
whereas FF reports "Value".
So how can script accurately extract the value that will actually be
submitted?

I have written this code, which works:

function optionValue(opt) {
if (opt.value!="") {
return opt.value;
}
if (!'value' in opt) {
return opt.text;
}
if (opt.outerHTML && opt.outerHTML.test(/<[^>]+value\s*=/i)) {
return opt.value;
}
return opt.text;
}
String.prototype.test=function(regex) {
return regex.test(this);
}

Suggestions?

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com


Jeremy

unread,
Jan 8, 2007, 2:06:07 PM1/8/07
to

This is what I've been doing, which seems to work pretty well:

var theRealValue = mySelect.value ||
mySelect.options[mySelect.selectedIndex].value ||
mySelect.options[mySelect.selectedIndex].childNodes[0].nodeValue;


Which will get either the value of the select (if it's reported), the
value of the selected index (if it's reported), or finally the contents
of the first node contained in the option tag (which should be a text
node containing its value, but then you have to be careful with your
markup or that will fail).

Since IE is really the only player that doesn't report the select's
value, you could probably replace the childNodes stuff with innerHTML
and be safe.

Jeremy

Matt Kruse

unread,
Jan 8, 2007, 2:44:39 PM1/8/07
to
Jeremy wrote:
> This is what I've been doing, which seems to work pretty well:

But it fails in a common case...

> var theRealValue = mySelect.value ||
> mySelect.options[mySelect.selectedIndex].value ||
> mySelect.options[mySelect.selectedIndex].childNodes[0].nodeValue;

If I have:
<OPTION VALUE="">Test</OPTION>

then your code will fall into the third case and report "Test", which would
not be accurate.

Jeremy

unread,
Jan 8, 2007, 3:37:59 PM1/8/07
to
Matt Kruse wrote:
> Jeremy wrote:
>> This is what I've been doing, which seems to work pretty well:
>
> But it fails in a common case...
>
>> var theRealValue = mySelect.value ||
>> mySelect.options[mySelect.selectedIndex].value ||
>> mySelect.options[mySelect.selectedIndex].childNodes[0].nodeValue;
>
> If I have:
> <OPTION VALUE="">Test</OPTION>
>
> then your code will fall into the third case and report "Test", which would
> not be accurate.
>

True that.

Elegie

unread,
Jan 8, 2007, 4:03:53 PM1/8/07
to
Matt Kruse wrote:

Hi,

> According to standards, if an option is selected and it has no VALUE
> attribute, the contents of the option tag is to be submitted.

<snip>

> Unfortunately, IE says that sel.options[sel.selectedIndex].value == "",
> whereas FF reports "Value".
> So how can script accurately extract the value that will actually be
> submitted?

<snip>

> if (!'value' in opt) {
> return opt.text;
> }

I do not understand why you have included this condition ?

> if (opt.outerHTML && opt.outerHTML.test(/<[^>]+value\s*=/i)) {

The regexp should be solid enough I think, the only way I can imagine to
defeat it would be to use some custom attribute which would contain
"value=" inside it :)

My analysis is probably the same as yours. Basically, the code should
handle three mutually exclusive states:
- the value is there and is not empty,
- the value is there, however it is empty,
- the value is not there, the content becomes the real value.

The point is to distinguish between an empty value and no value at all.
Reading the value 'programmatically' does not help, because for each
case an empty string is returned. Therefore the script should not
attempt to use some 'programmatic' way to make the difference; using
outerHTML and parsing the serialized string of the option seems the
appropriate alternative.

Here's some function, also managing the "value=" slight issue.

---
function getOptionValue(opt){
var v=opt.value, t=opt.text;
return (v || attributeExists(opt,"value")) ? v : t;

function attributeExists(obj, attrName) {
var oHtml=obj.outerHTML;
var found=false;

if(oHtml)
found=/value\s*=/i.test(collapseQuotedValues(oHtml));

return found;

function collapseQuotedValues(txt){
var sQuote=txt.indexOf("'");
var dQuote=txt.indexOf("\"");
var q="";

if(sQuote==-1 && dQuote!=-1) {
q="\"";
} else if(sQuote!=-1 && dQuote==-1) {
q="'"
} else if(sQuote!=-1 && dQuote!=-1) {
if(sQuote<dQuote) q="'";
if(dQuote<sQuote) q="\"";
}

if(q) txt=arguments.callee(
txt.replace(new RegExp(q+"[^"+q+"]*"+q),"_")
);

return txt;
}

}
}
---


Kind regards,
Elegie.

PS: also, when the MULTIPLE attribute is set, there can be many values
for the SELECT.

0 new messages