The page walks you through the development process for a sample plug-in that provides a Google Map component. Make sure you've already set up your developer instance.
Note: We review all component plug-ins to ensure they meet our standards for customer use. Check the review guidelines and get a pre-approval to make sure you're on the right track before starting your own component development.
The code for this sample plug-in is hosted on our GitHub repository.
Before getting into the code, let's review what this component should do and how Google's APIs make it possible:
google.maps.Geocoder
class to translate designer input into a location, and pass that location into the google.maps.Map
constructor to set the initial location.addListener
) that provide a location of the click event.google.maps.Marker
class.There are many more features of the Google Maps API that you might find useful in a map component. Once you've mastered the basics we encourage you to experiment with your component to explore the possibilities!
Since we're using Google Maps, you'll need to register an account and get an API key for the Maps JavaScript API:
http://local.example-dynamic.com:8080
)You'll use this API key later when using your component in an interface.
The component design above provides all the detail necessary to define the component and its parameters in the appian-component-plugin.xml manifest file:
mapField
with an initial 1.0.0
version.input-only
parameter named key
for providing the API keyinput-only
parameter named location
for setting the initial location.input-output
parameter named pin
for placing the initial pin and for capturing user click events.You just need to update the sample manifest to match your organization:
key
to a value that includes your organization's URN prefix (for example, com.example.map
)vendor
name
and url
to appropriate values for your organizationsupport
fields to reflect your choice and specify support contact options (phone
, email
, or website url
).The sample is very simple, consisting of just one HTML and one CSS file. You won't need to update these files to get your component running, but we'll review how the code uses a few component plug-in concepts.
This stylesheet sets the height of the map element. A preset height makes this a good fit for the AUTO height option when configuring the component in an interface. If the designer selects one of the fixed height options this sample isn't designed to adjust and instead will scroll or leave unused white space. Adding height adjustment would make this a better component.
1
2
3
4
5
html, body, #map-container {
height: 400px;
margin: 0;
padding: 0;
}
This HTML file serves as the html-entry-point for the component. All the HTML and JavaScript code for your component is in this file. In a more complicated example you'd probably want to use a separate JavaScript file or a JavaScript framework like React or jQuery.
We start by loading the stylesheet and the component plug-in client library:
1
2
3
4
<head>
<link rel='stylesheet' href='./map.css'></link>
<script src='APPIAN_JS_SDK_URI'></script>
</head>
Later, we define a function to handle new parameter values from the interface. This function starts by extracting values for the individual component parameters:
1
2
3
4
5
Appian.Component.onNewValue(function (newValues) {
newKey = newValues.key;
newLocation = newValues.location;
newPin = newValues.pin;
...
If the designer tries to use the component without an API key we set a validation message:
1
2
3
if (!(currentKey || newKey)) {
Appian.Component.setValidations('The API Key provided is empty. Please update the parameter "Google API Key" with a valid key.');
}
When setting the pin location as a result of a user clicking on the map, we save the new value back to the interface:
1
2
3
if (save) {
Appian.Component.saveValue('pin', currentPin);
}
There's a lot more to see in the code, so feel free to review it further before moving on.
The sample provides translations for the default en_US locale in mapField\_en\_US.properties
. Note the three properties used to define friendly names and description for the pin
parameter which uses the input-output
category.
mapField\_en\_US.properties
to a new file named mapField_es.properties
(es
is the Appian locale code for Spanish (Mexico))mapField_es.properties
into Spanish. For example:
Map
–> Mapa
Location
–> Localización
By adding this file your component will automatically use these translations when a viewed by a designer that has set their language to Spanish (Mexico).
Before wrapping up, personalize your component with a custom logo:
appian-component-plugin.xml
<icon-file>
element pointing to the Google Maps logo with a built in map icon <icon-name>map-o</icon-name>
, or pick your own icon using either of the two icon-* elementsmapField-1.0.0.zip
appian-component-plugin.xml
and the mapField
component folder.<APPIAN_HOME>/_admin/plugins/
folder of your developer instance.http://myappiansite.com/suite/admin/page/plugins
)
If you don't see your plug-in listed after 60 seconds, review the output of tomcat-stdOut.log
in <APPIAN_HOME>/logs
. You should see a message confirming that the plug-in has been successfully installed:
Successfully installed Component Plug-in 'Map Component Plug-in' (<your plug-in key>)
Instead you may see an error message like this:
Failed to load Component Plug-in '<your plug-in key>': mapField (1.0.0) - Could not read key "parameter.location.description" from properties file: mapField_en_US.properties
If you see an error, use the log message to help resolve the problem and redeploy the plug-in.
Once your plug-in is successfully deployed:
http://myappiansite.com/suite/design
).the white house
The following interface makes it easy to test the sample component. You'll need to update it if you make changes to the component design or parameters.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
load(
local!location: "the white house",
local!pin,
{
mapField(
label: "Map",
height: "AUTO",
key: "AIza...5vE4",
location: local!location,
pinValue: local!pin,
pinSaveInto: local!pin
),
a!textField(
label: "Location",
value: local!location,
saveInto: local!location
),
a!floatingPointField(
label: "Pin Latitude",
value: local!pin.lat,
saveInto: local!pin.lat
),
a!floatingPointField(
label: "Pin Longitude",
value: local!pin.lng,
saveInto: local!pin.lng
)
}
)
Test all the configuration options like setting the initial pin location. Make sure to test edge cases and validations too! What happens if you provide a poorly formatted Pin Value?
If you need to troubleshoot your component or just want to see what's happening behind the scenes, use the Chome Developer Tools console. More detail on how to use these tools is available from online tutorials.
Develop Your First Component