Develop Your First Component

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.

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.

Get the Sample Code

The code for this sample plug-in is hosted on our GitHub repository.

  1. Fork the repo and create a local clone.
    • If you're not familiar with Git or don't care about maintaining your version history just download the repository to your development machine. Note: We highly recommend using a version control system for your own plug-ins, so it's better to use it from the start!
  2. The sample code is in the Component Plug-in (CP) Examples/mapField subfolder.

Design

Before getting into the code, let's review what this component should do and how Google's APIs make it possible:

  1. We want to show a map in an Appian interface.
  2. We'll be using the Google Maps JavaScript API to create the component.
  3. The Maps API uses an API key to track usage and billing. We'll need to specify the API key as an input to the component.
    • Security Note: It might seem like the API key should be encrypted or secured in some way, but since it's visible in every user's browser it's not considered sensitive. Instead, Google provides ways to restrict the key to ensure you can control where it's used.
  4. We want to set the initial location displayed by the map
    • We can use the 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.
  5. We want the set an initial pin location and allow the user to change the pin location by clicking on the map:
    1. The updated pin location will be available for designers to use in smart service functions or other components on the interface.
    2. User clicks can be captured using standard JavaScript event handlers (addListener) that provide a location of the click event.
    3. A pin can be created at that location using the 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!

API Key

Since we're using Google Maps, you'll need to register an account and get an API key for the Maps JavaScript API:

  1. Follow the instructions on Google's documentation to get an API key for the Maps API.
  2. Restrict your key by adding your developer instance's dynamic content domain to the list of HTTP referrers (web sites) (For example: http://local.example-dynamic.com:8080)

You'll use this API key later when using your component in an interface.

Plug-in Manifest

The component design above provides all the detail necessary to define the component and its parameters in the appian-component-plugin.xml manifest file:

  1. A component called mapField with an initial 1.0.0 version.
  2. An input-only parameter named key for providing the API key
  3. An input-only parameter named location for setting the initial location.
  4. An 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:

  1. Change the plug-in key to a value that includes your organization's URN prefix (e.g.: com.example.map)
  2. Change the vendor name and url to appropriate values for your organization
  3. Decide whether your organization will provide formal support for this plug-in (since this is a sample, probably not!). Then update the support fields to reflect your choice and specify support contact options (phone, email, or website url).

Code

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.

map.css

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;
}

index.html

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.

Internationalization Bundles

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.

  1. Add support for a second language by copying mapField\_en\_US.properties to a new file named mapField_es.properties (es is the Appian language code for Spanish (Mexico))
  2. Translate the properties in mapField_es.properties into Spanish. For example:
    1. Map –> Mapa
    2. 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:

  1. Edit appian-component-plugin.xml
  2. Replace the <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-* elements

Package and Deploy

  1. Create a ZIP with the contents of your plug-in and name the file mapField-1.0.0.zip
    1. Make sure the root of the ZIP file contains appian-component-plugin.xml and the mapField component folder.
  2. Copy your plug-in ZIP into the <APPIAN_HOME>/_admin/plugins/ folder of your developer instance.
  3. Wait 60 seconds.
  4. Open the Plug-Ins page in the Administration Console (For example: http://myappiansite.com/suite/admin/page/plugins)
    1. Your plug-in should appear in the list of deployed plug-ins.

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.

Test

Once your plug-in is successfully deployed:

  1. Log in to Appian Designer (For example: http://myappiansite.com/suite/design).
  2. Create a new interface.
  3. Find your component in the palette by searching or scrolling down to the Custom Components section.
  4. Click on the info icon next to your component and make sure the package details are correct (your organization information, support contacts, etc.).
  5. Drag your component onto the palette and use the design pane to configure it:
    1. Set the API key using the key you created earlier
    2. Set an initial location using an address, location, or coordinates. For example: the white house
  6. The map should render with the initial location
  7. Configure Pin Save Input To to populate a local variable, then display that value in a text field on the interface.
  8. Click around the map and see how the pin variable is updated each time.

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?

Debugging

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.

Next Steps

  1. Experiment with the sample code to explore what you can create with a component plug-in. Use the How To topics for ideas or try your own!
  2. Read the Core Concepts documentation to get a more complete understanding how component plug-ins work.
  3. Understand the Review Process and the guidelines for what types of components will be approved.
  4. Create your own plug-in, submit it for review, and get it listed on the AppMarket!
FEEDBACK