Click here to Skip to main content
15,891,136 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I'm using JavaScript to create some HTML. So I'm creating the HTML in JavaScript, using createElement in a loop.

I was having issues between Mozilla and Internet Explorer, but have seperated the 2, and now I'm down to the last issue.

In my array loop for IE, this works, but the value ends up being the last idx of the array, so the last image in the list is always selected.

I can't figure out how to create sort of a static link, so each image has the appropriate unique file name assigned to it in the DOM. I know if I create a var, the var will just keep changing to the new value, at least I think so.

[Internet Explorer]
var table_Object = document.createElement("table");
table_Object.id = "_table_PreviewCell_Container_" + idx;
table_Object.className = "_colorChange";
table_Object.cellPadding = "0";
table_Object.cellSpacing = "0";
table_Object.border = "0";
table_Object.onclick = function () { load_ModalPreview(fbType, image_Object[idx].image_Filename); };
table_Object.style.cursor = "hand";
table_Object.style.cursor = "pointer";
table_Object.style.width = "96%";
table_Object.style.backgroundColor = "rgb(255,255,255)";
tableCell_Container.appendChild(table_Object);


In Mozilla, I did this, which works, but I was warned to never use setAtributes, and would like to get around it. And it doesn't work in IE7 and 8

[Mozilla]
var table_Object = document.createElement("table");
table_Object.id = "_table_PreviewCell_Container_" + idx;
table_Object.className = "_colorChange";
table_Object.cellPadding = "0";
table_Object.cellSpacing = "0";
table_Object.border = "0";
table_Object.setAttribute("onclick", "load_ModalPreview('" + fbType + "', '" + image_Object[idx].image_Filename + "');");
table_Object.style.cursor = "hand";
table_Object.style.cursor = "pointer";
table_Object.style.width = "96%";
table_Object.style.backgroundColor = "rgb(255,255,255)";
tableCell_Container.appendChild(table_Object);


[EDIT] by request - The whole loop with new code change for onclick - purpose to perhaps consolidate 2 versions into one that works on both.

