Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Create a Google Maps JavaScript Plugin in restdb.io

DZone's Guide to

How to Create a Google Maps JavaScript Plugin in restdb.io

Let's see how to develop a plugin for RestDB by way of an example. This is a new feature of RestDB so you won't want to miss this.

· Database Zone ·
Free Resource

RavenDB vs MongoDB: Which is Better? This White Paper compares the two leading NoSQL Document Databases on 9 features to find out which is the best solution for your next project.  

RestDB recently announced support for developing client-side JavaScript plugins. Plugins let you override and enhance existing functions in your database admin application.

Plugins are perfect tools to enrich and improve your data admin user interface with custom widgets and new functionality.

In this tutorial, we'll show how you can create a Google Maps plugin widget. The plugin will display a map of a particular street address in a database.

The final result will look something like the screenshot below:final result of a google maps plugin

Before you can start writing your first plugin, let's cover the most important basics of writing a plugin.

The Basic Plugin Concepts

A RestDB plugin is a client-side API that you can call to "hook" your own JavaScript functions into various points of the standard data admin application.

You edit your plugins in Developer Mode by navigating to the plugin code editor from the database top menu, as shown in the example below.

plugin code editor

The Plugin API

The generic format to add a plugin is shown in the following code snippet:

// load an external JS library
plugins.loadScript(url, () => {
    // the JS library is loaded
});

// register a plugin hook
plugins.register("[plugin-hook-string]", (parameters...) => {
    // your plugin code here
})

The plugin API has the following available plugin hooks:

Plugin hooks Description Function parameters
list-view-row-renderer Change row style (rowdata, context)
list-view-cell-renderer Change cell style (celldata, context)
detail-view-field-renderer Access DOM object (fielddata, context)
detail-view-layout Change layout and add virtual fields (recorddata, context)
record-preview Change default data previews (recorddata, context)
lookup-select Override lookup (relation) query, filter, item display (context)
lookup-field Change a records' lookup/relation display (context)

Standard Libraries Available From a Plugin

The RestDB client application uses the following standard libraries, so you don't need to (and should not) load any of these to use in your plugin code.

  • Bootstrap 3.3.6
  • jQuery 2.10
  • jQuery UI - 1.10.4
  • lodash 3.0.1

Loading Your Plugin

Whenever a client uses the data admin application, all plugin code is loaded into the browser session. The actual plugin is called based on the hook-string.

For example, when the client is about to render an input field, it checks to see if there are any plugins registered on the detail-view-field-renderer hook. If so, your plugin gets called and is consequently given control over how a field gets rendered.

Testing and Debugging Your Plugin

Your plugin is dynamically loaded after the RestDB client starts. And since your plugin is not actually a JavaScript file, it can be a bit tricky to locate in the browser debugger. However, by adding a console.log("..."); statement in your plugin code, you can start the debugger by clicking on the output line in the browser Console window.

console.log

Clicking on the output line (VM4197:6) starts the debugger right into your plugin code.

An example debugging session screenshot is shown below:

debugging plugin code

With the basic plugin development workflow covered, let's move on to create an actual plugin that does something useful: a Google Maps plugin for street addresses in our database.

Create a Google Maps Developer API Key

The Google Maps API is a bit strict and you need to register for an API key to use the APIs. Head over to the Google Maps developer site and create a new API key for your project. Copy the API key. You'll need to add this to the code later.

Google maps apikey

Click on the GET A KEY button and select or create a project. Then, you should receive a unique API key for your project:

the apikey

Initialize Your Plugin

With the new API key from Google Maps copied to your clipboard, we can start by initializing our plugin, first by creating a variable for the API key and then loading the Google Maps JavaScript library.

const GOOGLE_API_KEY = "YOUR-API-CODE-HERE";

plugins.loadScript(`https://maps.googleapis.com/maps/api/js?key=${GOOGLE_API_KEY}`);

Now, we need to register the plugin as a hook for the field renderer. In this example, we want the map plugin to execute on the People collection and on the Address input field. We use the context parameter to get the collection name and we use the field parameter (JQuery.find) to check if the current field is the Addressfield we want. We then fetch the actual text address from that field and this will be used to initialize a Google Map for that location.

