[Mapserver-users] integrating HTML Legends with dbox/javascript landview framework
Emilio Mayorga
emiliom at u.washington.edu
Wed Feb 4 20:25:08 PST 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