// Use Ajax to Load the Library in the DOM
$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "productEditor.asmx/load_Library",
    data: "{\"fbType\" : \"" + fbType + "\"}",
    dataType: "json",
    success: function (responseText) {

        eval('(' + responseText.d + ')');
        var objB = jQuery.parseJSON(responseText.d);

        var image_ExitCode = objB.image_ExitCode;
        var image_Objects = objB.image_Objects;
        var image_Object = image_Objects.image_Object;
        var array_Length = image_Object.length;

        if (bMSIE == true) {
            // We have a non gecko Browser, Internet Explorer
            var table_Container = document.createElement("table");
            table_Container.cellPadding = "0";
            table_Container.cellSpacing = "0";
            table_Container.border = "0";
            table_Container.style.width = "97%";
            table_Container.style.display = "block";
            //table_Container.style.border = "solid 1px orange";

            var tr_ContainerRow = table_Container.insertRow(-1);
            var trx = 0;

            // Loop through the array and build the html
            for (idx = 0; idx < array_Length - 1; idx++) {

                var tableCell_Container = tr_ContainerRow.insertCell(-1);
                tableCell_Container.vAlign = "top";
                tableCell_Container.style.width = "20%";
                tableCell_Container.style.height = "102px";
                tableCell_Container.style.textAlign = "center";
                //tableCell_Container.style.border = "solid 1px green";
                tr_ContainerRow.appendChild(tableCell_Container);

                var temp_Data = image_Object[idx].image_Filename;
                var table_Object = document.createElement("table");
                table_Object.id = "_table_PreviewCell_Container_" + idx;
                table_Object.className = "_colorChange";
                table_Object.cellPadding = "0";
                table_Object.cellSpacing = "0";
                table_Object.border = "0";
                table_Object.onclick = (function (fbType, temp_Data) { return function () { load_ModalPreview(fbType, temp_Data) } })(fbType, temp_Data);
                table_Object.style.cursor = "hand";
                table_Object.style.cursor = "pointer";
                table_Object.style.width = "96%";
                table_Object.style.backgroundColor = "rgb(255,255,255)";
                tableCell_Container.appendChild(table_Object);

                // Image Markup Tag
                var tr_Object_Image = table_Object.insertRow(-1);

                var td_Object_Image = document.createElement("td");
                td_Object_Image.style.width = "100%";
                td_Object_Image.style.height = "72px";
                td_Object_Image.style.textAlign = "center";
                td_Object_Image.style.verticalAlign = "middle";
                tr_Object_Image.appendChild(td_Object_Image);

                var img_Thumbnail = document.createElement("img");
                img_Thumbnail.src = image_Object[idx].image_Thumbnail;
                img_Thumbnail.alt = truncate(image_Object[idx].image_Filename, 15);
                img_Thumbnail.style.margin = "2px";
                td_Object_Image.appendChild(img_Thumbnail);

                // Image File Name
                var tr_Object_Filename = table_Object.insertRow(-1);

                var td_Object_Filename = document.createElement("td");
                td_Object_Filename.style.width = "100%";
                td_Object_Filename.style.height = "12px";
                td_Object_Filename.style.textAlign = "center";
                tr_Object_Filename.appendChild(td_Object_Filename);

                var span_Filename = document.createElement("span");
                span_Filename.style.color = "rgb(0,0,0)";
                span_Filename.style.fontSize = "0.6em";
                span_Filename.innerText = truncate(image_Object[idx].image_Filename, 15);
                td_Object_Filename.appendChild(span_Filename);

                // Image File Date
                var tr_Object_Filedate = table_Object.insertRow(-1);

                var td_Object_Filedate = document.createElement("td");
                td_Object_Filedate.style.width = "100%";
                td_Object_Filedate.style.height = "12px";
                td_Object_Filedate.style.textAlign = "center";
                tr_Object_Filedate.appendChild(td_Object_Filedate);

                var span_Filedate = document.createElement("span");
                span_Filedate.style.color = "rgb(0,0,0)";
                span_Filedate.style.fontSize = "0.6em";
                span_Filedate.innerText = image_Object[idx].image_Filedate;
                td_Object_Filedate.appendChild(span_Filedate);

                // Image Lower Spacer
                var tr_Object_LowerSpacer = table_Object.insertRow(-1);

                var td_Object_LowerSpacer = document.createElement("td");
                td_Object_LowerSpacer.style.width = "100%";
                td_Object_LowerSpacer.style.height = "4px";
                td_Object_LowerSpacer.style.textAlign = "center";
                td_Object_LowerSpacer.innerText = " "
                tr_Object_LowerSpacer.appendChild(td_Object_Filedate);

                //////////////////////////////////////////////////////////
                if (trx == 4) {
                    trx = 0;
                    var tr_ContainerRow = table_Container.insertRow(-1);
                }
                else {
                    trx++
                }
            }

        } // End of bMSIE == true
        else {

            // bMSIE = false, We have a Gecko Browser, thank god
            var table_Container = document.createElement("table");
            table_Container.cellPadding = "0";
            table_Container.cellSpacing = "0";
            table_Container.border = "0";
            table_Container.style.width = "98%";
            table_Container.style.display = "block";
            table_Container.style.textAlign = "center";
            table_Container.style.margin = "0px auto";
            //table_Container.style.border = "solid 1px orange";

            var tr_ContainerRow = document.createElement("tr");
            table_Container.appendChild(tr_ContainerRow);
            var trx = 0;

            // Loop through the array and build the html
            for (idx = 0; idx < array_Length - 1; idx++) {

                var tableCell_Container = tr_ContainerRow.insertCell(-1);
                tableCell_Container.vAlign = "top";
                tableCell_Container.style.width = "150px";
                tableCell_Container.style.height = "102px";
                tableCell_Container.style.textAlign = "center";
                //tableCell_Container.style.border = "solid 1px green";
                tr_ContainerRow.appendChild(tableCell_Container);

                var temp_Data = image_Object[idx].image_Filename;
                var table_Object = document.createElement("table");
                table_Object.id = "_table_PreviewCell_Container_" + idx;
                table_Object.className = "_colorChange";
                table_Object.cellPadding = "0";
                table_Object.cellSpacing = "0";
                table_Object.border = "0";
                table_Object. önclick = (function (fbType, temp_Data) { return function () { load_ModalPreview(fbType, temp_Data) } })(fbType, temp_Data);
                table_Object.style.cursor = "hand";
                table_Object.style.cursor = "pointer";
                table_Object.style.width = "96%";
                table_Object.style.backgroundColor = "rgb(255,255,255)";
                tableCell_Container.appendChild(table_Object);

                // Image Markup Tag
                var tr_Object_Image = document.createElement("tr");
                table_Object.appendChild(tr_Object_Image);

                var td_Object_Image = document.createElement("td");
                td_Object_Image.style.width = "100%";
                td_Object_Image.style.height = "72px";
                td_Object_Image.style.textAlign = "center";
                td_Object_Image.style.verticalAlign = "middle";
                tr_Object_Image.appendChild(td_Object_Image);

                var img_Thumbnail = document.createElement("img");
                img_Thumbnail.src = image_Object[idx].image_Thumbnail;
                img_Thumbnail.alt = truncate(image_Object[idx].image_Filename, 15);
                img_Thumbnail.style.margin = "2px";
                td_Object_Image.appendChild(img_Thumbnail);

                // Image File Name
                var tr_Object_Filename = document.createElement("tr");
                table_Object.appendChild(tr_Object_Filename);

                var td_Object_Filename = document.createElement("td");
                td_Object_Filename.style.width = "100%";
                td_Object_Filename.style.height = "12px";
                td_Object_Filename.style.textAlign = "center";
                tr_Object_Filename.appendChild(td_Object_Filename);

                var span_Filename = document.createElement("span");
                span_Filename.style.color = "rgb(0,0,0)";
                span_Filename.style.fontSize = "0.6em";
                span_Filename.innerHTML = truncate(image_Object[idx].image_Filename, 15);
                td_Object_Filename.appendChild(span_Filename);

                // Image File Date
                var tr_Object_Filedate = document.createElement("tr");
                table_Object.appendChild(tr_Object_Filedate);

                var td_Object_Filedate = document.createElement("td");
                td_Object_Filedate.style.width = "100%";
                td_Object_Filedate.style.height = "12px";
                td_Object_Filedate.style.textAlign = "center";
                tr_Object_Filedate.appendChild(td_Object_Filedate);

                var span_Filedate = document.createElement("span");
                span_Filedate.style.color = "rgb(0,0,0)";
                span_Filedate.style.fontSize = "0.6em";
                span_Filedate.innerHTML = image_Object[idx].image_Filedate;
                td_Object_Filedate.appendChild(span_Filedate);

                // Image Lower Spacer
                var tr_Object_LowerSpacer = document.createElement("tr");
                table_Object.appendChild(tr_Object_LowerSpacer);

                var td_Object_LowerSpacer = document.createElement("td");
                td_Object_LowerSpacer.style.width = "100%";
                td_Object_LowerSpacer.style.height = "6px";
                td_Object_LowerSpacer.style.textAlign = "center";
                td_Object_LowerSpacer.innerHTML = " "
                tr_Object_LowerSpacer.appendChild(td_Object_Filedate);

                //////////////////////////////////////////////////////////
                if (trx == 4) {
                    trx = 0;
                    tr_ContainerRow = document.createElement("tr");
                    table_Container.appendChild(tr_ContainerRow);
                }
                else {
                    trx++
                }
            }
        }

        $('[id*="_panel_Preview_Object"]').empty();
        $('[id*="_panel_Preview_Object"]').append(table_Container);
        $("_table_Progress").hide('fast');


        $('[id*="_table_PreviewCell_Container_"]').bind('mouseover', function () {
            $(this).css("background-color", "#C6DEFF");
        });

        $('[id*="_table_PreviewCell_Container_"]').bind('mouseout', function () {
            $(this).css("background-color", "#FFFFFF");
        });
    },
    error: AjaxFailed
