Main

Web Archives

January 21, 2007

Mysterious JavaScript function call failure and loading optimization

Optimize Your Scripts in DHTML Using the DEFER Attribute

When, for example, a perfect JavaScript function call foo() with the correct syntax is always mysteriously ignored, watch out for the side effect of script loading optimization. The root cause turned out to be that the script that contains the foo() function is loaded like the the following with "defer":

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

//foo.js
function foo() {
    document.write("hello");
}

Optimization never comes for free. Watch out for the side effects it may brings.

March 12, 2007

Display multiple virtual earth maps on the same web page


Playing with mapping service API is a lot of fun, especially the Virtual Earth 3D maps, on which you can adjust altitude, heading, pitch and so on and pan through the city downtown over the skyscrapers.  Google map and Microsoft Virtual Earth has similar JavaScript/AJAX interfaces.  Tried the MTGoogleMaps plug-in and it's quite good and easy to use.  There is one problem though when displaying, on IE, multiple maps by using multiple template tags on the same page.  The problem the tag will generate the same script-lets each time it appears on a page.  So there are multiple pairs of <div id="map"> and <script> in the resulting page, and the element ID of them are all the same - "map".  Although the element IDs are supposed to be unique across the page, but the browser will still try to render the page when there are ID collision.  However the result is not consistent on IE and Firefox.  Look at this example:

Element ID Collision
    <div id="Div1" style="width: 100px; height: 100px">d1</div>
<script type="text/javascript">
var v = document.getElementById("Div1");
alert(v.innerHTML);
</script>


    <div id="Div1" style="width: 100px; height: 100px">d2</div>
<script type="text/javascript">
var v = document.getElementById("Div1");
alert(v.innerHTML);
</script>

The above script-let will show "d1" and then "d2" on firefox, which suggests the space locality.  The closer element is picked when there are multiple elements with the same ID.  But on IE, "d1" will show up twice.

To fix this issue, firstly we need to move the <div> tag (hosting the map) generation into the client script so that we can generate tags with different IDs.  Secondly, use an array to keep track of all the map objects in case we need them later to further manipulate the maps.

Dynamic Map Object Generation without ID Collision
function CreateMap(width, height)
{
    // If there is no maps on this page at all, initilize the map array
    if (!maps)
    {
        maps = new Array();
        mapId = 0;
    }
   
    // Create a new map and append it to the array
    var nextIdx = maps.length;
    var nextDivId = "mapDiv" + nextIdx;
    document.writeln('<div id="' + nextDivId + '" style="position:relative; width:' + width + '; height:' + height + ';"></div>');
    var map = new VEMap(nextDivId);
    maps[nextIdx] = map;
    ++ nextIdx;
   
    return map;
}

function GetMapByCoordinates(latitude, longitude)
{
    // ...
    map = CreateMap(width, height);
    map.LoadMap(new VELatLong(latitude, longitude));
    // ...
}

March 18, 2007

Test my new Virtual Earth Maps plugin

This is a road-view 2D map:
<$MTVirtualEarthMaps address="525 Bellevue Sq, Bellevue, WA" info="P F Chang" zoom="16" style="r" width="500" height="400"$>

This is a hybrid 3D map of Space Needle viewing at 35 degree angle:
<$MTVirtualEarthMaps latitude="47.620858" longitude="-122.348891" info="Space Needle" style="h" mode="3D" zoom="15" width="500" height="400"$>

Movable Type plugin of Virtual Earth maps

There are some great map plug-ins from Nick Punter and Stefan Dembowski.  I implemented this new one based on Virtual Earth.  Some new features in this plug-in are:
Give it a try at the map test page.
Screen Shot:



Download:

VirtualEarthMaps-0.6.zip

Installations and Instructions:

# Virtual Earth Maps
# (Movable Type Plub-In of Virtual Earth http://maps.live.com/)
#
# Author: Stanley Yao (http://stanblog.jojoyao.com)
# Created: March 10, 2007

