[Mapserver-users] integrating HTML Legends with dbox/javascript landview framework

Emilio Mayorga emiliom at u.washington.edu
Wed Feb 4 23:25:08 EST 2004


Hi (specially Steve Lime),

A few weeks ago I asked about HTML legends and the DHTML/javascript 
"landview" application. The problem was this: how do you load into the 
page the result of the cgi statement that creates the HTML legend? I 
found a partial solution using an iframe, and someone else mentioned 
their own solution -- which, while it worked fine, it was implemented 
using a cross-browser DHTML/javascript library other than CBE. Steve, 
since you mentioned you were interested in this topic, I'm reporting 
some progress I made.

A problem with using an iframe element is that the html legend becomes 
isolated from the rest of the document -- it's its own document. Also, 
the HTML Legend parser ignores all html outside the special tags in the 
legend template file. So, you can't define an external CSS file or add 
javascript code to the html legend. That's a real bummer.

* Here's what I've done. I use an "invisible" iframe. I define the 
iframe element, give it an id attribute, and set the element visibility 
to hidden. I also define an empty div element, with an id:

<iframe id="legendiframe" src="blank.html" style="visibility:hidden" 
width="1" height="1" scrolling="auto" frameborder="0">
[your browser can't display frames]
</iframe>

<div id="legenddiv"></div>

* In the postdraw() function, I update the legend by setting the src 
attribute of the iframe to the HTML legend cgi line. Then, I use the 
iframe's contentDocument property and innerHTML to suck in all the HTML 
& text found within the iframe body element, then stuff it on my empty 
div, again using innerHTML.

// update the legend
var legifrm = document.getElementById("legendiframe");
legifrm.src = MapServer + "?map=" + mapfile + "&mode=legend&mapext=0+0+" 
+ (ms.extent[2] - ms.extent[0]) + "+" + (ms.extent[3] - ms.extent[1]) + 
"&mapsize=" + ms.width + "+" + ms.height;

// contentDocument is defined in the W3C DOM, but contentWindow is
// the only method in the IE DOM; Mozilla 1+ (NN7+) defines both
if (document.getElementById("legenddiv"))
{
   var ifrmdoc = (legifrm.contentDocument) ? legifrm.contentDocument :
     ((legifrm.contentWindow) ? legifrm.contentWindow.document : null);
   var getiframebody = ifrmdoc.getElementsByTagName("body");
   document.getElementById("legenddiv").innerHTML =
                                    getiframebody[0].innerHTML;
}

* It works! It's very flexible because you can stuff the HTML legend 
content into any element you want, not just a div; for example, adding 
rows to a table element, or adding a complete table with rows. It's also 
very clean and simple, though using innerHTML is a little inelegant. And 
of course, now your legend html is exposed to the general context, 
external CSS, javascript, etc.

HOWEVER, there is one bug: the resulting legend content is always one 
step behind the actual current legend. It's very noticeable if you have 
scale-specific classes and the legend flags are set to be sensitive to 
scale. I think it has to do with the div element not knowing that the 
content of the iframe has been updated, but I can't figure it out. 
Steve, any suggestions??

-Emilio Mayorga




More information about the mapserver-users mailing list