Posted
Updated 16-Jul-12 10:03am
v2
Comments
Karthik. A 16-Jul-12 14:47pm    
I guess posting the entire code might help. To begin with, are you sure that you are incrementing "idx" ? And have you considered using jQuery instead of writing the same code with very little variations (onclick) for every browser ?
jkirkerx 16-Jul-12 16:08pm    
After coming back from lunch, I searched again with new words, and found a more advanced version of using function, that retains the value while looping.

I went ahead and posted the whole loop, perhaps I can merge the 2 versions into a unified version, with some tutoring from a more skilled JavaScript programmer than me.

The only difference between the 2 is using innnerHTML on the span tag, and the tableRows (tr), and 1 css width value in tableCell_Container.

Thanks for the response, appreciate it!

1 solution

I think the name of the language feature that will save you here is 'closures'.

Basically, by encapsulating a section of code in round braces, followed by a pair of them - as used by a function call, you cause the javascript engine to maintain any variables, rather than chucking them away.

This has the effect of giving you a new instance of any variables for each time the loop is run. Probably horrible in terms of memory consumption - though it is functional, even if really, really ugly.

I should probably confess to having never heard of them before earlier this week..
I'd be dissapointed but not surprised if I've just commited a code-horror...

Here's some code I just bashed together that will create 4 divs, style them with some css and show an alert box displaying the corresponding image name for each div. I don't have FF installed at the moment and don't feel like digging it up, though the code has been tested with Chrome and IE6 - the only difference being that the :hover selector doesn't work in IE.