plugins.register("detail-view-field-renderer", (field, context) => {
    if (context.collection === "people" && field.find("input[name='Address']").length > 0) {
        const address = field.find("input[name='Address']").val();
    }
});

After retrieving the address, we also need to add a content element for the Google Map component. The code example used jQuery to append an empty div element with an id="map". This will be the element that Google Maps uses to inject the map component.

field.find("input[name='Address']")
        .closest(".form-group")
        .append('<div class="container col-md-12"><div id="map" >loading map ...</div></div>');

Adding a Google Map With a Marker

To place a marker for an address, we need to use an additional API from Google Maps: the google.maps.Geocoder API.

Geocoding is the process of converting addresses (i.e. 1600 Amphitheatre Parkway, Mountain View, CA) into geographic coordinates (i.e. latitude 37.423021 and longitude -122.083739), which you can use to place markers or position the map.

We create a helper function to initialize Google Maps with a default position, zoom level, and DOM element. We wrap the function in a setTimeout to ensure that the page has been loaded properly

const initMap = (cb) => {
    setTimeout(() => {
        var geocoder = new google.maps.Geocoder();
        var latlng = new google.maps.LatLng(-34.397, 150.644);
        var mapOptions = {
          zoom: 10,
          center: latlng
        }
        var map = new google.maps.Map(document.getElementById('map'), mapOptions);
        cb(map, geocoder);
    }, 1000);
}

When the plugin code executes and renders our Address field, we can finally call the helper code and place a marker for the Address value.

initMap((map, geocoder) => {
        geocoder.geocode( { 'address': address}, (results, status) => {
                if (status == 'OK') {
                        map.setCenter(results[0].geometry.location);
                        var marker = new google.maps.Marker({
                                map: map,
                                position: results[0].geometry.location
                        });    

                } else {
                        console.log('Geocode was not successful for the following reason: ' + status);
                }
        });
});

That's all there is to it — just a few lines of JavaScript code to add Google Maps to any address input field in your admin application.

The complete plugin code is shown below:

/*
* A restdb.io Plugin demo using Google maps.
*/

console.log("My plugin starts");

const GOOGLE_API_KEY = "YOUR-API-CODE-HERE";

plugins.loadScript(`https://maps.googleapis.com/maps/api/js?key=${GOOGLE_API_KEY}`);

const initMap = (cb) => {
    setTimeout(() => {
        var geocoder = new google.maps.Geocoder();
        var latlng = new google.maps.LatLng(-34.397, 150.644);
        var mapOptions = {
          zoom: 10,
          center: latlng
        }
        var map = new google.maps.Map(document.getElementById('map'), mapOptions);
        cb(map, geocoder);
    }, 1000);
}

// register the Plugin in restdb.io

plugins.register("detail-view-field-renderer", (field, context) => {
    if (context.collection === "people" && field.find("input[name='Address']").length > 0) {
        const address = field.find("input[name='Address']").val();
        field.find("input[name='Address']")
        .closest(".form-group")
        .append('<div class="container col-md-12"><div id="map" >loading map ...</div></div>');
        initMap((map, geocoder) => {
            geocoder.geocode( { 'address': address}, (results, status) => {
                if (status == 'OK') {
                    map.setCenter(results[0].geometry.location);
                    var marker = new google.maps.Marker({
                        map: map,
                        position: results[0].geometry.location
                    });    

                } else {
                    console.log('Geocode was not successful for the following reason: ' + status);
                }
            });
        });

    }  
})

The detailed view with our plugin:

the plugin result

Summary

This post has demonstrated the powerful concept of RestDB JavaScript plugins. They let you enhance and change the default behavior and look of the data client.

The Google Maps API contains awesome functions for displaying and interacting with map data. One logical next challenge could perhaps be; to create a search-as-you-type plugin by using the Autocomplete API.

Links:

Get comfortable using NoSQL in a free, self-directed learning course provided by RavenDB. Learn to create fully-functional real-world programs on NoSQL Databases. Register today.

Topics:
database ,tutorial ,restdb ,javascript ,api ,google maps ,plugins

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}