Saturday, September 17, 2005

Divs, Iframes, and Windows rendering

Been a long weekend debugging a bunch of pop-ins that we're using that were hosed because of IE's rendering of Selects. The divs that were being popped-in overlapped some selects are were thus subject to the nasty effect of the Selects bleeding through. I was trying to glean code from the DatePicker.js in Tapestry, but the way it automatically generates the coordinates for the calendar was a little too tricky for what we need. And, I couldn't get it to work right (after 2-3 hours!). Thankfully it was helpful enough to illustrate the necessity of generating an IFrame (which takes rendering precedence) under the div. I had that working except in some cases the iframe was out of synch with the div so the locations appear hosed.

Anyhow, long story short, thanks to this blog from Joe King at MS, it clicked that I was 90% of the way there but was missing only a couple small things. After another hour of tweaking, I have a solution.

Assuming you have a DIV that is your pop-in already placed where you want it to show, it's just a matter of adding the following code and calling "hideOrShowPop" (stupid, yes, I should rename it):


function hideOrShowPop(id){
var popin= document.getElementById(id);
var idToFetch = id + "Active";
var popinActive = document.getElementById(idToFetch);

if(popin.style.visibility=="hidden"){
handlePop(id);
}
else{
popin.style.visibility="hidden";

var clone = document.getElementById("clone"+id);
if(clone != null){
clone.style.visibility="hidden";
clone.removeNode(true);
}
}
}

function handlePop(id){
var popinDiv = document.getElementById(id);
var anchorNode = document.getElementById(id+"Anchor");

popinDiv.style.visibility="visible";
popinDiv.style.display="block";

var cloneDiv = popinDiv.cloneNode(false);
//this is for figuring out how to put the popin ANYWHERE on the screen, currently not working
//var anchorPoint = getLocationPoint(anchorNode);
//popinDiv.style.top = anchorPoint.y;
//popinDiv.style.left = anchorPoint.x;

var width = parseInt(popinDiv.style.width);
var height = parseInt(popinDiv.style.height);

cloneDiv.id = "clone" + id;
try{
cloneDiv.zIndex="3";
cloneDiv.innerHTML = "";
popinDiv.parentNode.appendChild(cloneDiv);
popinDiv.parentNode.appendChild(popinDiv);
} catch(e){
alert("Popin exception caused by id: " + idToFetch + " or " + id);
if(ie)
alert(e.description);
else
alert(e);
}
}


So the code clones the div, then sets the inner node of the cloned div to an iframe. Lastly it's appended to whomever owns the original div, and then the original div is appended after the clone.

Now I can go to bed.

No comments: