Wednesday, November 25, 2015

Google Maps for Webcenter Portal 12c


Recently I received the requirement to implement a task flow that presents a map using Google Maps API and it should be compatible with Webcenter Portal 12c. After some research on the internet I found Jay’s article on how to integrate ADF and Google Maps v3. It was a nice start since I was also using version 3 of the maps API but I would still need to adapt his solution for my requirements.

So I started creating a bounded task flow, adding a view, I pasted his code on it and started to adapt it. First problem I had to fix was how Google Maps API was being loaded. The original API loading was:

<af:resource type="javascript" source="https://www.google.com/jsapi?key=[API Key]"/>


While there is nothing wrong with the way Jay coded, and it will work just fine for a pure Fusion Web Application or while you are testing it locally on your Jdeveloper, it will not work for Portal 12c. It will error out as soon as you add the task flow to a page on Composer and you will no longer be able to access the page on view/edit mode.

In order to solve this, change the way the Google Maps API is loaded. The fragment code now is the following:

<?xml version='1.0' encoding='UTF-8'?>
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
   <af:group id="g11">
      <div id="map" style="width: 800px; height: 800px"></div>
      <af:resource type="javascript"
            source="https://maps.googleapis.com/maps/api/js?key=[API KEY]"/>
      <af:resource type="javascript">
         function initialize() {
            map = new google.maps.Map(document.getElementById('map'), 
            {
               center : {
                  lat : 51.507, lng : - 0.127
               },
            zoom : 8
            });
         }
      </af:resource>
   </af:group>
</ui:composition>


Changing the source of the API also forced me to change the way the map is initialized. If we use a more traditional approach of using a clientListener to call the initialization JavaScript method once the page is loaded, we will face another issue with Webcenter Portal Composer where you would be able to see the map on the page that contains your task flow, but would not be allowed to enter in edit mode.

The solution is to implement a Controller class for our fragment that will call the initialization JavaScript during the appropriate phase. Start by creating a new class that implements RegionController class.



After created, change the refreshRegion method to call a custom method that will trigger the JavaScript call, as shown below.

@Override
    public boolean refreshRegion(RegionContext regionContext) {
        int refreshFlag = regionContext.getRefreshFlag();
        if (refreshFlag == RegionBinding.PREPARE_MODEL) {
            this.initializeMethod();
        }
        regionContext.getRegionBinding().refresh(refreshFlag);
        return false;
    }
   
    public void initializeMethod() {
        String language = JSFUtils.resolveExpression("#{pageFlowScope.language}").toString();
        FacesContext fctx = FacesContext.getCurrentInstance();
        ExtendedRenderKitService erks = Service.getRenderKitService(fctx, ExtendedRenderKitService.class);
        erks.addScript(fctx, "initialize('"+ language +"');");
    }

Next thing to do is to add the new class as the controller on the page definition of our fragment which should look like the following:

<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel" version="12.2.1.0.31" id="sampleMapPageDef"
                Package="fragments" ControllerClass="mapssample.view.SampleMapController">
After that we are done, just deploy your task flow as a shared library and it will be ready to be used in your Webcenter Portal 12c environment.




No comments:

Post a Comment