Monday, February 26, 2007

AJAX Safe HTML Forms

Whenever you create a form on a HTML page it's easy to make it AJAX safe. All you have to do is call your ajax form submission code in the forms onsubmit event and specify the standard postback address in case the ajax fails or the user doesn't have javascript support. Use this template:

<form action="servercode.aspx" onsubmit="return ajax submit()">
...
.
.
.

function ajax_submit()
{
// if ajax submission successfull
return false;

//else if ajax submssion failed
return true;
}

So if the ajax postback to the server was successful post back to the action URL will not take place. Hence, if you pass false to onsubmit, the form will not postback. However if you return true to onsubmit the form will do a traditional post back.

In conclusion, since we only return false if the ajax action was successful the program degrades gracefully to a traditional post back. That is an ajax safe html form!

Saturday, February 10, 2007

Creating Custom Controls for Google Maps

With the release of the Google Maps API, usage of the fantastic framework Google has laid is now possible. Fueled by the easy to use, highly abstracted and well documented API, customized versions of Google Maps are running all over the Internet. With the API it is possible to create custom effects, tools, data, etc. for your map -- basically, the possibilities are endless because you have access to the whole world of the Javascript language. This article will show how to create a custom control for google maps, which will allow a user to click and drag a rectangle over a selected area on the map which will then be centered on and magnified.

What is a Google Maps Control?

While there is no specific definition of a maps API control per se, however basically a control is this: some tool ("control") that is displayed in the google maps window and provides some custom functionally that doesn't come with the maps API. Technically, a control is anything that implements the GControl Interface. The maps API already comes with a hand full of helpful controls:
  • GLargeMapControl - a large pan/zoom control used on Google Maps. Appears in the top left corner of the map.
  • GSmallMapControl - a smaller pan/zoom control used on Google Maps. Appears in the top left corner of the map.
  • GSmallZoomControl - a small zoom control (no panning controls) used in the small map blowup windows used to display driving directions steps on Google Maps.
  • GScaleControl - a map scale
  • GMapTypeControl - buttons that let the user toggle between map types (such as Map and Satellite)
  • GOverviewMapControl New! - a collapsible overview map in the corner of the screen
If you've ever used the maps API you should be familiar with at least one of these controls. They are already implemented and included in the maps API, however now, we are going to make our own custom control, that allows the user to click a point on the map and drag a rectangle over and area to another point. This area will then be centered upon and magnified to the appropriate level.

The Hello World of GMaps Controls

As I alluded to above, the most minimal amount of code you have to write to create a true gmaps control is implement the GControl interface.

// base definition and inheritance
function MyCustomControl()
{
}

//Default constructor for GControl
MyCustomControl.prototype = new GControl(false,false);

// Default location for the control
MyCustomControl.prototype.getDefaultPosition = function() {
return new GControlPosition(G_ANCHOR_TOP_LEFT,new GSize(700,8));
};

GControlSelector.prototype.initialize = function(gmapref)
{

var container=gmapref.getContainer();

var c = document.createElement("div");
c.innerHTML="This is a custom control";

container.appendChild(c);

return c;
}


The first function MyCustomControl()is the name of the class and the control, this is your base class for the control. The next block of code simply initializes an instance of the GControl() interface using it's default constructor, so now we must implement all it's required interfaces.

The required members of the GControl interface are:
  • printable() > bool -- Returns to the map if the control should be printable.
  • selectable() > bool -- Returns to the map if the control contains selectable text.
  • initialize(map) > Node -- Will be called by the map so the control can initialize itself.
  • getDefaultPosition() > GControlPosition -- Returns to the map the position in the map view at which the control appears by default. This will be overridden by the second argument to GMap2.addControl().
We already have 2 of these implimented by means of our call to the GControl contstructor which has this signature: GControl(printable?, selectable?). Since we passed false to both the parameters we only need to impliment initialize(map) and getDefaultPosition().

initialize(map) - The purpose of the initialize method is to build the control, i.e. load it's code for use. For, all we are doing in initialize is build the UI, which is a simple div element with some text inside. Once we build the UI we add it the map and return it.
getDefaultPosition() - The purpose of the getDefaultPosition() method is so the maps API knows where to place the control if the user doesn't specify a custom location.

Almost there. Once we have designed our custom control we have one step left, we must add it to the map using the method Gmap2.addControl().

Adding the control to the map

Now we have to add our control to the map, this is the last step of creating your custom control.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=abcdefg"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.addControl(new MyCustomControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
}
}

//]]>
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

The above is a stock google maps page. The above highlighted text is all we need to do to use
our new google maps custom control.






