Usage and Quick Start

This page shows how to get up and running quickly on Windows platforms using either IE or FireFox.

Prerequisites

  1. You should have a basic understanding of JavaScript and the prototype JavaScript library.
  2. Download and Install the Garmin Communicator Plugin
  3. Obtain a Garmin Communicator key to unlock the plugin (only needed for site deployment).

Code Examples

  1. Verify Garmin Communicator presence
  2. Unlock the Plugin
  3. Connect to GPS Devices
  4. GPS + Google Maps
  5. Upload a waypoint to a GPS device

Verify Garmin Communicator presence

This example just verifies that you have the Garmin Communicator ActiveX Plugin installed and that you can communicate with it using JavaScript.

The bare minimums are:

  1. The prototype, plugin and control script elements must be referenced with valid URLs.
  2. The GarminActiveXControl object must be present in the HTML body.

Step-By-Step

  1. Create a web page and name it plugin.html. Then paste in the following code:
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <title>Check for Garmin Communicator Plugin</title>
    </head>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js">&#160;</script>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js">&#160;</script>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js">&#160;</script>
    <script type="text/javascript">
        var control;    
        function load() {
            try {
                control = new Garmin.DeviceControl();
                if(control.isPluginInitialized()) {
                        $('message').innerHTML = "<h2>Garmin Communicator plugin version "+control.getPluginVersionString()+" found!</h2>";
                    }
            } catch(e) {
                    $('message').innerHTML = "<h2>" + e.message + "</h2>";
            }
        }
    </script>
    <body onload="load()">
        <h1>Check for Garmin Communicator Plugin</h1>
        <div id="message"></div>
        <object id="GarminActiveXControl" style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0" classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5">
                    <object id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin" width="0" height="0"> </object>
            </object>
    </body></html>
  2. Load it into IE or FireFox.
  3. Verify the you get the 'Communicator Found' message.

Unlock the Plugin

The next example adds a call to unlock the plugin. This call is required before calling any other communicator methods. Normally you pass the base URL of your host site and the key obtained from Garmin, however for development on your localhost you don't need to pass any parameters. The important point about the key is that it must be verified against the exact same URL that was used to generate it. So if the key was generated using 'http://mydomain.com/', none of the following will successfully unlock the plugin:

  1. http://mydomain.com
  2. http://myDomain.com/
  3. http://www.mydomain.com/

Only 'http://mydomain.com/' will work!

Follow the steps in the last example to run this example.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Unlock the Plugin</title>
</head>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js">&#160;</script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js">&#160;</script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js">&#160;</script>
<script type="text/javascript">
    var control;    
    function load() {
        try {
            control = new Garmin.DeviceControl();
            if(control.isPluginInitialized()) {
                    $('message').innerHTML = "<h2>Garmin Communicator plugin version "+control.getPluginVersionString()+" found!</h2>";
                }
                
                if(control.unlock("http://mydomain.com","pasteYourKeyInHere")) {
                $('status').innerHTML = "The plug-in has been unlocked successfully";
                        } else {
                                $('status').innerHTML = "The plug-in was not unlocked successfully";
                        }
        } catch(e) {
                $('message').innerHTML = "<h2>" + e.message + "</h2>";
        }
    }
</script>
<body onload="load()">
    <h1>Unlock the Plugin</h1>
    <div id="message"></div>
    <div id="status"></div>
    <object id="GarminActiveXControl" style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0" classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5">
        <object id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin" width="0" height="0"> </object>
    </object>
</body></html>

Connect to GPS Devices

This example starts getting more interesting and demonstrates how to get a list of connected devices. The key point in this example is the use of call-back method to handle the plugin responses. The two steps typical of handling call-back communication with the plugin are:

  1. Create a listener class with call-back methods of interest. Note all call-back methods are prefixed with on, in this case the method is onFinishFindDevices:
    var listener = Class.create();
    listener.prototype = { 
        onFinishFindDevices: function(json) { 
        ... }}
  2. Register an instance of the listener class with the control:
    control.register( new listener() );

