In our previous examples, we had seen how to load FusionMaps in your Flash movies in a very basic way. In this advanced example, we'll assimilate all the information that you've gained from previous examples and use that with new concepts to create an interactive form based mapping application. We'll build a form that takes in continent-wise sales information and then plot it on a World Map.

This application explains the following new concepts pertinent to FusionMaps:

  1. Using FusionMaps with data received in forms.
  2. Showing map on-demand
  3. Hiding a map when not required
  4. Removing and re-initializing a map.
  5. Updating an existing map with new data.

If you're excited after just reading the possibilities above, let's inspire you more by showing how the application would look when it's finished:

Initial state of the application, where the user enters sales data.

Final map generated when the user enters requisite data and then clicks on "Plot It" button.

Now that you're already jumping, let's straight jump into action.

 
Setting the movie

For this example, we'll create a new .fla and name it as FormExample.fla. We keep it under the same FlashExamples folder so that we do not have to make additional copies of com folder.

In this application, we've three states.

  1. Initialization State - This is an invisible state for the user. In this state, we create an instance of the WorldMap class and convey the initialization parameters.
  2. Form State - This is the first visible state for the user. In this state, we show the data-entry form to the user. Internally, we update the form fields with default data. We also handle the click event for form's submit button.
  3. Map State - In this state, we request the data submitted by the user, create an XML data document out of it and then show it as a map.

Each state is represented by a key-frame as shown below. The name of state keyframes are FInit, FForm and FMap respectively. Shown below is a screenshot:

As you can see above we've following additional layers in this movie:

  • Background layer contains the oval background shared by form and map.
  • Form layer contains the form elements which we'll soon visit. The form elements are visible only in frame 1 and 2, as the 3rd frame shows the map.
  • Back Button layer contains a button used by the user to get back to form when viewing the map. As such, it's present only in the 3rd frame.
  • Actions Layer contains actions to initialize map, initialize form and then render map
Setting the form
The form for this application looks as under. We've 6 text fields on this form to accept data for 6 continents. Apart from that, it also contains a few descriptive labels.
 
Binding Actions
Let's now switch our focus to the core of this application - ActionScripts which bind the entire application. We'll study the ActionScripts frame by frame. Let's first see the ActionScript contained in frame 1:

/**
* In this frame, we initialize the map object.
* We initialize it only once but re-use it multiple times
* later.
*/
//You first need to include the following two files in your movie.
//These two files contain pre-loading functions and application
//messages for the map.

#include "com/fusionmaps/includes/LoadingFunctions.as"
#include "com/fusionmaps/includes/AppMessages.as"

//Import the Class of the map which you want to create.
import com.fusionmaps.maps.WorldMap;

//Create container movie clip for map
var mapContainerMC:MovieClip = this.createEmptyMovieClip("MapHolder", 1);
//Initialize map object.
var salesMap:WorldMap = new WorldMap(mapContainerMC, 1, 450, 290, 20, 15, false, "EN", "noScale", false, "");
//Goto next frame
gotoAndStop("FForm");

In this frame, we're basically including and importing the required files for map. We're also creating the empty movie clip for the map and then instantiating the WorldMap. The actions in this frame run only once during the entire application. So, we're effectively creating only one instance of WorldMap. We'll be updating the same instance with new data as and when the user changes the data in form.

Let's see the code that runs the form in frame 2:

/**
* This frame is an application state which contains the input form
* for the user.
*/
//Restrict text fields to accept only numeric values
txtNA.restrict = "0-9";
txtSA.restrict = "0-9";
txtEU.restrict = "0-9";
txtAS.restrict = "0-9";
txtAF.restrict = "0-9";
txtAU.restrict = "0-9";

//Set default values for text fields - just for demo.
txtNA.text = "108124";
txtSA.text = "162346";
txtEU.text = "36766";
txtAS.text = "171453";
txtAF.text = "99235";
txtAU.text = "184655";