Friday, February 9, 2007

The Medium is the Message; The Future of the User Interfaces

Critical comparison of traditional user interface development and web-based user interface development showing how web-based user interfaces are the future

Abstract
HTML is the most perfect medium available today to build user interfaces for software; compiled programming languages are not and are already being matched in complexity and easy of use by their web based (HTML/CSS/Javascript) rivals. Progress in web based UIs is being fueled by the Renaissance of the XMLHTTP Javascript object, or in more commonly, "AJAX". With a web-based front end interface and C#/ASP.net back end connected via asynchronous AJAX calls over broadband Internet connections, the web based user experience is virtually as seamless as their desktop based rivals.

Designing a UI with C#/Java
The process of creating UI elements in a C# applicaiton is reletlivy simple in itself, but the larger context you'll see how it is inheretnly not suited for this task. Also, I will not go deeply into the symantics of C#. Below is a barebones .net 3.0 windows app written in C#:

using System;
using System.Windows.Forms;

namespace alexegg.com
{
class UI : Form
{
static void Main()
{
Application.Run(new UI());
}
}
}



None of the above code actually defines/configures any element of the UI. All it does is tell the C# language, which is not natively designed to build UIs, that we want this class to have a Windows UI. Lets modify the above skeleton C# windows from to look like the below HTML login screen:



I'll save the HTML for this example for later, now let's look at the C# code required to recreate this simple HTML interface:


using System;
using System.Windows.Forms;

namespace alexegg.com
{
class UI : Form
{
private System.Windows.Forms.TextBox textBoxPassword;
private System.Windows.Forms.Button buttonSubmit;
private System.Windows.Forms.PictureBox pictureBoxLogo;
private System.Windows.Forms.Panel panelDialog;
private System.Windows.Forms.CheckBox checkBoxRemember_me;
private System.Windows.Forms.Label labelPassword;
private System.Windows.Forms.Panel panelDialogBorder;

public UI()
{
this.textBoxPassword = new System.Windows.Forms.TextBox();
this.buttonSubmit = new System.Windows.Forms.Button();
this.pictureBoxLogo = new System.Windows.Forms.PictureBox();
this.panelDialog = new System.Windows.Forms.Panel();
this.labelPassword = new System.Windows.Forms.Label();
this.checkBoxRemember_me = new System.Windows.Forms.CheckBox();
this.panelDialogBorder = new System.Windows.Forms.Panel();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxLogo)).BeginInit();
this.panelDialog.SuspendLayout();
this.SuspendLayout();


//
// textBoxPassword
//
this.textBoxPassword.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxPassword.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(102)))), ((int)(((byte)(102)))), ((int)(((byte)(102)))));
this.textBoxPassword.Location = new System.Drawing.Point(125, 31);
this.textBoxPassword.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.textBoxPassword.Name = "textBoxPassword";
this.textBoxPassword.Size = new System.Drawing.Size(150, 27);
this.textBoxPassword.TabIndex = 0;
this.textBoxPassword.UseSystemPasswordChar = true;
//
// buttonSubmit
//
this.buttonSubmit.Font = new System.Drawing.Font("Verdana", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonSubmit.Location = new System.Drawing.Point(125, 107);
this.buttonSubmit.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.buttonSubmit.Name = "buttonSubmit";
this.buttonSubmit.Size = new System.Drawing.Size(66, 29);
this.buttonSubmit.TabIndex = 1;
this.buttonSubmit.Text = "Sign in";
this.buttonSubmit.UseVisualStyleBackColor = true;
//
// pictureBoxLogo
//
this.pictureBoxLogo.Image = System.Drawing.Image.FromFile("resources\tcs_logo.png");
this.pictureBoxLogo.Location = new System.Drawing.Point(258, 49);
this.pictureBoxLogo.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.pictureBoxLogo.Name = "pictureBoxLogo";
this.pictureBoxLogo.Size = new System.Drawing.Size(106, 107);
this.pictureBoxLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pictureBoxLogo.TabIndex = 2;
this.pictureBoxLogo.TabStop = false;
//
// panelDialog
//
this.panelDialog.BackColor = System.Drawing.Color.White;
this.panelDialog.Controls.Add(this.checkBoxRemember_me);
this.panelDialog.Controls.Add(this.labelPassword);
this.panelDialog.Controls.Add(this.textBoxPassword);
this.panelDialog.Controls.Add(this.buttonSubmit);
this.panelDialog.Location = new System.Drawing.Point(72, 192);
this.panelDialog.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.panelDialog.Name = "panelDialog";
this.panelDialog.Size = new System.Drawing.Size(475, 162);
this.panelDialog.TabIndex = 3;
//
// labelPassword
//
this.labelPassword.AutoSize = true;
this.labelPassword.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelPassword.Location = new System.Drawing.Point(25, 35);
this.labelPassword.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.labelPassword.Name = "labelPassword";
this.labelPassword.Size = new System.Drawing.Size(92, 18);
this.labelPassword.TabIndex = 2;
this.labelPassword.Text = "Password:";
//
// checkBoxRemember_me
//
this.checkBoxRemember_me.AutoSize = true;
this.checkBoxRemember_me.Font = new System.Drawing.Font("Verdana", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.checkBoxRemember_me.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(102)))), ((int)(((byte)(102)))), ((int)(((byte)(102)))));
this.checkBoxRemember_me.Location = new System.Drawing.Point(125, 77);
this.checkBoxRemember_me.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.checkBoxRemember_me.Name = "checkBoxRemember_me";
this.checkBoxRemember_me.Size = new System.Drawing.Size(235, 20);
this.checkBoxRemember_me.TabIndex = 3;
this.checkBoxRemember_me.Text = "Remember me on this computer";
this.checkBoxRemember_me.UseVisualStyleBackColor = true;
//
// panelDialogBorder
//
this.panelDialogBorder.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
this.panelDialogBorder.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(204)))), ((int)(((byte)(204)))), ((int)(((byte)(204)))));
this.panelDialogBorder.Location = new System.Drawing.Point(60, 180);
this.panelDialogBorder.Name = "panelDialogBorder";
this.panelDialogBorder.Size = new System.Drawing.Size(500, 186);
this.panelDialogBorder.TabIndex = 4;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(229)))), ((int)(((byte)(229)))), ((int)(((byte)(229)))));
this.ClientSize = new System.Drawing.Size(622, 415);
this.Controls.Add(this.pictureBoxLogo);
this.Controls.Add(this.panelDialog);
this.Controls.Add(this.panelDialogBorder);
this.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.Name = "Form1";
this.Text = "Login Form";
((System.ComponentModel.ISupportInitialize)(this.pictureBoxLogo)).EndInit();
this.panelDialog.ResumeLayout(false);
this.panelDialog.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}

