Current location: Hot Scripts Forums » General Web Coding » JavaScript » [SOLVED] Stuck while expanding on Seth Duffey's 'Accessible Map'


[SOLVED] Stuck while expanding on Seth Duffey's 'Accessible Map'

Reply
  #1 (permalink)  
Old 07-03-08, 06:33 PM
marcy_sss marcy_sss is offline
New Member
 
Join Date: Jul 2008
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Question [SOLVED] Stuck while expanding on Seth Duffey's 'Accessible Map'

Hello all,

I'm new here but I also don't like to waste time. I am currently stuck on a Javascript problem that expands upon Seth Duffey's "A More Accessible Map" from a few years ago. I emailed him about it, but still couldn't come up with a solution as this pushes the limits of my JS knowledge.

Basically, I am using his map technique, which uses a Javascript object literal (mapMaker). If you are not familiar with it, it converts a definition list <DL> into points on a map, placing each one with CSS. They are "hidden" until you roll over them. The benefit is that the map image and data are totally separate, and you can add/delete/edit points easily. It is meant to be simple to fit in with the design/project scope we sold to the client.

Here is where I am expanding on it: I have a list of the places on the map elsewhere on the page (in a table dynamically populated with JS, so I only have to edit the <DL>). When an item in the list outside of the map is hovered, I want the corresponding point on the map to become active - mapMaker.showTooltip(). Just look at the page and you will see what I mean.

What I need to do is call mapMaker.showTooltip() or mapMaker.addEvt() on mouseover of an item outside of the map (which already has a unique ID based on the corresponding item inside of the map). I am having a hell of a time trying to make use of any of the functions in the script. None of the properties seem to be available when I need them, including 'currentLocation'. Any idea how to call a function that isn't really available? Do I have to rewrite the script to be a class instead of an object literal?

I would really appreciate some help on this one - I find it hard to believe that no one has ever wanted to solve this same problem in the two years since the article was published.

Here is the page where I am using it:

http://client.deicreative.com/row5/n...d.php?page=map

Here is some code I wrote:

Code:
// This function dynamically populates a table outside of the map:
function mapList(id) {
	var dlID = document.getElementById(id).innerHTML;
	var tdID = id + 'tableitem';
	document.write('<td id="'+tdID+'" class="mapList" onmouseover="" onmouseout="">' + dlID + '</td>');
}
Here is a copy of mapevents.js, taken from A List Apart:

