Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Create dynamic 'span' elements from 'select' element

Status
Not open for further replies.

Slippenos

MIS
Apr 22, 2005
333
US
I am trying to dynamically alter the state of a select element (with a default height of 6 options) and swap it with 6 span elements.

Disabling the select is not an option.

Code:
// Create variables for the select box element and get the height of the select box

var scorecardSelector = document.thisForm.scorecard_selected; 
var numSpans = parseInt(document.thisForm.scorecard_selected.size);
var stack = [];

// Push each select box's text (up to the max visible) into a one-dimensional array

for (optionCounter = 0; optionCounter < numSpans; optionCounter ++){

   // ... if the height is greater than the number of options
   try{
      stack.push(scorecardSelector[optionCounter].text);
   }catch (err){
      stack.push("");
   }
}

// Put select box's text values in order

stack.reverse();

// Pop out each item in the array and create span elements for them

while (stack.length > 0){
   var current = stack.pop();
   var newSpan = document.createElement("span");
      // some css ...
      newSpan.setAttribute("id", "n10");
   var scorecardName = document.createTextNode(current.valueOf());
      newSpan.appendChild(scorecardName);
   var parentSpan = current.parentNode;
      parentSpan.replaceChild(newSpan, current);       
   } 
}

Once all of the span elements are created- my idea is just use the replaceChild function and swap the select element with the newSpan(s).

However it is not working.

Please lend me some insight as to how I can resolve this issue. Any help is greatly appreciated.

Thanks in advance,
Mike.

[blue]Go to work to learn. Don't go to work to earn.[/blue]
 
Several possible points of note:

You're missing a base specifier when using parseInt:

Code:
var numSpans = parseInt(document.thisForm.scorecard_selected.size[!], 10[/!]);

You *might* (in some browsers) need to explicitly reference the options collection:

Code:
stack.push(scorecardSelector[!].options[/!][optionCounter].text);

and you are creating n spans all with the same ID (which is totally invalid):

Code:
newSpan.setAttribute("id", "n10");

If the array only holds text, why use "valueOf"?

Code:
var scorecardName = document.createTextNode(current[s].valueOf()[/s]);

But this is the most likely candidate:

Code:
var parentSpan = current.parentNode;

I've not tried the code, but isn't "current" purely a text string rather than an element?

If all else fails, tell us a bit more about how it's not working, or better still, install Firefox, and see what errors the JS console is showing.

Hope this helps,
Dan

Coedit Limited - Delivering standards compliant, accessible web solutions

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
BillyRayPreachersSon,

Thank you very much for the great post. I don't consider myself that great at JS, but its posts like yours that really help all of us [get better].

BTW, The 'id' attribute was meant to be a 'class' attribute. I definately missed that one.

Unfortunately, my application is not compatible with Firefox (some CSS and presentation issues)- so I cannot use the console feature.

However, IE6 tells me that 'undefined is null or not an object'.

and breaks on:
Code:
parentSpan.replaceChild(newSpan, current);

My intent for the variable 'current' is to hold the text of the option, not the value itself.

Any thoughts? Suggestions?

[blue]Go to work to learn. Don't go to work to earn.[/blue]
 
Yes - if current holds text, then it is not an element. You'd need to create one (a span, etc) to hold the text.

AFAIK, only elements can be passed to "replaceChild".

You've got me wondering now... what "CSS and presentation issues" are there that would stop your site working in Firefox? Are they things that you've specifically chosen to do with browser-specific code, or just stuff that you've not worked out how to make cross-browser?

Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

[tt]Dan's Page [blue]@[/blue] Code Couch
[/tt]
 
There are cross-browser issues that have yet to be worked out.

I'll continue along with your suggestions. Thanks.

[blue]Go to work to learn. Don't go to work to earn.[/blue]
 
Code:
<html>
<head>
<title>Dynamic div</title>
<style type="text/css">

.n10 {
	font-family: Arial;
	font-size: 10px;
	font-style: normal;
	font-variant: normal;
	font-weight: normal;
	color: black;
}

</style>
<script language="JavaScript">