static void Main()
{
Application.EnableVisualStyles();
Application.Run(new UI());
}
}
}

Below is the respective HTML + CSS for the exact same UI


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Login Form</title>
<style>
#login_container
{
width:100%;
height:700px;
position:absolute;
background-color:#E5E5E5;
z-index:99;
color:#333333;
font-family:"Lucida Grande",verdana,arial,helvetica,sans-serif;
margin:0pt auto;
padding:0pt;
text-align:center;
}
.login div.cont {
margin:60px auto 20px;
min-width:inherit;
width:500px;
}
div#LogoBox {

}
div#LogoBox img {

}
.login div#Dialog {
background:#FFFFFF none repeat scroll 0%;
border:10px solid #CCCCCC;
padding:15px 20px 10px;
text-align:left;
}
form {
margin:0pt;
padding:0pt;
}
.login dl {
margin:10px 0pt 0pt;
}
.login dt {
float:left;
font-size:14px;
line-height:24px;
width:80px;
}
.login dd {
color:#666666;
font-size:11px;
line-height:24px;
margin:0pt 0pt 5px 80px;
}
.login input#password {
margin-right:5px;
width:150px;
}
.login dd span {
color:#CCCCCC;
}
.login input {
font-size:14px;
}
#Flash.bad {
background:#CC0000 url(images/alertbad_icon.gif) no-repeat scroll left center;
border-color:#CC9999;
color:#FFFFFF;
}
.login #Flash {
font-size:12px;
margin-top:12px;
}
#Flash {
border:1px solid #CCCCCC;
font-size:14px;
margin:0pt 7px 12px auto;
padding:5px 5px 5px 30px;
text-align:left;
}
</style>
</head>
<body>
<div class="login" id="login_container">
<div class="cont">
<div id="LogoBox">
<img alt="Time Critical Solutions" src="resources/tcs_logo.png" /></div>
<div id="Dialog">
<form method="post" action=" ">
<dl>
<dt>Password:</dt>
<dd>
<input type="password" id="password" name="password" />
</dd>
<dd>
<input type="checkbox" name="remember_me" />
Remember me on this computer</dd>
<dd>
<input type="submit" value="Sign in" /></dd>
</dl>
</form>
</div>
</div>
</div>
</body>
</html>