//Define the listener for "Plot" button's click event.
var btnListener:Object = new Object();
btnListener.click = function() {
    //When the plot button is clicked, we need to generate XML document
    //from data provided in form fields.

    //Build the XML data and convey it to map

    var strXML:String= "<map bgAlpha='0' showCanvasBorder='0' includeNameInLabels='0' includeValueInLabels='1' baseFontSize='9' legendPosition='BOTTOM' legendShadow='0'>";
    //Define color range
    strXML = strXML + "<colorRange>";
    strXML = strXML + "<color minValue='0' maxValue='50000' displayValue='Low Sales Region' color='FF9377'/>";
    strXML = strXML + "<color minValue='50000' maxValue='100000' displayValue='Moderate Sales Region' color='FFFFCC' />";
    strXML = strXML + "<color minValue='100000' maxValue='10000000' displayValue='High Sales Region' color='A7E9BC' />";
    strXML = strXML + "</colorRange>";

    //Add data to it
    strXML = strXML + "<data>"
    strXML = strXML + "<entity id='NA' value='" + txtNA.text + "' />";
    strXML = strXML + "<entity id='SA' value='" + txtSA.text + "' />";
    strXML = strXML + "<entity id='EU' value='" + txtEU.text + "' />";
    strXML = strXML + "<entity id='AS' value='" + txtAS.text + "' />";
    strXML = strXML + "<entity id='AF' value='" + txtAF.text + "' />";
    strXML = strXML + "<entity id='AU' value='" + txtAU.text + "' />";
    strXML = strXML + "</data>"
    strXML = strXML + "</map>";
    //Convey the XML data to map.
    salesMap.setXMLData(new XML(strXML));
    //We draw the map on next frame. So, go there.
    gotoAndStop("FMap");
};
//Attach the event listener to button.
btnPlot.addEventListener("click", btnListener);

//Stop till an action is invoked.
stop();

Here, we're:

  1. Restricting the form text fields to accept only numeric data
  2. Setting some default values for them (for demonstration purpose only)
  3. Defining the event listener for "Plot it" button
  4. In the click event listener handler, we create an XML data document out of data specified by the user in the form. We store the data in strXML variable.
  5. We convey this XML data to map using setXMLData() method.
  6. Finally, we send the control to FMap frame, which contains the code to render the map.

In FMap frame, we've the following actions:

/**
* We actually draw the map in this frame.
*/
//Show the map container.

mapContainerMC._visible = true;
//Draw the map
salesMap.render();

//Define the listener for back button's click event.
var btnListener:Object = new Object();
btnListener.click = function(){
    //Re-initialize the map, so that user can plot again
    //as we're allowing the user to go back to form and then
    //map the data again.

    salesMap.remove();
    salesMap.reInit();
    //Hide the map container so that it doesn't overlap form.
    mapContainerMC._visible = false;

    //Goto the form
    gotoAndStop("FForm");
}
//Add event listener
btnBack.addEventListener("click",btnListener);
stop();

In the above code, we're first setting the visibility of map container movie clip (mapContainerMC) to true. If this application is running for the first time, the visibility of this movie clip is already true. However, if the user has viewed the map once, then updated data in form and then clicked "Plot it" button, the container for map is hidden by us. So, we set it to visible again.

Thereafter, we straight render the map by calling render() method on salesMap object (which is an instance of WorldMap class). The XML data was already conveyed to map in previous frame.

We also define the event listener for "Back" button. In this handler, we're first removing the map using remove() method of this map. This method removes all the items in the map (barring logger). The map still stays in the memory though. remove() method is used when you want to use the same map object again in your movie to plot another map. Since we intend to re-use the map object to plot the data again, we call the remove() method. After the remove() method, we ask the map to re-initialize by calling the reInit() method. This method prepares the map to accept new data and be able to render again. reInit() method should always be called after remove() method of the map, if you intend to use the map object to plot another map.

If you need to destroy the map altogether (when you do not need to plot any other maps using the same object), you should call the destroy() method of map. e.g., salesMap.destroy(). This method removes all the associated movie clips, listeners, events and data containers for the map.

We also hide the container movie clip for the map, as that's not required in the Form visible state. Finally, we go back to the form state of the application.

When you now run the application, you'll get the desired results (as shown above). This example demonstrates all the features that you can attain when using FusionMaps within your Flash movies.