Files in this plugin package
============================
-+
 +--plugins
 |   +--VirtualEarthMaps
 |       +--VirtualEarthMaps.pl
 +--mt-static
     +--plugins
         +--VirtualEarthMaps
             +--js
                 +--virtual_earth.js

Installation
============
* Copy the VirtualEarthMaps.pl file into <MTROOT>/plugins/VirtualEarthMaps/
  Create sub-directories as necessary.
  <MTROOT> is where your Movable Type software is installed.
* Copy the virtual_earth.js file into <MT_STATIC_ROOT>/plugins/VirtualEarthMaps/
  Create sub-directories as necessary.
  Here the <MT_STATIC_ROOT> (usually named "mt-static") is not necessarily
  inside your <MTROOT> directory.

Tags to be used to insert maps in your blog
===========================================
<$MTVirtualEarthMaps address="<ADDRESS>"
                     latitude="<LAT>"
                     longitude="<LONG>"
                     info="<INFORMATION>"
                     zoom="<ZOOM>"
                     style="<STYLE>"                     mode="<MODE>"
                     width="<WIDTH>"
                     height="<HEIGHT>"$>

"address" OR ("latitude", "longitude") specifies the location you want to map.
"info" is the extra description (e.g., restaurant name)
"zoom" is how detail the map is.  It can be from 1 through 19, the bigger the more detail.  Default is 15.
"style" can be "r" - "road view", "a" - aerial view, "h" - hybrid view, and "o" bird's eye view.  Default is "r".
"mode" can be "2D" or "3D".  "3D" requires IE.  Default is "2D".
"width" and "height" specifies how big the map is.  Default is 300px by 300px.


Examples:
<$MTVirtualEarthMaps address="525 Bellevue Sq, Bellevue, WA"$>
<$MTVirtualEarthMaps address="525 Bellevue Sq, Bellevue, WA" info="P F Chang" zoom="16" style="r" width="500" height="400"$>
<$MTVirtualEarthMaps latitude="47.604439" longitude="-122.330081" style="r" zoom="15" width="400" height="400"$>
<$MTVirtualEarthMaps latitude="47.620858" longitude="-122.348891" info="Space Needle" style="h" mode="3D" zoom="15" width="500" height="400"$>

Showing maps in your blog entries
=================================
You need "Process Tags" plugin http://kalsey.com/2002/08/process_tags_plugin/.
See more details in Stefan Dembowski's explaination http://www.sixapart.com/pronet/plugins/plugin/mtyahoomaps.html.

Thank:

The following resources have been very helpful:

Bug Report:

You can report bugs by either comment on this entry or send me email at email.GIF .

March 21, 2007

AddThis's bookmarking products user engagement data, clipmarks missing

clipped from www.techcrunch.com
This is a really smart idea that produces very interesting data. Unfortunately, clipmarks, a favorite bookmarking tool of mine, is not measured, because it requires a client browser plug-in to be installed and thus can't be included by the AddThis widget. A surprise is that google bookmarks is as popular as del.icio.us, but its functionality and usability is far behind del.icio.us, digg, and clipmarks.

From the user experience point of view, the AddThis button could be more dynamic. The icons on the button could be clickable, so that there is no need to pop-up another window to choose the bookmarking site. This makes the bookmarking experience more convenient. For example, the small bookmark icons on the button could be displayed based on the user's profile, current bookmarking choice, and aggregated popularity. If the user logins to AddThis, the user's preferred bookmarking sites' icons will be on the button as shortcuts. Otherwise, the last bookmarking sites that were chosen on this browser session will be on the button. The "..." icon will pop-up a window that contains all other icons that are not directly accessible on the button.
  powered by clipmarks

March 28, 2007

Zimbra - Offline Web Office and Collaboration Suite


Zimbra Goes Offline With Zimbra Desktop

The history is once again recurring. Off-line application, then online application, and then "off-line application" again. But rather than circling, this is an evolution in a rising spiral style. When Google online web applications take on Microsoft Office and there is heated discussion about their comparison, this third approach is emerging. Although Google enjoys the buzz of its branding and pricing, web apps still has many limitations like rich UI, performance, security, difficult admin maintenance due to frequent incremental software change, and so on. Off-line ajax solution answered some very important challenges of web apps. For example, the not yet pervasive and stable Internet connection, page latency, and UI responsiveness. This helps narrowing the gap between the web apps and traditional desktop apps.