Code:
var mapMaker = {
	offsetX: -25, // tooltip X offset
	offsetY: 7,  // tooltip Y offset
	element: false,
	DLs:     false,
	DTs:     false,
	on:      false,
	/* constructor - sets events */
	init: function(){
		var i=0;
		var ii=0;
		var currentLocation = 0;
		mapMaker.DLs = document.getElementsByTagName('dl');
		mapMaker.DTs = document.getElementsByTagName('dt');
		// only loop thru items once
		if( mapMaker.on == false ){
			//loop through each DL on page
			while (mapMaker.DLs.length > i) {
				//only affect DLs with a class of 'map'
				if (mapMaker.DLs[i].className == 'map' ){
					//change map DL class, this way map is text only without javascript enabled
					mapMaker.DLs[i].className = 'map on';
					//strip whitespace
					mapMaker.stripWhitespace(mapMaker.DLs[i]);
					mapMaker.stripWhitespace(mapMaker.DTs[i]);
					// loop thru all DT elements
					while (mapMaker.DTs.length > ii){
						//current Location
						currentLocation = mapMaker.DTs[ii].firstChild;
						
						// add events to links
						mapMaker.addEvt(currentLocation,'mouseover',mapMaker.showTooltip);//displays tooltip on mouse over
						mapMaker.addEvt(currentLocation,'mouseout',mapMaker.hideTooltip);//hide tooltip on mouse out
						mapMaker.addEvt(currentLocation,'focus',mapMaker.showTooltip);//display tooltip on focus, for added keyboard accessibility
						mapMaker.addEvt(currentLocation,'blur',mapMaker.hideTooltip);//hide tooltip on focus, for added keyboard accessibility
						ii++;
					};
					ii=0;
				};
				i++;
			};
			mapMaker.on = true;

		};
	},
	
	/* SHOW TOOLTIP */
	showTooltip: function() {
		var evt = this;
		var i = 0;
	
		//Find DD to display - based on currently hovered anchor move to parent DT then next sibling DD
		var objid = evt.parentNode.nextSibling;
		mapMaker.element = objid;//set for the hideTooltip
		
		//get width and height of background map
		var mapWidth  = objid.parentNode.offsetWidth;
		var mapHeight = objid.parentNode.offsetHeight;
		//get width and height of the DD
		var toopTipWidth = objid.offsetWidth;
		var toopTipHeight = objid.offsetHeight;
		//figure out where tooltip should be places based on point location
		var newX = evt.offsetLeft + mapMaker.offsetX;
		var newY = evt.offsetTop + mapMaker.offsetY;
		//check if tooltip fits map width 
		if ((newX + toopTipWidth) > mapWidth) {
			objid.style.left = newX-toopTipWidth-24 + 'px';
		} else {
			objid.style.left = newX + 'px';
		};
		//check if tooltip fits map height 
		if ((newY + toopTipHeight) > mapHeight) {
			objid.style.top = newY-toopTipHeight-14 + 'px';
		} else {
			objid.style.top = newY + 'px';
		};
	},
	/* HIDE TOOLTIP */
	hideTooltip: function() {
		mapMaker.element.style.left = '-9999px';
	},
	addEvt: function(element, type, handler) {
		// assign each event handler a unique ID
		if (!handler.$$guid) handler.$$guid = mapMaker.addEvt.guid++;
		// create a hash table of event types for the element
		if (!element.events) element.events = {};
		// create a hash table of event handlers for each element/event pair
		var handlers = element.events[type];
		if (!handlers) {
			handlers = element.events[type] = {};
			// store the existing event handler (if there is one)
			if (element["on" + type]) {
				handlers[0] = element["on" + type];
			};
		};
		// store the event handler in the hash table
		handlers[handler.$$guid] = handler;
		// assign a global event handler to do all the work
		element["on" + type] = mapMaker.handleEvent;
		
	},
	handleEvent: function(event) {
		var returnValue = true;
		// grab the event object (IE uses a global event object)
		event = event || mapMaker.fixEvent(window.event);
		// get a reference to the hash table of event handlers
		var handlers = this.events[event.type];
		// execute each event handler
		for (var i in handlers) {
			this.$$handleEvent = handlers[i];
			if (this.$$handleEvent(event) === false) {
				returnValue = false;
			};
		};
		return returnValue;
	},
	fixEvent: function(event) {
		// add W3C standard event methods
		event.preventDefault = mapMaker.fixEvent.preventDefault;
		event.stopPropagation = mapMaker.fixEvent.stopPropagation;
		return event;
	},
	stripWhitespace: function( el ){
		for(var i = 0; i < el.childNodes.length; i++){
			var node = el.childNodes[i];
			if( node.nodeType == 3 && !/\S/.test(node.nodeValue)) {
				node.parentNode.removeChild(node);
			};
		};
	}
};
mapMaker.fixEvent.preventDefault = function() {this.returnValue = false;};
mapMaker.fixEvent.stopPropagation = function() {this.cancelBubble = true;};
mapMaker.addEvt.guid = 1;


/* LOAD SCRIPT */
	/* for Mozilla */
		if (document.addEventListener) {
			document.addEventListener("DOMContentLoaded", mapMaker.init, null);
		};
		
	/* for Internet Explorer */
		/*@cc_on @*/
		/*@if (@_win32)
			document.write("<script defer src=ie_onload.js><"+"/script>");
		/*@end @*/
		
	/* for other browsers */
		mapMaker.addEvt( window, 'load', mapMaker.init);