HTML
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style>
		.myDiv
		{
			cursor: pointer;
			width: 96%;
			background-color: white;
			display: inline;
		}
		.myDiv:hover
		{
			font-weight: bold;
		}
		#myDiv1{color: #111;}
		#myDiv2{color: #311;}
		#myDiv3{color: #511;}
		#myDiv4{color: #711;}
		
	</style>
	<script>
        var imgNames = new Array("img/rss16.png", "img/girl.png", "img/rss128.png", "img/logo.gif");
    
		function loadModalPreview(filename)
		{
			alert(filename);
		}
	
		function myInit()
		{
			var index, curDiv, numImages;
			var numImages = imgNames.length;
			for (index=0; index<numImages; index++)
			{
				(
					function()
					{
						var curFilename;
						var curFuncStr;
						curDiv = document.createElement('div');
						curDiv.className = "myDiv";// + (index+1);
						curDiv.id = "myDiv" + (index+1);
						curDiv.appendChild( document.createTextNode("Image: "+ (index+1) ) );
						curFilename = imgNames[index];
						curFuncStr = "loadModalPreview('"+curFilename+"');";

						curDiv.setAttribute('onclick', curFuncStr);
						
						curDiv.onclick = function () { loadModalPreview("'" + curFilename + "'"); } 
						document.body.appendChild(curDiv);
						document.body.appendChild(document.createElement('br'));
					}
				)();
			}
		}
	</script>
</head>
<body onload="myInit();">
</body>
</html>
 
Share this answer
 
v2
Comments
jkirkerx 16-Jul-12 16:35pm    
Thanks enhzflep

I read about closures last night on my iPhone, but did not put the 2 together till I read your comment. I had the version problem, and the closure came up today under final testing. I should fix the versions, but I've been working on this for 3 weeks now, head is kind of fried. I need to get back to my c++ program and fix some threads.

Thanks for taking the time to demostrate closure to me. It does work in firefox, just tested it, and I fixed the hover

curDiv.style.cursor = "hand";
curDiv.style.cursor = "pointer";

You explanation of how it works was easier to understand, and now I get it. Ready to get bolder soon with Javascript.

Oh, if your wondering what the function is for, it's sort of like ckEditor, in which you click on the image, and a popup window comes up asking you upload new image, browse server library, generates new images to the correct sizes and updates the main browser window thumbnail and hidden textboxes, closes popup.

I'm surprised that your knowledge overlaps into JavaScript. Didn't think you did any web work, just OS stuff.

Question:
curDiv.appendChild(document.createTextNode("Image: " + (index + 1)));

Is this more of a common way to add elements, or just a quick shortcut to finish the task?
enhzflep 16-Jul-12 16:48pm    
That's okay jkirkerx, it made for a refreshing break away from non-mfc COM work. It also gave me a chance to test my understanding of closures and at the same time understand some code I ripped years back for doing fade ins/outs.

Re: the broken hover, The ":hover" css selector was what I'd meant - the text gets bold when moused-over, just doesn't work in IE6. Setting the same attribute to 2 different values will just leave the most recent one in place.
curDiv.style.cursor = "hand";
curDiv.style.cursor = "pointer";

is functionally identical to

curDiv.style.cursor = "pointer";



As for the way I added some text, a text-node is something of a special case - you can't do anything to 'em apart from give 'em a value. With that in mind, it seemed unnecessary to save it to a variable before adding it to the curDiv
This would be equivalent (but undoubtedly that little bit slower/more memory hungry)
curText = document.createTextNode("Image: " + (index + 1) );
curDiv.appendChild(curText);

EDIT: Surprised to see you here too! Knew it would be an intelligent/interesting Q when I saw jkirkerx as the poster.
jkirkerx 16-Jul-12 18:34pm    
Well sometimes I do ask dumb questions, but not today.

I thought cursor hand and pointer was for IE and Mozilla, and one would pickup and read, like moz-border. I'll look into that.

I used the Javascript discussion earlier, but only the crickets were lurking, guess it's not that strong of a subject here on the CJ.

As far as memory hungry goes, I need to run some test to see how much memory my script consumes, or if it leaks. I'm pretty sure I used var's in an efficient way this time, but you never know.

Well thanks for the professional help today. I appreciate it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900