Thanks in large part to help from George Rhee, I was able to isolate a bug in the code that prevented it from working properly on certain sites. The problem came about if the Maps Link column was the last column on the list and manifest itself by demolishing the columns and formatting of the list. I found a way to prevent this and now it will work regardless of where the column is in relation to other columns in the list.
I've also updated the code so that the maps popup will show up within the body of the page you're viewing. No more having to scroll right and/or down to see your maps!
If you have a list of addresses that you want to create dynamic Google Maps for then this blog's for you! It's actually really easy ... I promise.
Here's how:- You'll need a list that has a column of addresses. For the purpose of this post, I have cleverly decided to use the column name of "Address" to represent my column of addresses. Yes I've had 5 cups of coffee today, why do you ask?
- Create another column to hold the links that will open the Google Map. Again, I have cleverly titled this column "Google Maps Link". This column will be a calcuated column with the following code:
=CONCATENATE("<div style='cursor:hand' onClick='showMap(this, event)'>",Address,"</div><tag>") - At the bottom of the page that will display these addresses, include a Content Editor Web Part with the following code:
<div id='mapDiv' style='display:none;position:absolute;'>
<div
onClick='hideMap()'
style='border-style:solid;
border-width:1px;
background:red;
position:absolute;
top:0px;
left:554px;
cursor:hand;'>
close(x)
</div>
<iframe
id='mapFrame'
frameborder='0'
src=''
style='width:600px;
height:600px;
border-style:solid;
border-width:1px'>
</iframe>
</div>
<script type="text/javascript">
//
// declare variables
var theTags = document.getElementsByTagName("TD");
var i=0;
var objFrame = document.getElementById("mapFrame");
var objDiv = document.getElementById("mapDiv");
var out = document.getElementById("output");
//
// write the calculated column into the page code
while (i < theTags.length)
{ try
{ TagContent = theTags[i].textContent || theTags[i].innerText;
if (TagContent.substr(TagContent.search("<tag>")) == "<tag>" && theTags[i].className == "ms-vb2")
{ theTags[i].innerHTML = TagContent; }
}
catch(err){}
i=i+1;
}
//
// function to make the map appear at the mouse
function showMap(obj, event)
{
urlMaps = "http://maps.google.com/maps?q=";
objFrame.src = urlMaps + (obj.innerText || obj.textContent);
objDiv.style.display = "";
(event.clientY + 600 > document.body.offsetHeight) ? objDiv.style.top = (document.body.offsetHeight - (event.clientY - 600)) : objDiv.style.top = event.clientY;
(event.clientX + 600 > document.body.offsetWidth) ? objDiv.style.left = (event.clientX - 600) : objDiv.style.left = event.clientX;
}
//
// function to hide the map
function hideMap()
{ objFrame.src = ""; objDiv.style.display = "none"; }
</script>
Enjoy!


9 comments:
Cool, except that when I do it I lose my column... suggestions?
Can you send a screen shot and a description of the list that you're working with?
Hi Sumit,
I gather by the deletion that you figured it out, congrats!
-Ben
I'd like to use this for a Car Pool site I need to create.
The Google Maps Link column us a Calculated column set to return a single line of text. It will actually reutrn the code of the DIV tag (I cannot actually post the value as it is not accepted in this post)
I copied and pasted the code into the a Content Editor WebPart and it is blank. I also removed the comments from the code and there is no change. Any help would be great, Thanks
Hi George,
The DIV code being shown is good, it's actually supposed to do that so that the Javascript can identify it and re-write it.
Because it's not being re-written, that means that the Javascript isn't identifying it properly. As long as you're pasting the javascript code into the "Source Editor..." of the CEWP that is BELOW the list, this should work.
If this doesn't work, please feel free to send me some screenshots and I'll do what I can to help.
Ben,
This is off topic but this post is the closest to my problem that I've been able to find.
I'm trying to do something very, very simple: measure the width of a span in Javascript code embedded in a Content Editor web part (WSS 3.0). The code looks like this:
function elementWidth ( element ) {
var theElement = document.getElementById(element);
return theElement.offsetWidth;
}
Easy as it gets. Call it with the ID of my span and away we go. The code works on both IE7 and Firefox when embedded in a simple HTML page. And it works on Firefox when embedded in a Content Editor web part.
It does NOT work on IE7 when embedded in a Content Editor web part. theElement.offsetWidth returns zero.
This makes Absolutely No Sense At All. The DOM is the DOM, and IE7 clearly supports the offsetWidth property. But something in the way SharePoint is rendering the web page is interfering with the property.
Have you ever run into this problem? Any idea how I can work around it?
Thanks much for any help you might offer!
Dave Shaw
Hi Dave,
I was able to reproduce your bug. The same code that produced a "0" for offsetWidth in IE7 produced a "100" in FF. When I tested a simple .html file that I had on my hard drive I was also able to get a "100" value returned, but when I moved that code into a CEWP it returned a "0" so the problem is obviously unique to IE7 & SharePoint.
The closest I could come to a functioning work-around is by using the theElement.style.width or theElement.style.pixelWidth settings. Unfortunately both require the element to have a hard-coded width property so I doubt this would be very useful to you.
Sorry I couldn't be more help.
-Ben
Thanks, Ben, for looking at this for me. I did find a work-around. It turns out that if you define the span in the CEWP, IE will return a zero width. But if the span is defined elsewhere in the master page, IE does return a valid width.
Bizarre that the mere location of the span definition would affect IE's support of the DOM, but there it is. I'm a major fan of SharePoint, but sometimes it makes me crazy.
What I am doing is measuring a string in a particular face and size to determine whether it will fit in a fixed-size table cell without wrapping. If not, I can trim it character by character until it does fit, including a trailing ... I'm using a "ruler" span (hidden with an absolute position to stay clear of the rendered page) to measure the text.
I include some common javascript at the top of my master page, and I wrote a "ruler" span tag to the page from that code at page load time. My measurement code sets the font face and point size, sets innerHTML to the text I want to measure, and pulls offsetWidth. Works like a champ. Truly the long way home, though.
Thanks again, sir.
Dave
Post a Comment