Dynamic options in Opera

JavaScript and client side scripting.

Moderator: General Moderators

Post Reply
SBukoski
Forum Contributor
Posts: 128
Joined: Wed May 21, 2003 10:39 pm
Location: Worcester, MA

Dynamic options in Opera

Post 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.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Post 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.
There are 10 types of people in this world, those who understand binary and those who don't
SBukoski
Forum Contributor
Posts: 128
Joined: Wed May 21, 2003 10:39 pm
Location: Worcester, MA

Post 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.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Post 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>

There are 10 types of people in this world, those who understand binary and those who don't
SBukoski
Forum Contributor
Posts: 128
Joined: Wed May 21, 2003 10:39 pm
Location: Worcester, MA

Post 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 :))
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Post 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>
There are 10 types of people in this world, those who understand binary and those who don't
SBukoski
Forum Contributor
Posts: 128
Joined: Wed May 21, 2003 10:39 pm
Location: Worcester, MA

Post 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?
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Post by VladSun »

In my opinion, Opera has many small bugs like this one - I've always had problems with Opera ...
There are 10 types of people in this world, those who understand binary and those who don't
SBukoski
Forum Contributor
Posts: 128
Joined: Wed May 21, 2003 10:39 pm
Location: Worcester, MA

Post 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.
User avatar
Popcorn
Forum Commoner
Posts: 55
Joined: Fri Feb 21, 2003 5:19 am

Post 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!
Post Reply