<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>OneMarco</title>
	<atom:link href="http://onemarco.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://onemarco.com</link>
	<description>Web development in the age of Web 2.0</description>
	<lastBuildDate>Fri, 18 Feb 2011 06:03:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Improving the Date Picker User Interface (UI)</title>
		<link>http://onemarco.com/2008/12/13/improving-the-date-picker-user-interface-ui/</link>
		<comments>http://onemarco.com/2008/12/13/improving-the-date-picker-user-interface-ui/#comments</comments>
		<pubDate>Sat, 13 Dec 2008 22:30:20 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[User Interface]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://onemarco.com/?p=47</guid>
		<description><![CDATA[Date pickers have become ubiquitous user interface elements in online forms. If you do not know what date pickers are, they are those interactive calendars that pop up to assist you when selecting a date. They are not useful in &#8230; <a href="http://onemarco.com/2008/12/13/improving-the-date-picker-user-interface-ui/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Date pickers have become ubiquitous user interface elements in online forms. If you do not know what date pickers are, they are those interactive calendars that pop up to assist you when selecting a date. They are not useful in all situations, like when you already know the date you are going to enter.  In this case you can just type the date in, as this tends to be quicker and simpler than using a date picker.  However, a date picker can be very useful when you are trying to figure out the date of the Monday before Christmas, the date of next Thursday, or the date of the first Wednesday in May.  This is because a date picker allows you to visualize the relationship between a date, January 4th, 2009, and a weekday, Sunday.  Yet, the common date picker does have its fair share of drawbacks.</p>
<h3>What the Date Picker Lacks</h3>
<div style="width: 182px;" class="afterHeading figure figureRight"><img src="/examples/DatePicker/generic_datepicker.png" width="182" height="133" alt="A comon date picker user interface with single arrows and double arrows for month and year navigation" /><p>Figure 1. A common date picker user interface.</p></div>	
<p>The common date picker is lacking in speed and simplicity when compared to typing a date into a text field.  Typing a date into a text field is a relatively quick and easy process, usually ten keystrokes is enough to enter a date formatted as mm/dd/yyyy.  What makes this task even quicker is that you only need eleven keys to enter any date (0-9 and /); using the number pad makes this even easier. On the other hand, selecting a date using a date picker can be a slower and more complex process. If you are selecting a date six months from the month initially displayed in the date picker, then you have to change the month six times before you are shown the appropriate month.  The same or a worse problem arises when navigating through years.  If the date picker allows navigation by year and month it is only slightly more problematic than only changing the month.  On the other hand if the date picker only allows navigation by month, changing the year takes eleven more clicks. It also does not help that most date pickers use a cryptic system of symbols to represent moving forward and back one month or one year.  These symbols are the single and double angle quotation marks &ndash; or something similar &ndash; pointed either right or left. The single angle quotes navigate through the months while the double angle quotes navigate through the years.  This is not the most intuitive way to represent month and year navigation.  All of these problems contribute to the relative slowness and complexity of common date pickers.</p>
<span id="more-47"></span>
<p>Speed and simplicity are important when filling out forms because users do not usually visit websites for this purpose. Users visit websites to obtain some kind of valuable information.  Forms are just there for users to specify the type of information they need. In other words, forms are means to and end and should not hinder or irritate a user on their path to that end. The simple reason for this is that making users happy keeps them coming back to the site. So it should be our goal to make entering dates into a form as easy (quick and simple) as possible.</p>
<h3>A Proposed Solution</h3>
<div style="width: 182px;" class="afterHeading figure figureRight"><img src="/examples/DatePicker/datepicker_step_1.png" width="182" height="154" alt="" /><p>Figure 2. A date picker with separate month and year displays.</p></div>
<p>The goal of the proposed solution is to simplify the date picker and make it quicker to use.  We start by separating the month and year in order to reduce the complexity introduced by the symbols shown in Figure 1.  It becomes easier to connect the meaning of the symbols because they are now grouped with their corresponding item, month and year. We can also use the same symbols to represent navigating forward and backward by month or year.  This reduces the number of symbols for which users have to interpret the meaning.</p>
<div style="width:212px;" class="figure figureLeft"><img src="/examples/DatePicker/datepicker_final.png" width="212" height="185" alt="" /><p>Figure 3. A date picker with expanded month and year interfaces.</p></div>
<p>The next step is to expand the months so that any month is selectable with one click, as opposed to 1-11 clicks.  This also allows us to remove the navigation symbols as they are no longer necessary.  Reducing clicks increases speed and removing the navigation symbols reduces complexity because the user no longer needs to decipher the meaning of the symbols or their connection to any item.  It is possible to expand the months because the number of months is finite and relatively small.  Twelve months can easily fit into two rows when they are abbreviated.</p>
<p>Applying this same solution to the year navigation is more difficult because the range of input for years is application-specific. Displaying 60 years in the manner the months have been displayed in Figure 3 is impractical.  It would make the date picker too big and would required more effort by the user to find the appropriate year.  In this situation a drop down list would be a better method for selecting a year &ndash; better than displaying all sixty years <em>and</em> better then navigating one year at a time.  As you can see, I have used an example where the range of input is restricted to five years.  In this case it <em>is</em> practical to display all the years because they fit in one row.  This has two obvious advantages over a dropdown list.  First, it requires fewer clicks and mouse movements to select the appropriate year.  Second, the valid range of years is immediately visible; whereas in a dropdown you must expand the list before you are shown that range. While this technique works for small ranges of years, at a certain number a decision has to be made between displaying all of the selectable years and using a dropdown list &ndash; or a similar UI element.  That decision is application-specific and ultimately left up to the UI designer. I cannot suggest where that line should be drawn, because I donâ€™t know myself.  That is a question that may have to be &ndash; or has already been &ndash; answered by research.</p>
<h3>The Date Picker Working Sample</h3>
<p>You can <a href="/examples/DatePicker">take a look at a working example of my date picker</a>. The example code authored by me is public domain, so use it for anything without any restrictions.  You can easily identify the code I have authored; as it has my name, email, and URL along with a statement declaring it public domain. If you use the code in your own work, I would appreciate my name and URL be included.</p>
<p>Get the <a href="/examples/DatePicker/DatePicker.js">DatePicker.js</a> File. The DatePicker class depends on <a href="http://jquery.com">jQuery</a>.</p>
<p>Get the <a href="/examples/DatePicker/datepicker.css">datepicker.css</a> file and <a href="/examples/DatePicker/datepicker.ie.css">datepicker.ie.css</a> file.</p>]]></content:encoded>
			<wfw:commentRss>http://onemarco.com/2008/12/13/improving-the-date-picker-user-interface-ui/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript Callbacks and Binding (and Callback Arguments and References)</title>
		<link>http://onemarco.com/2008/11/12/callbacks-and-binding-and-callback-arguments-and-references/</link>
		<comments>http://onemarco.com/2008/11/12/callbacks-and-binding-and-callback-arguments-and-references/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 03:03:51 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[binding]]></category>
		<category><![CDATA[callbacks]]></category>

		<guid isPermaLink="false">http://onemarco.com/?p=9</guid>
		<description><![CDATA[Callback functions are used in JavaScript (JS) extensively. They are required for AJAX/XHR, event handling, and in popular JS libraries. However, passing around functions as arguments can cause headaches, especially for beginner JS programmers. Problems with binding/this One of the &#8230; <a href="http://onemarco.com/2008/11/12/callbacks-and-binding-and-callback-arguments-and-references/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>
	Callback functions are used in JavaScript (JS) extensively. They are required 
	for AJAX/XHR, event handling, and in popular JS libraries. However, passing around
	functions as arguments can cause headaches, especially for beginner JS programmers.
</p>
<h3>Problems with binding/<code>this</code></h3>
One of the biggest problems with passing functions as callbacks is <code>this</code> and what it
refers to. You usually run into the problem when passing an object&#8217;s method as a
callback function.  Another way to encounter this problem is by passing as a callback a function that
expects to be bound to a certain type of object.  You&#8217;ll usually get an error stating that
<code>this.someProperty</code> is undefined.  You can resolve this with 
<code>Function.apply</code>, <code>Function.call</code> or a closure. For example:
<code class="brush: js">//using Function.call
takesCallback(
	function callbackProxy(argOne, argTwo){
		//assume myFunction is already defined
		myFunction.call(myObject, argOne, argTwo);
	}
);

//or using Function.apply
takesCallback(
	function callbackProxy(argOne, argTwo){
		//assume myFunction is already defined
		myFunction.apply(myObject, [argOne, argTwo]);
	}
);

//or using a closure
takesCallback(
	function callbackProxy(argOne, argTwo){
		//assume myObject is already defined
		myObject.myMethod(argOne, argTwo);
	}
);</code>
<p>In the code above, the function <code>takesCallback</code> takes a callback function as its
only argument and calls that function at a later time with two arguments.  The function, <code>callbackProxy</code> is 
a wrapper function that takes the arguments and passes them to the real callback, while ensuring
that the function is bound to the correct object.</p>
<span id="more-9"></span>
<h3>Problems with Arguments</h3>
Another problem with callback functions is that the arguments
passed to the callback function are often out of your
control. Sometimes you need more information than what is
passed to your callback function by the caller. This, too can be solved with a closure. For example:
<code class="brush: js">function main(){
	var myVarOne = "one";
	takesCallback(
		function callbackProxy(argOne){
			//assume myFunction is alread defined
			myFunction(argOne, myVarOne);
		}
	);
}</code>
<p>Again, the <code>callbackProxy</code> function takes care of calling the real callback with
the correct arguments.  In this case it appends myVarOne to the list of arguments.</p>
<h3>Problems with references</h3>
<p>The issue with references does not come up often. But when it does, it can be difficult to 
solve. When you use a callback proxy to pass additional arguments to the real callback, you
may find that the values of those arguments have changed between the time the callback proxy
was created and when it was called.  This will happen if you are using a loop counter as
an argument for your callback or if you change the value of the variable for some other reason.
For example:</p>
<code class="brush: js">//looping
for(var i = 0; i &lt; 5; i++){
	takesCallback(function callbackProxy(){
		//assume myFunction is already defined
		myFunction(i);
	})
}

//general example
var x = 2;
takesCallback(function callbackProxy()){
	myFunction(x);
}
x = x * 2;</code>
<p>In both of the cases above, when <code>myFunction</code> is called, the value of the first
argument will be 4.  This is true for all iterations of the loop. It happens because the references to <code>i</code> and <code>x</code>
are never broken.  In the general example, you can eliminate this problem by using another variable
in place of <code>x</code>. In the looping example, the fix is more complicated:</p>
<code class="brush: js">for(var i = 0; i &lt; 5; i++){
	takesCallback(
		(function breakReference(arg){
			return function callbackProxy(){
				myFunction(arg);
			};
		})(i)
	);
}</code>
<p>This code creates the callback proxy with the <code>breakReference</code> function.  The
<code>breakReference</code> function is executed immediately and returns the callback proxy.
The reference to <code>i</code> is broken because <code>i</code> is passed as an argument.
In JS, primitives passed as arguments are passed by value and objects passed as arguments are passed by reference.
So, if you are trying to break a reference to an object, this method will not work.</p>
<h3>A better solution</h3>
<p>You probably don&#8217;t want to remember all these tricks or write these routines over and over. Personally, I dislike
closures because they can become nested several levels deep, making debugging and reading your code difficult.  If you&#8217;ve ever written a web application,
you know the code can quickly become a mess.  Closures can compound that mess, so I try to stay away from them or hide them in other
functions.  So what can you do? You can write a function to take care of these issues for you and use it as often as you need or you can use
a binding function from your favorite JS library. Or, you can use the one I already wrote (if you don&#8217;t use a library and don&#8217;t want
to write your own).</p>
<code class="brush: js">/**
 * @param {Function} func the callback function
 * @param {Object} opts an object literal with the following
 * properties (all optional):
 * scope: the object to bind the function to (what the "this" keyword will refer to)
 * args: an array of arguments to pass to the function when it is called, these will be
 * appended after any arguments passed by the caller
 * suppressArgs: boolean, whether to supress the arguments passed
 * by the caller.  This default is false.
 */
function callback(func,opts){	
	var cb = function(){
		var args = opts.args ? opts.args : [];
		var scope = opts.scope ? opts.scope : this;
		var fargs = opts.supressArgs === true ?
			[] : toArray(arguments);
		func.apply(scope,fargs.concat(args));
	}
	return cb;
}

/* A utility function for callback() */
function toArray(arrayLike){
	var arr = [];
	for(var i = 0; i &lt; arrayLike.length; i++){
		arr.push(arrayLike[i]);
	}
	return arr;
}</code>
<p>The <code>callback</code> function is fairly straight forward. It takes a function and
and an object literal and returns a callback function that takes care of the 
problems discussed earlier.  The properties of the object literal are all optional and will
default to what is normal behavior for callbacks. The object literal defines the scope and extra arguments.  It can
also supress the arguments provided by the caller (the extra arguments are still used). This is useful when you don&#8217;t need the
arguments provided by the caller or when you are using a function that isn&#8217;t always called as a callback. Here is 
an example of how to use it.</p>
<code class="brush: js">takesCallback(callback(myFunction,{scope:myObject,args:[myArgOne,myArgTwo],suppressArgs:true}));

//or
takesCallback(myObject.myMethod,{scope:myObject,args:[myArgOne]});</code>
<p>As you can see, using the <code>callback</code> function is much easier than using the tricks shown above.
If you are using callbacks often, as is the case with event handling and AJAX, this is very handy tool.  You can
create your objects, methods, and functions once and quite easily reuse them.</p>]]></content:encoded>
			<wfw:commentRss>http://onemarco.com/2008/11/12/callbacks-and-binding-and-callback-arguments-and-references/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Startup Weekend Houston</title>
		<link>http://onemarco.com/2007/10/01/startup-weekend-houston/</link>
		<comments>http://onemarco.com/2007/10/01/startup-weekend-houston/#comments</comments>
		<pubDate>Mon, 01 Oct 2007 12:41:56 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Startup Weekend Houston]]></category>
		<category><![CDATA[Startup Weekend]]></category>
		<category><![CDATA[TipDish]]></category>

		<guid isPermaLink="false">http://onemarco.com/2007/10/01/startup-weekend-houston/</guid>
		<description><![CDATA[This past weekend I participated in Startup Weekend Houston. For some reason I ended up in the UI design group, even though my specialty is front-end web-dev. I had a blast though, working with the UI team, Matt Alberty, Marcus &#8230; <a href="http://onemarco.com/2007/10/01/startup-weekend-houston/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[This past weekend I participated in <a href="http://houston.startupweekend.com/">Startup Weekend Houston</a>.  For some reason I ended up in the UI design group, even though my specialty is front-end web-dev.  I had a blast though, working with the UI team, <a href="http://mediamatt.com">Matt Alberty</a>, <a href="http://marcus.mateus.com">Marcus Mateus</a>, and Ramesh Bhaskar.  Two and a half days went by incredibly fast, and in the end we ran short on time and only partially launched.  But, this project will keep moving forward.  We created <a href="http://tipdish.com">TipDish</a>, a news wire for social media.  If you blog/dish, you can <a href="http://tipdish.com/disher/">register</a> at the site to receive tips pertinent to the subject(s) you blog about.  We expect a full launch sometime this month.]]></content:encoded>
			<wfw:commentRss>http://onemarco.com/2007/10/01/startup-weekend-houston/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Google Maps Tooltip Gets a Shadow (and HTML Support)</title>
		<link>http://onemarco.com/2007/08/06/the-tooltip-gets-a-shadow-and-dom-node-support/</link>
		<comments>http://onemarco.com/2007/08/06/the-tooltip-gets-a-shadow-and-dom-node-support/#comments</comments>
		<pubDate>Tue, 07 Aug 2007 02:11:20 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Google Maps API]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[tooltips]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://onemarco.com/2007/08/06/the-tooltip-gets-a-shadow-and-dom-node-support/</guid>
		<description><![CDATA[In the spirit of consistency, I decided to add a shadow to the tooltips (View the example). They just didn&#8217;t blend in with the rest of the Google Maps overlays. So I set out to replicate the &#8220;standard&#8221; Google Maps &#8230; <a href="http://onemarco.com/2007/08/06/the-tooltip-gets-a-shadow-and-dom-node-support/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In the spirit of consistency, I decided to add a shadow to the tooltips (<a href="/examples/Tooltip_v2/">View the example</a>).  They just didn&#8217;t blend in with the rest of the Google Maps overlays.  So I set out to replicate the &#8220;standard&#8221; Google Maps shadows.</p>
<h3>Replicating the Shadow</h3>
Through a mix of reasoning, instinctive guessing, and trial and error, I have devised a technique to replicate the shadows using Adobe Photoshop.  It&#8217;s a fairly simple process and the steps are outlined below.
<ol>
	<li>Make a copy of the overlay&#8217;s layers and merge and rasterize the copies if needed</li>
	<li>Make the copy all black (I use a gradient map and set both ends to black)</li>
	<li>Perform a Free Transform and set the Height/Vertical Scale to 50% and the Horizontal Skew to -45°
<img class="exampleSettings" src="/examples/Tooltip_v2/google_shadow_transform.jpg" alt="Photoshop Free Transform Settings" /></li>
	<li>Apply the Gaussian Blur filter (I set it to .5 pixels for small images and 2 to 3 pixels for large ones)</li>
	<li>Set the Opacity to 45%</li>
	<li>Save the shadow layer only as a PNG</li>
</ol>
<span id="more-7"></span>
<h3>Drawing a Variable Size Shadow on the Map</h3>
<p>After figuring out how to replicate the shadow, I moved on to drawing it on the map.  The first step to drawing the shadow is getting its size and location.  From replicating the shadow we know that the height is 50% (plus padding for the Gaussian blur).  The width of the shadow is the width of the tooltip, plus half the height of the tooltip (and again, the padding).  Half the height of the tooltip is added to the width to take into account the offset of the shadow&#8217;s top, right corner caused by the skew.  Since the skew is 45 degrees, the offset is a one to one ratio with the height of the shadow.  The position of the tooltip&#8217;s shadow is relative to the marker&#8217;s shadow.  So I apply the same principles to the marker&#8217;s dimensions in order to calculate the position of the tooltip&#8217;s shadow.</p>

<p><img class="sample" src="/examples/Tooltip_v2/tooltip_shadow_quadrants.jpg" alt="tooltip shadow quadrants" />Because the size of the tooltip is not fixed, the shadow needs to be able to grow vertically and horizontally.  I accomplish this by dividing the shadow into four quadrants.  Each quadrant contains the same shadow image, positioned to display its respective corner.  The image&#8217;s positions in the first and third quadrants are straight forward.  The image is positioned so the top and right edges of the image line up with the top and right edges of the first quadrant. The bottom and left edges of the image line up with the bottom and left edges of the third quadrant. The positioning of the image in the second and fourth quadrants requires some simple calculations.  The image in the second quadrant is placed so the top edge of the image lines up with the top edge of the quadrant. The left edge of the image is offset from the quadrant&#8217;s left edge.  The image in the fourth quadrant is symmetrically opposite from the second, bottom edge of image to bottom edge of quadrant and right edge of image offset from the right edge of quadrant.  See the <a href="/examples/Tooltip_v2/Tooltip.v2.js">source code</a>, the <code>Tooltip.prototype.redraw</code> method, for the calculations of the offset.</p>

<p>The code below is a sample of the xhtml generated by the <code>Tooltip</code> object to create the shadow.  The parent div is the container for the entire shadow, it is outlined in black in the image above.  The child divs represent the quadrants of the shadow.  Each quadrant contains a reference to the same shadow image and the image is positioned relatively to the quadrant.</p>

<code class="brush: html">&lt;div style="position: absolute; visibility: visible; left: 300px; top: 197px; width: 226px; height: 32px;"&gt;

&lt;div style="overflow: hidden; position: absolute; right: 0px; top: 0px; width: 113px; height: 16px;"&gt;
&lt;img src="/examples/Tooltip_v2/tooltip_shadow.png" style="position: absolute; top: 0px; right: 0px;"/&gt;
&lt;/div&gt;

&lt;div style="overflow: hidden; position: absolute; left: 0px; top: 0px; width: 113px; height: 16px;"&gt;
&lt;img src="/examples/Tooltip_v2/tooltip_shadow.png" style="position: absolute; top: 0px; left: -128px;"/&gt;
&lt;/div&gt;

&lt;div style="overflow: hidden; position: absolute; left: 0px; bottom: 0px; width: 113px; height: 16px;"&gt;
&lt;img src="/examples/Tooltip_v2/tooltip_shadow.png" style="position: absolute; bottom: 0px; left: 0px;"/&gt;
&lt;/div&gt;

&lt;div style="overflow: hidden; position: absolute; right: 0px; bottom: 0px; width: 113px; height: 16px;"&gt;
&lt;img src="/examples/Tooltip_v2/tooltip_shadow.png" style="position: absolute; bottom: 0px; right: -128px;"/&gt;
&lt;/div&gt;

&lt;/div&gt;
</code>
<h3>HTML Support</h3>
<p>The tooltip can now take an HTML Element for its content. To do so, just create an element and pass it to the tooltip&#8217;s constructor. This technique is illustrated below.</p>
<code class="brush: js">//create the marker
var myMarker = new GMarker(new GLatLng(lat,lng),{icon:icon});

//create the tooltip content
var myElement = document.createElement('p');
myElement.appendChild(document.createTextNode("Some Text..."));

//create the tooltip with the marker and content
var myTooltip = new Tooltip(myMarker, myContent, 0);
</code>]]></content:encoded>
			<wfw:commentRss>http://onemarco.com/2007/08/06/the-tooltip-gets-a-shadow-and-dom-node-support/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Improved CSS Styling for Visited Links</title>
		<link>http://onemarco.com/2007/06/06/better-visited-links/</link>
		<comments>http://onemarco.com/2007/06/06/better-visited-links/#comments</comments>
		<pubDate>Thu, 07 Jun 2007 03:06:06 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://onemarco.com/2007/06/06/better-visited-links/</guid>
		<description><![CDATA[I was recently checking my site traffic reports to see where my visitors were coming from and I found a mind-blowing (at least for me) CSS technique for visited links. Eva-Lotta Lam uses a check mark background image for visited &#8230; <a href="http://onemarco.com/2007/06/06/better-visited-links/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was recently checking my site traffic reports to see where my visitors were coming from and I found a mind-blowing (at least for me) CSS technique for visited links.  <a href="http://www.evalotta.net/">Eva-Lotta Lam</a> uses a check mark background image for visited links rather than simply changing the text color.  You might not think that this is mind-blowing, but consider that using background images to attach information to links has been around for awhile now, i.e. external link icons.</p>
<p>
Why has this technique not been applied broadly to visited links as well? It makes so much more sense than changing the color.  You don&#8217;t have to think about which color corresponds to a visited link as opposed to a non-visited link.  The color swapping doesn&#8217;t really help across different websites because there is no standard convention for which colors to use.  The exception may be blue for non-visited purple for visited, but these are antiquated and clash with most websites&#8217; color schemes.  Using a check mark doesn&#8217;t require that users remember a link had a different color when or if they re-encounter it after they have visited the it the first time.  Users do not have to compare one link&#8217;s color to another and try to remember which of those links has been visited and which has not.  The check mark conveys the same meaning without requiring the user to think as much; it is a much better solution.</p>
<p>Evalotta pointed out that <a href="http://boagworld.com/">Paul Boag</a> also uses this technique.  If you know of any others, let me know.</p>]]></content:encoded>
			<wfw:commentRss>http://onemarco.com/2007/06/06/better-visited-links/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Batch Geocoding with the Google Maps API</title>
		<link>http://onemarco.com/2007/06/03/geocoding-with-the-google-maps-api/</link>
		<comments>http://onemarco.com/2007/06/03/geocoding-with-the-google-maps-api/#comments</comments>
		<pubDate>Sun, 03 Jun 2007 23:52:45 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Google Maps API]]></category>
		<category><![CDATA[Geocoding]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://onemarco.com/2007/06/03/geocoding-with-the-google-maps-api/</guid>
		<description><![CDATA[I&#8217;ve been working more and more with the Google Maps API recently. And one thing strikes me as odd; it&#8217;s difficult to find examples of how to retrieve geocodes for addresses. If you&#8217;re going to implement the API in a &#8230; <a href="http://onemarco.com/2007/06/03/geocoding-with-the-google-maps-api/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img src="/examples/Geocoder/sample.jpg" alt="tooltip sample" class="sample" />I&#8217;ve been working more and more with the Google Maps API recently.  And one thing strikes me as odd; it&#8217;s difficult to find examples of how to retrieve geocodes for addresses.  If you&#8217;re going to implement the API in a website, you usually have to take multiple addresses and convert them to geocodes.  But how do you do this?</p>
<p>Enter <a href="/examples/Geocoder">Geocoder</a>. You may be asking yourself, &#8220;Who&#8217;s Geocoder?&#8221;  No, no my friend; Geocoder is not a who, it&#8217;s a what.  It is a little web app that will retrieve the coordinates of any address (known to Google Maps), using the Google Maps API. The beautiful thing about Geocoder is that it allows you to perform batch retrievals using any character(s) to separate the records.  Geocoder also gives you the ability to drop a draggable marker onto the map and it will tell you the coordinates of the location you move it to.  This is extremely helpful for locations without addresses.  And best of all, Geocoder is completely free and onemarco.com-independent.  &#8220;How,&#8221; you ask?  Simple, you can download Geocoder and insert your Google Maps API key in the index file. It will run on any web server as long as you have an API key.  I&#8217;ve even zipped it up into a convenient archive so that you can download all the files with one click.</p>
<p>Geocoder is free to use for any reason without any restrictions. Just credit me if you redistribute it.</p>
<div><a href="/examples/Geocoder">View</a> Geocoder in action.<br/><a href="/examples/Geocoder/Geocoder.zip">Download</a> Geocoder.zip.</div>
<p>P.S. I would like to thank Simon Reynolds for designing my masthead.  You can check out his blog at <a href="http://www.sr28.com/">SR28.com</a> and his artwork at <a href="http://www.4storystudio.com/">4StoryStudio.com</a>. His blog is designed beautifully.</p>]]></content:encoded>
			<wfw:commentRss>http://onemarco.com/2007/06/03/geocoding-with-the-google-maps-api/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Custom Tooltips for the Google Maps API</title>
		<link>http://onemarco.com/2007/05/16/custom-tooltips-for-google-maps/</link>
		<comments>http://onemarco.com/2007/05/16/custom-tooltips-for-google-maps/#comments</comments>
		<pubDate>Wed, 16 May 2007 14:19:04 +0000</pubDate>
		<dc:creator>Marco</dc:creator>
				<category><![CDATA[Google Maps API]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[tooltips]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://onemarco.com/2007/05/16/custom-tooltips-for-google-maps/</guid>
		<description><![CDATA[Welcome to my JavaScript blog, onemarco.com, or as I like to call it, Blog de Alionso. I&#8217;ve been developing with JavaScript for about six months now and I&#8217;ve learned so much from others&#8217; blogs. I&#8217;ll be sharing some of the &#8230; <a href="http://onemarco.com/2007/05/16/custom-tooltips-for-google-maps/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Welcome to my JavaScript blog, onemarco.com, or as I like to call it, Blog de Alionso. I&#8217;ve been developing with JavaScript for about six months now and I&#8217;ve learned so much from others&#8217; blogs. I&#8217;ll be sharing some of the scripts I&#8217;ve developed recently, in the hopes that my experience and knowledge will help others.</p>
<h3>What?</h3>
<img src="/examples/Tooltip/sample.jpg" alt="tooltip sample" class="sample" />
<p>Today I present the <code>Tooltip</code> object for the Google Maps API. It is used to add quickly-appearing, easy-to-style (via CSS) tooltips to Google Maps&#8217; markers.  This is in contrast to the built-in tooltips of versions 2.5 and higher, which appear after a short delay and cannot be styled.  You can view <del datetime="2007-08-08T12:56:38+00:00">an <a href="/examples/Tooltip" target="_blank">example</a></del> the <a href="/examples/Tooltip_v2/">new example</a> of the tooltips in action which also includes a sidebar.</p>
<p>View the <code><a href="/examples/Tooltip/Tooltip.js">Tooltip</a></code> source code. The code is free to use for any reason without any restrictions. Just credit me if you redistribute it.</p>
<h3>Why?</h3>
<p>
I developed the tooltips for two reasons.  First, I find it difficult to figure out which marker a sidebar entry belongs to.  It is time consuming to look at the letter for the entry and find the matching letter on the map, especially when markers overlap and hide each other.  It is easier if the tooltip appears above the marker when I hover over the sidebar entry.  Secondly, sometimes I just want to quickly figure out what a certain marker on the map is without having to look for its corresponding letter in the sidebar. And having to click on the marker to pull up the location&#8217;s name is annoying, especially when it moves the center of the map.  It just seems natural to me that when you hover on a marker, the name of the location should appear.  Besides, it was a good exercise in extending the Google Maps API.</p>
<span id="more-3"></span>
<h3>How?</h3>
<p>
Adding tooltips to a Google Map, using the <code>Tooltip</code> object is easy.  I&#8217;ll explain the steps I use when implementing the tooltips.  The constructor for the tooltip takes three parameters: the marker, the text, and the padding between the tooltip and the marker.</p>
<code class="brush: js">var marker = new GMarker(new GLatLng(29.78933,-95.716748));
var tooltip = new Tooltip(marker,'HEB Grocery Store',4);
marker.tooltip = tooltip;
map.addOverlay(marker);
map.addOverlay(tooltip);
GEvent.addListener(marker,'mouseover',function(){
	this.tooltip.show();
});
GEvent.addListener(marker,'mouseout',function(){
	this.tooltip.hide();
});</code>
<p>After I&#8217;ve created the tooltip, I set it to the marker&#8217;s tooltip property.  Then, I add the marker and tooltip to the map via the <code>addOverlay</code> method of the <code>GMap2</code> object.  The last step is to add the <code>mouseover</code> and <code>mouseout</code> listeners to the marker to show and hide the tooltip.</p>
<h3>Things to consider</h3>
<ul>
	<li>You may want to suppress the tooltip when the <code>GInfoWindow</code> is open.  Since the markers do not have a property that indicates whether their info window is open, you would need to add listeners to their <code>infowindowopen</code> and <code>infowindowclose</code> events.  <ins datetime="2007-08-08T12:48:00+00:00">For an example of how to do this check out the source code of the <a href="/examples/Tooltip_v2/">Tooltips with drop shadows example</a>.</ins></li>

	<li>Another possible extension would be to add a timeout to the <code>hide</code> method of the <code>Tooltip</code> object to delay how quickly the tooltip disappears.</li>

	<li><del datetime="2007-08-08T12:48:00+00:00">One limitation of the tooltip is that it currently only supports text.  If you wanted more advanced styling, you could add support to the <code>Tooltip</code> object for inserting DOM Elements.</del>  <ins datetime="2007-08-08T12:48:00+00:00">The <a href="/2007/08/06/the-tooltip-gets-a-shadow-and-dom-node-support/">new version of the tooltip</a> now supports DOM Elements for the content.</ins></li>
<li><del datetime="2007-08-08T12:48:00+00:00">The <code>Tooltip</code> object does not cast a drop shadow. If you want to keep it consistent with the Google Maps look-and-feel, this would be something to consider adding.</del> <ins datetime="2007-08-08T12:48:00+00:00">The <a href="/2007/08/06/the-tooltip-gets-a-shadow-and-dom-node-support/">new version of the tooltip</a> now casts a drop shadow.</ins></li>
</ul>]]></content:encoded>
			<wfw:commentRss>http://onemarco.com/2007/05/16/custom-tooltips-for-google-maps/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>