function change(){
	var scorecardSelector = document.thisForm.scorecard_selected; 
	var stack = [];

	// Push each scorecard name (up to the max visible) into a one-dimensional array

	for (optionCounter = 0; optionCounter < document.thisForm.scorecard_selected.size; optionCounter ++){
		try{
			[red]stack.push(scorecardSelector.options[optionCounter].text + "\n");[/red]
		}catch (err){
			stack.push("");
		}
	}

	stack.reverse();

	// Pop out each item in the array and create a div element

	var newDiv = document.createElement("div");

	while (stack.length > 0){
		var current = stack.pop();
		var scorecardName = document.createTextNode(current);
			newDiv.appendChild(scorecardName);
	} 

	// Replace scorecard selector with newly created div

	var oReplaceNode = document.getElementById("selector").childNodes(0);
		oReplaceNode.replaceNode(newDiv);

	document.forms['thisForm'].elements['thisButton'].disabled = true;
}	
	
</script>
</head>
<form name="thisForm">
	<span id="selector" class="n10">
	<select name="scorecard_selected" class="n10" style="width: 50%;" size="6">
		<option value="1">Scorecard 1 - Mike</option>
		<option value="2">Scorecard 2 - Chuck</option>
		<option value="3">Scorecard 3 - Jim</option>
		<option value="4">Scorecard 4 - Greg</option>
	</select>
	</span>

	<br />
	<br />

	<input type="button" name="thisButton" value="Click to convert" onClick="javascript:change();">
</form>
</body>
</html>

I created this file in case anyone was interested in what I was attempting. I have tried in vain to create multiple spans, but to no avail, as they are overwritten each time in the loop.

The only thing I cannot do with the above code is insert a line break (it comes out as one line).

I don't even know if its possible ..

PS This does not work in Firefox, only IE.

[blue]Go to work to learn. Don't go to work to earn.[/blue]
 
OK, best solution I could come up with (see comments for details):

Code:
<html>
<head>
<title>Dynamic divs</title>
<style type="text/css">

.n10 {
	font-family: Arial;
	font-size: 10px;
	font-style: normal;
	font-variant: normal;
	font-weight: normal;
	color: black;
}

</style>
<script language="JavaScript">

function change(){
	
	// create a list and store each option in it
	var scorecardSelector = document.getElementById("scorecard_selected"); 
	var stack = [];
	
	for (i = 0; i < scorecardSelector.size; i ++){
		// in case the number of options are fewer than the select height
		try{
			stack.push(scorecardSelector.options[i].text);
		}catch (err){
			stack.push("");
		}
	}
	
	// 1. create one-dimensional array to store div elements
	// 2. create divs (block-element for line-breaking) and push them into the array	
	var divArray = new Array(1);

	for (x = 0; x < scorecardSelector.size; x ++){
		
		var current = stack.pop();
		var scorecardName = document.createTextNode(current);
		var newDiv = document.createElement("div");
			newDiv.setAttribute("className", "n10", 0);
			newDiv.appendChild(scorecardName);
				
		divArray[x] = newDiv; 
			
	} 
	
	// reverse so they come out in order	
	divArray.reverse();
	
	// create a span to replace with the span that holds the select element	
	var newSpan = document.createElement("span");
	document.getElementById("selector").replaceChild(newSpan, scorecardSelector)
	
	// 1.  Loop through the array pulling out the newly created divs and
	// 2.  append the newly created span
	for (z = 0; z < scorecardSelector.size; z ++){
		
		newSpan.appendChild(divArray[z]);
		
	}
	
	// I will not let you click this again because it throw an error at you
	document.forms['thisForm'].elements['thisButton'].disabled = true;
	}	
	
</script>
</head>
<form name="thisForm">
	<!-- parent -->
	<span id="selector" class="n10">
	<!-- child -->
	<select name="scorecard_selected" class="n10" style="width: 50%;" size="6">
		<option value="1">Scorecard 1 - Mike</option>
		<option value="2">Scorecard 2 - Chuck</option>
		<option value="3">Scorecard 3 - Jim</option>
		<option value="4">Scorecard 4 - Greg</option>
	</select>
	</span>

	<br />
	<br />

	<input type="button" name="thisButton" value="Click to convert" onClick="javascript:change();">
</form>
</body>
</html>

PS: This will only work with IE. That was my intent from the beginning.

If anyone thinks that there is a better way- please let me know.

Thanks,
Mike

[blue]Go to work to learn. Don't go to work to earn.[/blue]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top