I look forward to hearing SOMETHING! Thanks for any time you care to contribute!
Cheers,
Marcy
Reply With Quote
  #2 (permalink)  
Old 07-03-08, 09:18 PM
End User's Avatar
End User End User is offline
Level II Curmudgeon
 
Join Date: Dec 2004
Posts: 3,027
Thanks: 14
Thanked 35 Times in 33 Posts
Wow....I don't have a solution, but I certainly admire the problem.
__________________
I don't live on the edge, but sometimes I go there to visit.
-------------------------------------------------------------------------
Sanitize Your Data | Oracle Date & Substring Functions | Code Snippet Library | [url=http://www.codmb.com/Call Of Duty[/url]
Reply With Quote
  #3 (permalink)  
Old 07-04-08, 05:36 PM
Vicious's Avatar
Vicious Vicious is offline
Community VIP
 
Join Date: Jan 2007
Location: Belgium
Posts: 584
Thanks: 0
Thanked 0 Times in 0 Posts
snippet from your code:
HTML Code:
    <td onmouseout="" onmouseover="mapListActive(location08)" class="mapList" id="location08tableitem">Victrola</td>

I haven't checked if the function mapListActive is correct, but in any case, you are not calling it correctly. MapListActive expects 1 parameter, a string. You are not giving it a string, but a variable name. You should use single quotes, like this;

javascript Code:
  1. <td onmouseout="" onmouseover="mapListActive('location08')" class="mapList" id="location08tableitem">Victrola</td>

The reason you have to use single quotes, is because the string represents the ID of the element you want to show.

I only made a quick glance at your example, and this error was apparent to me. Maybe if you solve this, all the rest will work. If not...... then we'll have to dig deeper : )
__________________
Jack Bauer makes Chuck Norris cry
Reply With Quote
  #4 (permalink)  
Old 07-07-08, 12:35 PM
marcy_sss marcy_sss is offline
New Member
 
Join Date: Jul 2008
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Well that is really just a placeholder function, not really in use yet. I am trying to decide whether to move everything into the main .js file as one of my friends suggested, I'm thinking that might help with issues of scope.

When I get further along I will definitely post my progress.
Reply With Quote
  #5 (permalink)  
Old 07-10-08, 07:59 PM
marcy_sss marcy_sss is offline
New Member
 
Join Date: Jul 2008
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
After rewriting the functions myself, they are much simpler though not as sophisticated as the original.... I did away with the object literal in order to accomplish the task, because after a while it really just had to get done.

Here are the functions I wrote. I did away with the definition list and instead put all the data into divs.

Code:
// JavaScript Document - Written by Marcy Sutton

function showTooltip(id) {
	document.getElementById(id).style.visibility='visible';	
	var a = document.getElementsByTagName('a');
	
	for (i=0; i<=17; i++) {
		var pid = document.getElementById(id+'p');
		if (a[i].className == 'location') {
			//alert(id);
			pid.style.backgroundImage="url(images/point-hover.png)";
		} else {
			//alert('ELSE on');	
		}
	};
}
function hideTooltip(id) {
	document.getElementById(id).style.visibility='hidden';
	var a = document.getElementsByTagName('a');
	
	for (i=0; i<=17; i++) {
		var pid = document.getElementById(id+'p');
		if (a[i].className == 'location') {
			//alert(id);
			pid.style.backgroundImage="url(images/point.png)";
		} else {
			//alert('ELSE on');	
		}
	};
}

function mapList(id) {
	//var pID = id + 'p';
	//var id = document.getElementById(id);
	var dlID = document.getElementById(id+'p').innerHTML;
	document.write('<td onmouseover="showTooltip(\''+id+'\');" onmouseout="hideTooltip(\''+id+'\');" class="mapList">' + dlID + '</td>');
}
Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Forum Jump


All times are GMT -5. The time now is 11:39 PM.
vBulletin® Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.