From server client model's point of view. The same recurring phenomenon is going on. Single machines, main frame, distributed systems, peer to peer systems, web applications running on central servers, and now off-line web applications. The big difference is the placement of software components and the global computing environments and infrastructure - majorly Internet.

From hierarchical architecture's point of view, the off-line web application is a more sophisticated caching model which involves not only static data like web pages and cookies but also software components and application states that run independently on the client machine without any help from the mother ship - servers. This has a load of benefits. For example, performance will improve a lot. "Off-line" is not only used when the network connection is off. Software components and state is cached locally and reduced a large portion of the server-client interaction round trips, especially those bulky post backs. Users data are better maintained locally and is immune to page load failure due to temporary connection problems.

Off-line mode is a significant innovation, but most of the rest of the system is more or less copy from Microsoft Office and/or Google Apps. But it's always like that, new startups who come up with a product, 10% of which are new ideas, are regarded innovative, but the big guys who come up with a similar product are still regarded as copy cats :) The expectations for them are quite different. The world is flattening and so does the computer software industry. These emerging new products are pushing the software moving forward faster.

March 29, 2007

InfoNow switches to Microsoft's Virtual Earth

This is an important step of Microsoft's Virtual Earth improving its branding awareness and could also potentially lead to more value added features to live local search. Virtual Earth comes later than MapQuest, Yahoo maps, and Google Maps, but it does has some nice features like 3-D view, 3-D building model, birds eye view, and my favorite feature Scratch Pad where you can store your favorite locations of restaurants, stores, and so on under different categories. This way you don't have to type in addresses you may check on the map from time to time and you can also conveniently share interesting locations with your friends through email or blog posts. It also showes real time traffic data and road incidents, which could be viewed on your cell phone or GPS to optimize your driving. The push pin is a cute tool too to enable you to mark any location where there is no valid address. There are lots of aspects that Virtual Earth maps needs to improve too though. For example, once I check the driving direction. The route Virtual Earth gave me looks optimal and shorter than the the one I got from Google maps, however in reality the shorter route is mostly through very narrow streets with lots of stop signs. Obviously, the "convenience" of the the streets that are picked for the routing is not weighted enough in Virtual Earth. By the way, if you are interested you can try out the Virtual Earth plugin for MovableType. It's fun to play with the 3D map on your blog.

read more | digg story

April 3, 2007

Live Maps launches new version with Firefox support for 3D

clipped from liveside.net

A new major revision of Live Maps was released today, with a number of new features and enhancements. At the top of the list is Firefox (v 1.5 or later) support for 3D mapping. In addition, memory management and cache performance has been improved for the IE version. 3D support is now also included for the Space Navigator, a 3D controller made by 3dConnexion, a Logitech company.

  powered by clipmarks blog it
This release really has a few very desired new features. Not being compatible with Firefox is a popular complaint about Microsoft's web services products. This is a good answer. Hopefully, the browser compatibility issues could be addressed at the very beginning of the future new product release, so that the public image of being IE-biased can be wiped off and gain more traction over the net.

This new release also enables inserting maps and driving directions into the emails and meeting appointments created in outlook. It is even considerate to block the driving time for the meeting too.

A feature that I have been longing for is the organization of scratch pad. However, still doesn't seem easy to move the push pins over to a different collection.

April 17, 2007

A letter from Pandora founder - Help Save Pandora and Internet Radio

It's sad that the Internet radio is undergoing a struggle to survive.  Actually I found Pandora pretty nice that it incorporates some cool innovative search technologies to help you customize your radio station with your favorite genre, artists, and songs.  When playing your favorites, it will also try recommending other songs and artists that have similar characteristics according to your taste.  Great way to discover new songs.  By interactively rating on those recommended songs you help to continuously refine your customization.  The UI is pretty cute too by the way.  The following is the original letter the Pandora founder sent to many listeners:

Hi, it's Tim from Pandora,

I'm writing today to ask for your help.  The survival of Pandora and all of Internet radio is in jeopardy because of a recent decision by the Copyright Royalty Board in Washington, DC to almost triple the licensing fees for Internet radio sites like Pandora.  The new royalty rates are irrationally high, more than four times what satellite radio pays and broadcast radio doesn't pay these at all.  Left unchanged, these new royalties will kill every Internet radio site, including Pandora.

In response to these new and unfair fees, we have formed the SaveNetRadio Coalition, a group that includes listeners, artists, labels and webcasters.  I hope that you will consider joining us. 

Please sign our petition urging your Congressional representative to act to save Internet radio: http://capwiz.com/saveinternetradio/issues/alert/?alertid=9631541 

Please feel free to forward this link/email to your friends - the more petitioners we can get, the better.  

Understand that we are fully supportive of paying royalties to the artists whose music we play, and have done so since our inception.  As a former touring musician myself, I'm no stranger to the challenges facing working musicians.  The issue we have with the recent ruling is that it puts the cost of streaming far out of the range of ANY webcaster's business potential. 

I hope you'll take just a few minutes to sign our petition - it WILL make a difference. As a young industry, we do not have the lobbying power of the RIAA. You, our listeners, are by far our biggest and most influential allies.

As always, and now more than ever, thank you for your support.

tim_signature.jpg 
-Tim Westergren
(Pandora founder)

 

May 6, 2007

Live.com Zillow Gadget for Tracking Your Home Value

I just created and published a new gadget on live.com called "Zillow Home Value Estimate".  Please give it a try!  The above link points to the gadget hosted on gallery.live.com.  If you are brave enough, you can also try the one I hosted on my own site by clicking the following link "Add the gadget to your live.com" or "Add the gadget to your live space".  I would normally upgrade the 2nd one quicker :)

Screenshot:

zillowGadget.jpg


If you are a home owner put this gadget on your own personalized live.com homepage, so you could closely monitor the value trend of your property.  Type in the street address and city/state (or zip code) of the real estate property that you are interested in, the zillow estimate (zestimate) and the 1 year value trend chart will appear on your live.com personalized home page.  To change the address, click on the underlined address itself and the editing functionality will show up.  The gadget uses zillow web services API to query the home value estimate.

A tip for developing live.com gadgets is beside publishing your new gadgets to the live.com gallery, you could also post a quick link on your own website/blog too so that the visitors can add your gadgets to their home page by a simple click on your site.  All you need to do is put a hyper link http://www.live.com/?add=URL_TO_YOUR_GADGET_XML_FILE for adding to live.com and http://spaces.live.com/spacesapi.aspx?wx_action=create&wx_url=URL_TO_YOUR_GADGET_XML_FILE for adding to live spaces. For example: <a href="http://www.live.com/?add=http://stanley.jojoyao.com/live_gadgets/Zillow/ZillowGadget.xml">Add to Live.com</a> and <a href="http://spaces.live.com/spacesapi.aspx?wx_action=create&wx_url=http://stanley.jojoyao.com/live_gadgets/Zillow/gadget.xml">Add to Live Spaces</a>

May 10, 2007

innerHTML could invalidate the event handlers of its child elements

In Javascript, using an element's innerHTML property to dynamically edit its content provides much flexibility and convenience.  But special care needs to be taken when using it, because it could bite you silently.  Take one of my experiences as an example, it could break the event handlers of the child elements.  Sample code as the following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>innerHTML</title>
</head>
<body>

<hr /><div id="myd"></div><hr />

<script language="javascript">
function myaction()
{
    alert("hello");
}

var d1 = document.createElement("div");
d1.onclick = myaction;
d1.innerHTML = "child div";

var d = document.getElementById("myd");
d.appendChild(d1);
//d.innerHTML += "parent div";
</script>

</body>
</html>