Step-By-Step

  1. Paste thoe following code into an html file called devices.html
  2. Load it into your browser
  3. Plugin a GPS device using a USB cable and turn it on
  4. Click on the Load Devices button (it may take a few seconds to find them)
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <title>Connect to Garmin GPS Devices</title>
    </head>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js">&#160;</script>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js">&#160;</script>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js">&#160;</script>
    <script type="text/javascript">
        var control;
        //create a call-back listener class
        var listener = Class.create();
        listener.prototype = { 
            initialize: function() { },
            onFinishFindDevices: function(json) { 
                var devices = json.controller.getDevices();
                var str = "<b>Devices Found: "+devices.length+"</b><ol>";
                if (json.controller.numDevices > 0) {
                    for( var i=0; i < devices.length; i++ ) {
                        str += "<li>"+devices[i].getDisplayName()+"</li>";
                    }
                    str += "</ol>";
                    $('devices').innerHTML = str;
                }
            }
        }
    
        function load() {
            try {
                control = new Garmin.DeviceControl();
                control.register(new listener());
                var unlocked = control.unlock("http://mydomain.com","pasteYourKeyInHere");
                $('msg').innerHTML = "<h2>Found Plugin, unlocked="+unlocked+"</h2>";
            } catch(e) { alert(e); }
        }
    
        function findDevices() {
            try {
                control.findDevices();
            } catch(e) { alert(e); }
        }
    </script>
    
    <body onload="load()">
        <h1>Auto Load Plugin</h1>
        <div id="msg"></div>
        <div id="devices"></div>
        <input type="button" value="Find Devices" onclick="findDevices()">
        <object id="GarminActiveXControl" style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0" classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5">
            <object id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin" width="0" height="0"> </object>
        </object>
    </body></html>

GPS + Google Maps

This example enters the realm of cool, allowing you to see your own track or waypoint data on a Google map. This code is closer to a real-world application, supporting progress bars and status line feedback. This code is taken from the DeviceControl API Demo which you can refer to for a running example.

The JavaScript is a little more verbose, but the methods are broken down into logical sections that taken one-at-a-time are not too hard to understand:

  1. The prototype initialize constructor method sets references to the UI elements and initializes the DeviceControl and Google MapController.
  2. DeviceControl call-back methods mostly do simple things like update the status bar. The two non-trivial methods of are:
    1. onFinishFindDevices - loads connected device(s) into a choice widget and attaches a button event to trigger a readFromDevice call.
    2. onFinishReadFromDevice - reads all the data off the selected device, uses an instance of the Garmin.GpsDataFactory to obtain both the track and waypoint data and loads this data into choice widgets.
  3. The last section consists of strait-forward utility methods (all prefixed with _) for doing UI grunt work.