Why is the Java community so far behind the C# community in terms of UI Development (An example of why c based language UI development is inherently wrong)
Designing user interfaces with technologies (HTML/CSS/Javascript) designed for information layout make infinitely more sense then designing interfaces with technologies designed for procedural tasks (compiled programming languages). Even with Microsoft Visual Studio Form Designer, one of the most advanced software interface building applications available today, design and development of UIs is awkward and clunky and almost impossible with the automated code emitted from the form builder. This truth is evident when you take a look at the state of UIs in the Java community. SWING/AWT and a few other tools kits available to the Java community are ill suited and largely inferior to Microsoftnulls solution, which is reflected in the lack of UI progression in the java community. This is a direct reflection of how awkward it is to create compelling user interfaces with c based languages. C# and Java are very similar in syntax and functionally, they can be considered cousins, however then why does the .net/C# community have such more advanced and numerous developed UIs? It's not cause one is more suited to develop UIs or that C# has a larger commuinity using it or that C# is older, but that the .net community has the Visual Studio form designer, a powerful tool to create UIs.

A window on a computer is not good for presenting information with a compelling design. With a pixel based layout, you spend more time writing code to get your content int he right place or to display at all, rather then concentrate on the content and if it looks compelling.

Creating rich UIs with c based languages, is simply too hard. For example, if I wanted to show a little emphasis to an element on my web page, I could just make a quick call to the Highlight method in the Prototype library. However, to do this in a programming environment, I'd have to find some class library with that functionally that works with my language/environment or else I'd have to code that from scratch. In the end you decide it's not even worth it for a little UI garnish.

Explore XAML UIs in .net 3.0

test from google docs

Thursday, February 8, 2007

Using Google Maps without API Key, Guide

When you use the Google maps API, you have to get a site key. To get a site key you need to register your website, however, what if you don't even have a website yet and you developing your site locally? If you enter 'http://localhost' into the API key registration form, it will give you a key but don't let this fool you, the maps won't load!

This is an easy problem to alleviate, with a simple one line javascript edit. Let's take a look at the Google Maps hello world example:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2&key=abcdefg"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
}
}

//]]>
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>

Notice the red line in the above source. This downloads a javascript file from google that acts like a configuration file for your map. Included in it is the code that checks your API key. All we have to do is remove the line that checks and were in action. So, since we need to run the js config file directly, we need to save it to our computer, just enter the line in red into your browser. This is the config file that the script element in your html page points to.

var G_INCOMPAT = false;
function GScript(src) {
document.write('<' + 'script src="' + src + '"' + ' type="text/javascript"><' + '/script>');
}
function GBrowserIsCompatible() {
if (G_INCOMPAT) return false;
if (!window.RegExp) return false;
var AGENTS = ["opera", "msie", "safari", "firefox", "netscape", "mozilla"];
var agent = navigator.userAgent.toLowerCase();
for (var i = 0; i < agentstr =" AGENTS[i];" versionexpr =" new" version =" 0;" version =" parseFloat(RegExp.$1);" agentstr ="=">= 7;
if (agentStr == "safari") return version >= 125;
if (agentStr == "msie") return (version >= 5.5 &&amp;amp;amp;amp;amp; agent.indexOf("powerpc") == - 1);
if (agentStr == "netscape") return version > 7;
if (agentStr == "firefox") return version >= 0.8;
}
}
return !!document.getElementById;
}
function GVerify() {
}
function GLoad() {
if (!GValidateKey("")) {
G_INCOMPAT = true;
alert("The Google Maps API key used on this web site was registered for a different web site. You can generate a new key for this web site at http://www.google.com/apis/maps/.");
return;
}
GLoadApi(["http://mt0.google.com/mt?n=404&v=w2.37&amp;amp;amp;amp;amp;", "http://mt1.google.com/mt?n=404&v=w2.37&", "http://mt2.google.com/mt?n=404&v=w2.37&", "http://mt3.google.com/mt?n=404&v=w2.37&"], ["http://kh0.google.com/kh?n=404&v=14&", "http://kh1.google.com/kh?n=404&v=14&", "http://kh2.google.com/kh?n=404&v=14&", "http://kh3.google.com/kh?n=404&v=14&"], ["http://mt0.google.com/mt?n=404&v=apt.36&", "http://mt1.google.com/mt?n=404&v=apt.36&", "http://mt2.google.com/mt?n=404&v=apt.36&", "http://mt3.google.com/mt?n=404&v=apt.36&"], "", "", "", false);
if (window.GJsLoaderInit) {
GJsLoaderInit("http://maps.google.com/mapfiles/maps2.72.api.js");
}
}
function GUnload() {
if (window.GUnloadApi) {
GUnloadApi();
}
}
var _mFlags = {
}
;
var _mHost = "http://maps.google.com";
var _mUri = "/maps";
var _mDomain = "google.com";
var _mStaticPath = "http://www.google.com/intl/en_us/mapfiles/";
var _mTermsUrl = "http://www.google.com/intl/en_us/help/terms_local.html";
var _mTerms = "Terms of Use";
var _mMapMode = "Map";
var _mMapModeShort = "Map";
var _mMapError = "We are sorry, but we don\'t have maps at this zoom level for this region.