This code works well and when you click on div, "hello" will pop up.  However if you uncomment the last line of the JavaScript code.  The message won't pop up any more.  innerHTML manipulates the content of the element as a string instead of DOM, so it might just break the underlying "wires" that hooks up the elements and their event handlers.  So watch out, when any of the events stops working as expected, look for the evil "innerHTML" first.

May 22, 2007

Building database and web service driven asynchronous google map application

Map API could help build very cool mashup websites.  Often times a back end database is the source of the objects to be drawn on the map and querying for those objects from the database based on the parameters the users choose on the website (e.g., state, city, search criteria) gets complex.  Also to improve the user experience, asynchronous map loading is desired so that while the next batch of objects is being retrieved from the server, the current ones on the map could continue functioning.  To address all these challenges and build a smooth database driven asynchronous loading map application, web service can serve as the bridge between the server side complex data model and the client side map drawing logic.  The following describes the steps of implementing such architecture and a sample code project created in Visual Studio (free version could be downloaded here).  This time, I played with Google Maps API.

ws_map.jpg

Firstly, set up a basic ASP.NET AJAX-enabled web site through the Visual Studio wizard.  You may need to download the AJAX extension from http://ajax.asp.net/.  Inside Default.aspx, add a div in the body like the following to host the map

<div id="map" style="width: 90%; height: 600px; margin-left:auto; margin-right:auto"></div>

Reference the google api javascript source and your own javascript file (e.g., gmap.js where the client side mapping code is located) in the head section.

Next is to prepare the data on the server side.  It is actually much easier to set up a relational database in Visual Studio by a just few clicks and there are tons of such examples on the web.  So here let's try a slightly trickier scenario where we only have a static plain text CSV data file (e.g., exported from an legacy system or Excel spreadsheet) that contains various cities and the fun places in them to be drawn on the map.  Add that data file (e.g., mapdata.csv) under the App_Data/ folder in the solution explore.  Assume the data file has 3 columns State, City, and FunPlace.  Now create a web service (e.g., MapDataWebService) to extract the data from the CSV file and serve to the client side mapping code.  To add this web service, right click the project in the solution explore, select "Add New Item...", select "Web Service", and then rename the file name into "MapDataWebService.asmx".  The web service skeleton is automatically added under App_Code/.  Open it and add 2 web methods getAllStates() and getFunPlacesByState(string state).  The former is used to populate the dropdown on the web page to select a state and the latter is to get the fun places of the selected state.  Both methods connect to the data file through OLE DB and query the data using convenient SQL syntax.  To quickly unit test the web method, you could open MapDataWebService.asmx and press F5 to run the web service alone.

The return value of getFunPlacesByState(string state) would be an array of objects (type of class Place), each of which contains the latitude and longitude of the city and the name of the fun place in that city.  The class Place is the object oriented representation of this information.  The web service will return the objects to the JavaScript caller.  In order for the caller to get the consistent objects and dereference them the same way as in C#, the following directive should be added to the top of the web service code and a reference to the assembly System.Web.Extensions.dll needs to be added to the solution too.  If you don't have this assembly already installed on your machine, you could download and install "ASP.NET Ajax" from http://ajax.asp.net/.

...
using System.Web.Script.Services;
...
    [ScriptService]
    [GenerateScriptType(typeof(Place))]
    public class MapDataWebService : System.Web.Services.WebService
    {
....
    }
    public class Place
    {
....
    }


After the data service is created, the getAllStates() web method could be used to build a data source to populate the dropdown list.  Drag and drop a dropdown list onto the Default.aspx, select to create a new data source from its context menu, choose object as the type, MapDataWebService as the business object, and getAllStates() as the SELECT method.  The data binding is automatically done.  Add an onchange event handler to this control to trigger the mapping function (e.g., drawMarkers) and we are almost done.

The last step is to implement the mapping method drawMarkers() in gmap.js.  It retrieves the state that the user chose in the dropdown and use it as the parameter to call the web service method getFunPlacesByState(state) asynchronously.  The callback function will receive the resulting list of Place objects and then use the Google maps API to draw them on the map.  To successfully make the web service call from JavaScript, it has to be registered in the Default.aspx like the following.

