Page 1 of 1
Dynamic options in Opera
Posted: Thu Dec 27, 2007 8:57 am
by SBukoski
OK, this has been driving me crazy for the last day. I have the below code which works fine in FireFox and IE and gives me two options in my select box. However, in Opera it is yielding me 4 options. The first two as expected and then another two that have no text but are selectable. The code is as follows:
Code: Select all
var pulldown = document.custombm.bmtech;
// clear values in pulldown
for (var a=pulldown.length-1; a>=0; a--)
pulldown.options[a] = null;
// populate First option
pulldown.options[0] = new Option('First', 'First');
// populate Second option
if (parseInt(this.techlevel) >= 2) pulldown.options[1] = new Option('Second', 'Second');
// set the length of the pulldown
pulldown.length = (parseInt(this.techlevel) == 1) ? 1 : 2;
// loop through and select the technology base if it is present
for (var b=0; b<pulldown.length; b++)
pulldown.options[b].selected = (pulldown.options[b].value == this.techbase) ? true : false;
// Make sure the current value matches what is selected
this.techbase = (pulldown.value != this.techbase) ? pulldown.value : this.techbase;
Now, I narrowed it down to the last for loop. If I comment that out I only get two select options; First and Second. If I don't comment it out I get the First and Second options as well as two options with no text but whose value always appears to be equal to First.
Does anyone have any ideas? This has been driving me crazy and I can't understand what is wrong with that simple for loop.
Posted: Thu Dec 27, 2007 9:28 am
by VladSun
I think you should not set the length of the options list manually:
Remove these lines:
Code: Select all
// set the length of the pulldown
pulldown.length = (parseInt(this.techlevel) == 1) ? 1 : 2;
I've tried it in Opera 9.24 and it works fine
PS:
Also, I would use the DOM model:
http://developer.mozilla.org/en/docs/DOM:element
to get/add/remove nodes.
Posted: Thu Dec 27, 2007 2:02 pm
by SBukoski
VladSun wrote:I think you should not set the length of the options list manually:
Remove these lines:
Code: Select all
// set the length of the pulldown
pulldown.length = (parseInt(this.techlevel) == 1) ? 1 : 2;
I've tried it in Opera 9.24 and it works fine
Interesting. I just tried it removing the manual setting of the length and I'm getting the same results as before. But when I comment out the last for loop (setting the selected value) everything works fine. I have Opera 9.25, though I would think with a minor release that shouldn't make a difference, but one never knows.
And something even more bizarre. If I put an alert() call between setting the length and cycling through the for loop, I don't get the extra blank rows.
Posted: Thu Dec 27, 2007 2:15 pm
by VladSun
I've just upgraded to Opera 9.25 - again, it works just fine:
Code: Select all
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body>
<select id="pulldown">
<option value="">1</option>
<option value="">2</option>
<option value="">3</option>
<option value="">4</option>
<option value="">5</option>
<option value="">6</option>
</select>
<script language="JavaScript">
function TObj()
{
this.techbase = 0;
this.techlevel = 1;
var pulldown = document.getElementById('pulldown');
// clear values in pulldown
for (var a = pulldown.length-1; a>=0; a--)
pulldown.options[a] = null;
// populate First option
pulldown.options[0] = new Option('First', 'First');
// populate Second option
if (parseInt(this.techlevel) >= 2)
pulldown.options[1] = new Option('Second', 'Second');
// loop through and select the technology base if it is present
for (var b=0; b<pulldown.length; b++)
pulldown.options[b].selected = (pulldown.options[b].value == this.techbase) ? true : false;
// Make sure the current value matches what is selected
this.techbase = (pulldown.value != this.techbase) ? pulldown.value : this.techbase;
}
var t = new TObj();
</script>
</body>
</html>
Posted: Thu Dec 27, 2007 3:10 pm
by SBukoski
OK, I took your code and implemented it and all was fine So I spent a little time to modify it to get it to more closely resemble the scenario I have. The below code represents that.
Code: Select all
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body>
<select id="pulldown">
<option value="First">First</option>
<option value="Second">Second</option>
<option value="Third">Third</option>
</select>
<input type="button" value="Click Me!" onClick="t.updatePD()">
<script language="JavaScript">
function TObj()
{
this.techbase = 'Second';
this.techlevel = 1;
}
TObj.prototype.updatePD = function() {
var pulldown = document.getElementById('pulldown');
// clear values in pulldown
for (var a = pulldown.length-1; a>=0; a--)
pulldown.options[a] = null;
// populate First option
pulldown.options[0] = new Option('First', 'First');
// populate Second option
if (parseInt(this.techlevel) >= 2) pulldown.options[1] = new Option('Second', 'Second');
// loop through and select the technology base if it is present
for (var b=0; b<pulldown.length; b++)
pulldown.options[b].selected = (pulldown.options[b].value == this.techbase) ? true : false;
// Make sure the current value matches what is selected
this.techbase = (pulldown.value != this.techbase) ? pulldown.value : this.techbase;
}
var t = new TObj();
</script>
</body>
</html>
When I run this code and click the button, it then creates two options in the pulldown. One for 'First' and one that is blank. Do you get the same result? (please say yes

)
Posted: Thu Dec 27, 2007 4:47 pm
by VladSun
YES!
Strange ... if you put an alert(b) in this loop, problem disappears ... Honestly, I hate Opera ... a little
Ok, this will work :
Code: Select all
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body>
<input type="button" value="Click Me!" onClick="t.updatePD()">
<select id="pulldown">
<option value="First">First</option>
<option value="Second">Second</option>
<option value="Third">Third</option>
</select>
<script language="JavaScript">
function TObj()
{
this.techbase = 'Second';
this.techlevel = 2;
this.updatePD = TObj_updatePD;
}
function TObj_updatePD()
{
document.body.removeChild(document.getElementById('pulldown'));
var pulldown = document.createElement('select');
pulldown.id = 'pulldown';
document.body.appendChild(pulldown);
// populate First option
opt = document.createElement("option");
opt.value = 'First';
opt.innerHTML = 'First';
pulldown.appendChild(opt);
// populate Second option
if (parseInt(this.techlevel) >= 2)
{
opt = document.createElement("option");
opt.value = 'Second';
opt.innerHTML = 'Second';
pulldown.appendChild(opt);
}
// loop through and select the technology base if it is present
for (var a=0; a<pulldown.length; a++)
{
if (pulldown.options[a].value == this.techbase)
{
pulldown.selectedIndex = a;
break;
}
}
// Make sure the current value matches what is selected
this.techbase = (pulldown.value != this.techbase) ? pulldown.value : this.techbase;
}
var t = new TObj();
</script>
</body>
</html>
Posted: Thu Dec 27, 2007 7:01 pm
by SBukoski
That is weird. If I remove the child and re-create it (even if all my other code remains the same), then everything works fine.
Would you consider this an Opera bug?
Posted: Fri Dec 28, 2007 4:33 am
by VladSun
In my opinion, Opera has many small bugs like this one - I've always had problems with Opera ...
Posted: Fri Dec 28, 2007 7:51 am
by SBukoski
VladSun wrote:In my opinion, Opera has many small bugs like this one - I've always had problems with Opera ...
Maybe that's why it's used by only 1.8% of the users.
Posted: Sun Jan 06, 2008 4:33 am
by Popcorn
Hi,
This is a bug that was submitted to Opera and tripped me up in the same way. See
http://my.opera.com/community/forums/to ... ?id=147949,
http://my.opera.com/community/forums/to ... ?id=149207
Very annoying.
Our work is the prime example that market share rarely has any relation to an objective measure of quality

but damn they are taking their time to fix this.
Glad that you guys are testing for Opera tho (no I am not in their employ

).
Happy coding!