Find value of SELECT if VALUE attribute is missing

M

Matt Kruse

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?
 
J

Jeremy

Matt said:
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?

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
 
M

Matt Kruse

Jeremy said:
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.
 
J

Jeremy

Matt said:
Jeremy said:
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.
 
E

Elegie

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.

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?

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top