Using Google maps with Garmin GPS data is achieved by pointing a script reference to google.com, which contains a site-specific key (see http://www.google.com/apis/maps/signup.html to get your own) and a reference to the GoogleMapController.js, a utility for converting GPX data to GPolyline vectors among other handy things.

Step-By-Step

  1. Paste this code into a file named google.html
  2. If your going to host this somewhere other than localhost, you'll need your own google map key.
  3. Load this page in a browser and press Find Devices.
  4. Press Read From Device to load the location data off the GPS - this may take a moment.
  5. Once the data is loaded tracks are displayed on the left and waypoints are diplayed on the right.
  6. Select a track from the drop-down list and it will be overlaid on the Google map, sized to fit the data.
  7. Likewise select a waypoint from the drop-down list to see its location on the Google map.
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <title>Overlay Track Data on a Google Map</title>
    </head>
    <style type="text/css" media="all">@import "apidemo/garminGpsControlAPIDemo.css";</style>
    <script src="http://maps.google.com/maps?file=api&v=2.69&key=ABQIAAAAkOp4960CVjgwg7aH_RVbsBQ8mFNy8mluGNJxasFfpjfy_rK2-hTqlIAT8DmZDqe108rJCva4VdWiGA" type="text/javascript">&#160;</script>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js">&#160;</script>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js">&#160;</script>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js">&#160;</script>
    <script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GoogleMapController.js">&#160;</script>
    <script type="text/javascript">
        var GarminDeviceControlDemo = Class.create();
        GarminDeviceControlDemo.prototype = {
    
            ////////////////////////////////////////////////////////////////////////
            //prototype constructor method:
            
            initialize: function(statusDiv, mapId) {        
                this.status = $(statusDiv);
                this.mc = new Garmin.MapController(mapId);       
                this.findDevicesButton = $("findDevicesButton");
                this.cancelFindDevicesButton = $("cancelFindDevicesButton");
                this.deviceSelect = $("deviceSelect");
                this.deviceInfo = $("deviceInfoText");
                this.readDataButton = $("readDataButton");
                this.cancelReadDataButton = $("cancelReadDataButton");
                this.readTracksText = $("readTracksText");
                this.readTracksSelect = $("readTracksSelect");
                this.readWaypointsSelect = $("readWaypointsSelect");
                this.progressBar = $("progressBar");
                this.progressBarDisplay = $("progressBarDisplay");
                this.garminController = null;
                this.tracks = null;
                this._intializeController();
                this._setStatus("Plug-in initialized.  Find some devices to get started.");
                this.findDevicesButton.disabled = false;
                this.findDevicesButton.onclick = function() {
                    this.findDevicesButton.disabled = true;
                    this.cancelFindDevicesButton.disabled = false;
                    this.garminController.findDevices();
                }.bind(this)
            },
            
            ////////////////////////////////////////////////////////////////////////
            //Garmin.DeviceControl call-back methods:
    
            onFinishFindDevices: function(json) {
                this.findDevicesButton.disabled = false;
                this.cancelFindDevicesButton.disabled = true;
    
                if(json.controller.numDevices > 0) {
                    var devices = json.controller.getDevices();
                    this._setStatus("Found " + devices.length + " devices.");
    
                    this._listDevices(devices);
                            
                    this.cancelReadDataButton.onclick = function() {
                        this.readDataButton.disabled = false;
                        this.cancelReadDataButton.disabled = true;
                        this._hideProgressBar();
                        this.garminController.cancelReadFromDevice();
                    }.bind(this)
                            
                    this.readDataButton.disabled = false;
                    this.readDataButton.onclick = function() {
                        this.readDataButton.disabled = true;
                        this.cancelReadDataButton.disabled = false;
                        this._showProgressBar();
                        this.garminController.readFromDevice();
                    }.bind(this)
    
                } else {
                    this._setStatus("No devices found.");
                }
            },
    
            onStartFindDevices: function(json) {
                this._setStatus("Looking for connected Garmin devices");
            },
    
            onCancelFindDevices: function(json) {
                this._setStatus("Find cancelled");
            },
    
            onProgressReadFromDevice: function(json) {
                this._updateProgressBar(json.progress.getPercentage());
                this._setStatus(json.progress);
            },
        
            onCancelReadFromDevice: function(json) {
                this._setStatus("Read cancelled");
            },
    
            onFinishReadFromDevice: function(json) {
                this.readDataButton.disabled = false;
                this.cancelReadDataButton.disabled = true;
                this._hideProgressBar();
                this._setStatus("Data read from device.");
    
                var gpsData = json.controller.gpsData;
            
                this._setStatus("Parsing track data...");
                var factory = new Garmin.GpsDataFactory();
                factory.parseGpxDocument(gpsData);
                this.tracks = factory.getTracks();
                this.waypoints = factory.getWaypoints();
                this._setStatus(this.tracks.length + " tracks and " + this.waypoints.length + " waypoints found");
            
                this._listTracks(this.tracks);
                this._listWayPoints(this.waypoints);
            },
        
            ////////////////////////////////////////////////////////////////////////
            //internal utility methods:
    
            _intializeController: function() {
                try {
                    this.garminController = new Garmin.DeviceControl();
                    this.garminController.unlock("http://mydomain.com","pasteYourKeyInHere");
                    this.garminController.register(this);
                } catch (e) {
                    this._setStatus(e.message);
                }
            },
    
            _showProgressBar: function() {
                Element.show(this.progressBar);
            },
    
            _hideProgressBar: function() {
                Element.hide(this.progressBar);
            },
    
            _updateProgressBar: function(value) {
                var percent = (value <= 100) ? value : 100;
                this.progressBarDisplay.style.width = percent + "%";
            },
    
            _listDevices: function(devices) {
                for( var i=0; i < devices.length; i++ ) {
                    this.deviceSelect.options[i] = new Option(devices[i].getDisplayName(),devices[i].getNumber());
                    if(devices[i].getNumber() == this.garminController.deviceNumber) {
                        this.deviceSelect.selectedIndex = i;
                        this._showDeviceInfo(devices[i]);
                    }
                }
                this.deviceSelect.onchange = function() {
                    var device = this.garminController.getDevices()[this.deviceSelect.value];
                    this.showDeviceInfo(device);
                    this.garminController.setDeviceNumber(this.deviceSelect.value);
                }.bind(this)
                this.deviceSelect.disabled = false;
            },
    
            _showDeviceInfo: function(device) {
                this.deviceInfo.innerHTML = "Part Number:\t\t" + device.getPartNumber() + "\n";
                this.deviceInfo.innerHTML += "Software Version:\t" + device.getSoftwareVersion() + "\n";
                this.deviceInfo.innerHTML += "Description:\t\t" + device.getDescription() + "\n";
                this.deviceInfo.innerHTML += "Id:\t\t\t" + device.getId();
            },
    
            _listTracks: function(tracks) {
                this._clearTracks();
                for( var i=0; i < tracks.length; i++ ) {
                    var trk = tracks[i];
                    if(trk.isDrawable()) {
                        this.readTracksSelect.options[i] = new Option(trk.getStartDate() + " - (" + trk.getDuration() + ")",i);
                    }
                }
                this._displayTrack(tracks[this.readTracksSelect.selectedIndex]);
                this.readTracksSelect.onchange = function() {
                    var trk = this.tracks[this.readTracksSelect.selectedIndex];
                    this._displayTrack(trk);
                }.bind(this)
                this.readTracksSelect.disabled = false;
            },
        
            _listWayPoints: function(waypoints) {
                this._clearWayPoints();
                for( var i=0; i < waypoints.length; i++ ) {
                    var wpt = waypoints[i];
                    this.readWaypointsSelect.options[i] = new Option(wpt.getName(),i);
                }
                this.readWaypointsSelect.onchange = function() {
                    var wpt = this.waypoints[this.readWaypointsSelect.selectedIndex];
                    this._displayWayPoint(wpt);
                }.bind(this)
                this.readWaypointsSelect.disabled = false;
            },
        
            _clearTracks: function() {
                for( var i=0; i < this.readTracksSelect.options.length; i++ ) {
                    this.readTracksSelect.options[i] = null;
                }
            },
    
            _clearWayPoints: function() {
                for( var i=0; i < this.readWaypointsSelect.options.length; i++ ) {
                    this.readWaypointsSelect.options[i] = null;
                }
            },
    
            _displayTrack: function(track) {
                this.mc.map.clearOverlays();
                this.mc.centerAndScale(track.getStartLat(), track.getStartLng());
                this.mc.addTrack(track);
            },
    
            _displayWayPoint: function(wpt) {
                this.mc.map.clearOverlays();
                this.mc.centerAndScale(wpt.getLat(), wpt.getLng());
                this.mc.addWayPoint(wpt);
            },
    
            _setStatus: function(statusText) {
                this.status.innerHTML = statusText;
            }
        };
    
        //display is created when HTML page is loaded
        var display;
            
        function load() {
            display = new GarminDeviceControlDemo("statusText", "readMap");
        }
    </script>
    
    <body onload="load()">
        
        <object id="GarminActiveXControl"
                style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0"
                classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5"> <object
                        id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin"
                        width="0" height="0"> </object> </object>
        
        <h2>Overlay Track Data on a Google Map</h2>
        
        <div id="actionStatus">
                <div id="statusText">Status Text</div>
        
                <div id="progressBar" style="display: none;" align="left">
                        <div id="progressWrapper"><div id="progressBarDisplay">&#160;</div></div>
                </div>
        </div>
        
        <div id="deviceBox">
                <input type="button" value="Find Devices" id="findDevicesButton" disabled="true" />
                <input type="button" value="Cancel Find Devices" id="cancelFindDevicesButton" disabled="true" />
        
                <br />
                <select name="deviceSelect" id="deviceSelect" disabled="true">
                        <option value="-1">No Devices Found</option>
                </select>
                <br />
                <textarea id="deviceInfoText" rows="3" cols="60"></textarea>
        </div>
        
        <div id="readBox">
                <input type="button" value="Read From Device" id="readDataButton" disabled="true" />
                <input type="button" value="Cancel Read From Device" id="cancelReadDataButton" disabled="true" />
                <br />
                <select name="readTracksSelect" id="readTracksSelect" disabled="true">
                        <option value="-1">No Tracks Found</option>
                </select>
                <select name="readWaypointsSelect" id="readWaypointsSelect" disabled="true">
                        <option value="-1">No Waypoints Found</option>
                </select>
                <div id="readMap" style="width:400px; height:400px;">&#160;</div>
        </div>
    
    </body>
    </html>

Upload a waypoint to a GPS device

Next-up, sending data back to a GPS device. This example consists of a text box that contains an example GPX file and a Write To Device button. As long as the text is valid GPX it will be accepted by the device so feel free to put your own data here. You can try this functionality out first on the API Demo page. The code is very similar to the last example and we'll leave it to you to read through it. Enjoy...

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Write GPX Data to Garmin GPS</title>
</head>
<style type="text/css" media="all">@import "apidemo/garminGpsControlAPIDemo.css";</style>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/prototype/prototype.js">&#160;</script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDevicePlugin.js">&#160;</script>
<script type="text/javascript" src="http://www.garmindeveloper.com/web/communicator-api-0.6/GarminDeviceControl.js">&#160;</script>
<script type="text/javascript">
    var GarminDeviceControlDemo = Class.create();
    GarminDeviceControlDemo.prototype = {

        ////////////////////////////////////////////////////////////////////////
        //prototype constructor method:
        
        initialize: function(statusDiv, mapId) {        
            this.status = $(statusDiv);
            this.findDevicesButton = $("findDevicesButton");
            this.cancelFindDevicesButton = $("cancelFindDevicesButton");
            this.deviceSelect = $("deviceSelect");
            this.deviceInfo = $("deviceInfoText");
            this.writeDataButton = $("writeDataButton");
            this.cancelWriteDataButton = $("cancelWriteDataButton");
            this.writeDataText = $("writeDataText");
            this.writeDataFilename = $("writeDataFilename");
            this.progressBar = $("progressBar");
            this.progressBarDisplay = $("progressBarDisplay");
            this.garminController = null;
            this.tracks = null;
            this._intializeController();
            this._setStatus("Plug-in initialized.  Find some devices to get started.");
            this.findDevicesButton.disabled = false;
            this.findDevicesButton.onclick = function() {
                this.findDevicesButton.disabled = true;
                this.cancelFindDevicesButton.disabled = false;
                this.garminController.findDevices();
            }.bind(this)
        },
        
        ////////////////////////////////////////////////////////////////////////
        //Garmin.DeviceControl call-back methods:

        onFinishFindDevices: function(json) {
            this.findDevicesButton.disabled = false;
            this.cancelFindDevicesButton.disabled = true;

            if(json.controller.numDevices > 0) {
                var devices = json.controller.getDevices();
                this._setStatus("Found " + devices.length + " devices.");
                this._listDevices(devices);
                
                this.cancelWriteDataButton.onclick = function() {
                    this.writeDataButton.disabled = false;
                    this.cancelWriteDataButton.disabled = true;
                    this._hideProgressBar();
                    this.garminController.cancelWriteToDevice();
                }.bind(this)
    
                this.writeDataButton.disabled = false;            
                this.writeDataButton.onclick = function() {
                    this.writeDataButton.disabled = true;
                    this.cancelWriteDataButton.disabled = false;
                    this._showProgressBar();
                    this.garminController.writeToDevice(this.writeDataText.value, this.writeDataFilename.value);
                }.bind(this);
            } else {
                this._setStatus("No devices found.");
            }
        },

        onStartFindDevices: function(json) {
            this._setStatus("Looking for connected Garmin devices");
        },

        onCancelFindDevices: function(json) {
            this._setStatus("Find cancelled");
        },

        //The device already has a file with this name on it.  Do we want to override?  1 is yes, 2 is no 
        onWaitingWriteToDevice: function(json) {    
            if(confirm(json.message.getText())) {
                this._setStatus('Overwriting file');
                json.controller.respondToMessageBox(true);
            } else {
                this._setStatus('Will not be overwriting file');
                json.controller.respondToMessageBox(false);
            }
        },
    
        onProgressWriteToDevice: function(json) {
            this._updateProgressBar(json.progress.getPercentage());
            this._setStatus(json.progress);
        },
    
        onFinishWriteToDevice: function(json) {
            this._hideProgressBar();
            this._setStatus("Data written to the device.");
            this._hideProgressBar();
            this.writeDataButton.disabled = false;
            this.cancelWriteDataButton.disabled = true;
        },

    
        ////////////////////////////////////////////////////////////////////////
        //internal utility methods:

        _intializeController: function() {
            try {
                this.garminController = new Garmin.DeviceControl();
                this.garminController.unlock("http://mydomain.com","pasteYourKeyInHere");
                this.garminController.register(this);
            } catch (e) {
                if(e == "OutOfDatePluginException") {
                    alert("Plug-in out of date");
                } else if(e == "PluginNotInstalledException") { 
                    alert("Plug-in not installed");
                } else if(e == "BrowserNotSupportedException") { 
                    alert("Browser not supported");
                } else {
                    alert("Error initializing - " + e);
                }
            }
        },

        _showProgressBar: function() {
            Element.show(this.progressBar);
        },

        _hideProgressBar: function() {
            Element.hide(this.progressBar);
        },

        _updateProgressBar: function(value) {
            var percent = (value <= 100) ? value : 100;
            this.progressBarDisplay.style.width = percent + "%";
        },

        _listDevices: function(devices) {
            for( var i=0; i < devices.length; i++ ) {
                this.deviceSelect.options[i] = new Option(devices[i].getDisplayName(),devices[i].getNumber());
                if(devices[i].getNumber() == this.garminController.deviceNumber) {
                    this.deviceSelect.selectedIndex = i;
                    this._showDeviceInfo(devices[i]);
                }
            }
            this.deviceSelect.onchange = function() {
                var device = this.garminController.getDevices()[this.deviceSelect.value];
                this._showDeviceInfo(device);
                this.garminController.setDeviceNumber(this.deviceSelect.value);
            }.bind(this)
            this.deviceSelect.disabled = false;
        },

        _showDeviceInfo: function(device) {
            this.deviceInfo.innerHTML = "Part Number:\t\t" + device.getPartNumber() + "\n";
            this.deviceInfo.innerHTML += "Software Version:\t" + device.getSoftwareVersion() + "\n";
            this.deviceInfo.innerHTML += "Description:\t\t" + device.getDescription() + "\n";
            this.deviceInfo.innerHTML += "Id:\t\t\t" + device.getId();
        },
    
        _setStatus: function(statusText) {
            this.status.innerHTML = statusText;
        }
    };

    //display is created when HTML page is loaded
    var display;
        
    function load() {
        display = new GarminDeviceControlDemo("statusText", "readMap");
    }
</script>

<body onload="load()">

<object id="GarminActiveXControl" style="WIDTH: 0px; HEIGHT: 0px; visible: hidden" height="0" width="0" classid="CLSID:099B5A62-DE20-48C6-BF9E-290A9D1D8CB5">
        <object id="GarminNetscapePlugin" type="application/vnd-garmin.mygarmin" width="0" height="0"> </object>
</object>

<h2>Write GPX Data to Garmin GPS</h2>

<div id="actionStatus">
    <div id="statusText">Status Text</div>

    <div id="progressBar" style="display: none;" align="left">
        <div id="progressWrapper"><div id="progressBarDisplay">&#160;</div></div>
    </div>
</div>

<div id="deviceBox">
    <input type="button" value="Find Devices" id="findDevicesButton" disabled="true" />
    <input type="button" value="Cancel Find Devices" id="cancelFindDevicesButton" disabled="true" />

    <br />
    <select name="deviceSelect" id="deviceSelect" disabled="true">
        <option value="-1">No Devices Found</option>
    </select>
    <br />
    <textarea id="deviceInfoText" rows="3" cols="60"></textarea>
</div>

<div id="writeBox">
    <input type="button" value="Write To Device" id="writeDataButton" disabled="true" />
    <input type="button" value="Cancel Write To Device" id="cancelWriteDataButton" disabled="true" />
    <br />
    Filename: <input type="text" id="writeDataFilename" value="test.gpx"><br />
    Write Contents:<br /> 
    <textarea id="writeDataText" name="writeDataText" rows="21" cols="75">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="mymy">
        <metadata>
                <link href="http://www.garmin.com">
                        <text>Garmin International</text>
                </link>
                <time>2006-12-23T02:02:36Z</time>
        </metadata>
        <wpt lat="37.778721" lon="-122.414819">
                <name>Burger King</name>
                <desc>1200 Market St
San Francisco, CA 94102</desc>
                <sym>Fast Food</sym>
        </wpt>
        <wpt lat="37.867791" lon="-122.499298">
                <ele>19.35</ele>
                <name>Motionbased</name>
                <sym>Waypoint</sym>
        </wpt>
</gpx>
    </textarea>
</div>

</body>
</html>