<asp:ScriptManager ID="ScriptManager1" runat="server">
    <Services>
        <asp:ServiceReference Path="~/MapDataWebService.asmx" />
    </Services>
</asp:ScriptManager>

To make it more fun and improve the user experience, during the async web service call, a spinning progress icon could be display indicating that the data is being loaded.  Overall, no whole page loading is done and web page looks better.  If you are interested the sample solution and code can be downloaded GMapExample.zip.  Before you can compile and run this web site, go to http://www.google.com/apis/maps/ to register your API key and replace the place holder "YOUR_API_KEY" in file Default.aspx and App_Code/MapDataWebService.cs.

By the way, a comment about Google Maps API.  The markers manager is a convenient way of aggregating all the markers, but removing objects from the manager seems buggy.  Whenever the map zoom level is changed, all the removed markers come back on the map.  The markers in the manager are not controlled by the map.removeOverlay() either.  Other than that, the API works pretty well.

Sample code download: GMapExample.zip

May 30, 2007

Google Gear: Web Applications Going Offline

The offline web applications like Zimbra narrow the gap between the web and desktop applications in many aspects like connectivity, performance, reliability, etc.  The newly released Google Gear is an even bigger hit in that it sets a platform to help bring any web application "offline".  This will change the way people perceive "web application".  You do NOT need to be always connected to a network in order to use a web application any more.

(From TechCrunch.com) Google Gears Lets Developers Take Apps Offline: Tomorrow, Google will be hosting a developer day for 5,000 developers worldwide...


Followed offline app demo above, I tried the offline Google Reader.  It is very cool.  Also tried simulating an unexpected network connection drop.  When browsing the feeds in Google Reader in "online" mode, the network was suddenly disconnected.  It tried to read the content but timed out.  Then it popped up a window reporting the connection drop and asked if I would like to switch to "offline" mode.  Answer "yes" and I was able to continue reading the feeds offline!  After I get back online, the local data (items marked as read) is synchronized back to the server.  I was never a big fan of Google Reader due to its lack of useful features.  But this offline mode really draws my attention and interest to try using it more.

What's next?  If this offline technology is used in developing mobile applications and it supports automatic smart downloading and synchronizing, it could greatly improve the performance of the sophisticated applications running on mobile devices with limited bandwidth.

An interesting comparison is with the Microsoft Smart Clients offline mode emerged in 2004 with the similar idea.

June 6, 2007

Cross-browser Event Handler Assignment

Making the client side scripts work across different major browsers is not easy, especially when client debugging is not as convenient as more strongly typed programming languages.  Try the following web page.  It works fine on IE but on FireFox clicking the button will trigger nothing to happen.

<html xmlns="http://www.w3.org/1999/xhtml" >
<
head><title>Untitled Page</title></head>
<
script language="Javascript">
function
document.onclick() {
  alert(
'doc event');
}
function foo() {
  alert(
'foo');
}
</script>
<
body>
<
input type="button" value="ok" onclick="foo();" />
</
body>
</
html>

The page will silently fail and none of the event handlers works.  Change the document.onclick handler assignment into the following and it works on both browsers.  Tools like the Error Console on FireFox is very helpful in diagnosing these type of errors.

...
document.onclick = function () {
  alert(
'doc event');
}
...

June 14, 2007

Yahoo! Mail Offering Unlimited Storage

 

Yahoo! Mail begins to roll out unlimited storage today worldwide.  Feeling lucky that minutes after their announcement, I'm getting this great offer already.  Now I don't need to worry about overflow any more. :)

July 7, 2007

Live Earth - 24 Hours Global Concerts for a Climate in Crisis

LE_logo_horz.jpg

Facts:

  • Across 6 continents
  • 24 hours exclusive beaming on liveearth.msn.com
  • 2 billion audience world wide
  • Organized in part by Al Gore
  • 150+ top bands

September 1, 2007

50 Best Websites 2007

clipped from www.time.com
From Photonhead.com to Cellswapper and FunnyorDie.com to Lastfm, we've chosen our favorite sites of the year.
  blog it