Try zooming out for a broader look.

";
var _mSatelliteMode = "Satellite";
var _mSatelliteModeShort = "Sat";
var _mSatelliteError = "We are sorry, but we don\'t have imagery at this zoom level for this region.

Try zooming out for a broader look.

";
var _mHybridMode = "Hybrid";
var _mHybridModeShort = "Hyb";
var _mSatelliteToken = "fzwq2rajrYBh2hw6LvGp_HbYvCkqeQX6J9W0Jg";
var _mZoomIn = "Zoom In";
var _mZoomOut = "Zoom Out";
var _mZoomSet = "Click to set zoom level";
var _mZoomDrag = "Drag to zoom";
var _mPanWest = "Pan left";
var _mPanEast = "Pan right";
var _mPanNorth = "Pan up";
var _mPanSouth = "Pan down";
var _mLastResult = "Return to the last result";
var _mMapCopy = "Map data ©2007 ";
var _mSatelliteCopy = "Imagery ©2007 ";
var _mGoogleCopy = "©2007 Google";
var _mKilometers = "km";
var _mMiles = "mi";
var _mMeters = "m";
var _mFeet = "ft";
var _mPreferMetric = false;
var _mPanelWidth = 20;
var _mTabBasics = "Address";
var _mTabDetails = "Details";
var _mDecimalPoint = '.';
var _mThousandsSeparator = ',';
var _mUsePrintLink = 'To see all the details that are visible on the screen,use the "Print" link next to the map.';
var _mPrintSorry = '';
var _mMapPrintUrl = 'http://www.google.com/mapprint';
var _mPrint = 'Print';
var _mOverview = 'Overview';
var _mStart = 'Start';
var _mEnd = 'End';
var _mStep = 'Step %1$s';
var _mStop = 'Destination %1$s';
var _mHideAllMaps = 'Hide Maps';
var _mShowAllMaps = 'Show All Maps';
var _mUnHideMaps = 'Show Maps';
var _mShowLargeMap = 'Show original map view.';
var _mmControlTitle = null;
var _mAutocompleteFrom = 'from';
var _mAutocompleteTo = 'to';
var _mAutocompleteNearRe = '^(?:(?:.*?)\s+)(?:(?:in|near|around|close to):?\s+)(.+)$';
var _mSvgEnabled = true;
var _mSvgForced = false;
var _mStreetMapAlt = 'Show street map';
var _mSatelliteMapAlt = 'Show satellite imagery';
var _mHybridMapAlt = 'Show imagery with street names';
var _mSeeOnGoogleMaps = "Click to see this area on Google Maps";
var _mLogInfoWinExp = true;
var _mLogPanZoomClks = false;
var _mLogWizard = true;
var _mTransitV2 = false;
function GLoadMapsScript() {
if (GBrowserIsCompatible()) {
GScript("http://maps.google.com/mapfiles/maps2.72.api.js");
}
}
GLoadMapsScript();



So to block the site key from being checked just remove the first whole if statement from the GLoad() function. Now the only step left is to point your script tag in your html file to point to this new config file instead of Google's. For example, I saved my script file as 'gmaps_config.js' to the same directory as my html page. So, I changed the script tag to this:

<script src="gmaps_config.js" type="text/javascript"></script>

Now the key check never takes place, and I can do development with Google maps without copying my site to a webserver everything I want to test it!


Update: 2/9/07

Geocoding by use of the GClientGeocoder class in the Google Maps API will not work if you are not using an API key. When you call any members of the GClientGeocoder class your API key as defined in your script block is attached to the http request sent to Google:

http://maps.google.com/maps/geo?q=San%20Diego%2C%20Ca&output=json&callback=__geoStore.__cg01171075463312&key=

Notice how the last parameter, 'key' is blank, well it appears that google validates this on the server side and since we don't have one defined the geocoder returns a 610 error which maps back to, GGeoStatusCode.G_GEO_BAD_KEY or " The given key is either invalid or does not match the domain for which it was given."

Well, I know what I'll be working on for the next few days!