HTML script mashup – launched from an Embedded Component
Use Case
Sometimes, we may need to pull and pass parameters from an SAP screen to to a mashup. In some cases, the outport of the SAP screen may not have all the parameters you need to pass to the mashup. In such cases, you could introduce an embedded component to have a control over the outport parameters that should be passed to the mashup. This document talks about such a scenario.
Here, we take a simple example of launching Google Maps – as an HTML mashup
This document consists of 3 parts
Part A: Making the Embedded Component with an Inport to connect to the Opportunity TI Outport
Part B: Making the HTML Mashup and connecting to the Embedded component created in Part A
Part C: Pulling other parameters’ information from related Business Objects and associations
Part A:
Step1: Identify the Source Outport
For your embedded component, identify the source Outport that would give you the information you need.
In our example, since we have an Opportunity with a line item – which has a travel package Product called Delhi, we want to be able to display the location of Delhi in Google Map with a certain Latitude and Longitude. In our case, the Outport PublicOutportECOOpportunityItem gives us some information. What we need from here for our mashup are ItemUUID and Product ID. Other than these parameters, we also need Latitude and Longitude which will be defined in our custom BO.
Step 2: Create your custom BO and declare the other elements and actions you need
businessobject Url_mashup {
[AlternativeKey] element itemUUID:UUID; //Will be used for the EC Inport
element productId:NOCONVERSION_ProductID;
element urlparamz:LANGUAGEINDEPENDENT_MEDIUM_Text;
element urlparamt:LANGUAGEINDEPENDENT_MEDIUM_Text;
action fillparams;
Set the parameter values in the action definition. This could be hardcoded as constants in the Mashup as well, but this is to demonstrate that you could set values to parameters that you would want to pass to the mashup. Other non-hard-codeable values – like Sales Org ID – is an example which could be pulled through association.
Step 3: Get the information you need in the Embedded component from the Opportunity TI Outport
· Create an Embedded Component
· Bind the necessary fields
· Create an OBN structure and data fields within that. These will be used as Placeholders when the Outport-Inport Navigation from the TI to the EC takes place
· Create an Inport for the Embedded Component.
Add the parameters that you want to receive from the TI Outport. Apart from the obvious Product ID for our use case, we have the Item UUID here. Since this was declared as an Alternative key in our custom BO, it gives us a proper handle to the Line Item of the Opportunity. This can later be used if required in retrieving further information about the item and its related associations
· In the properties of the Inport, create a new Event Handler
Using this Event Handler, we create Operations, which control how the information is read from the Outport of the TI, and what further actions take place.
Using the Alternative Key Item UUID, we do a read Operation
If our Custom BO instance was not already created for the Opportunity Line Item that is selected, we would like to create that instance, so as to store the values we need. For this, we will create a new event handler and define it later.
Next, we would like to assign the values that we received into our Data Structure to our Data Elements – ie, Item UUID and Product ID
Now, we would like to assign values to the other elements declared in our BO – like z and t. We had already defined this in our Action fillparams(). Now, we would like to call this action..hence, the next Operation:
Now, we also define the event handler Create_Item as mentioned in the Script Operation
After Create(), we read the instance
Now, the Inport definition along with its Event Handlers are done. Let’s drag the Product ID, Z and T fields to the UI. (This is not really needed, but we could use it for testing and ensuring that the values coming to the EC Inport from the TI Outport are correct)
· Displaying the Embedded Component:
Now that the EC has been created we need to display it at the right place. In this example, since for each line selected, the travel package product would determine the Location that would be shown by the Google Maps url, we display the EC in a Pane container within the Product facet of the Opportunity TI. To do this, navigate to the Opportunity TI from the Configuration Explorer of the UI designer and edit it. This would open up the Extensibility Explorer. Identify the Pane where you want to embed the EC, and Choose “Add EC to Pane”
Binding information needs to be provided, hence specify the Outport of the TI and the Inport of your EC and bind the parameters
Save and Activate your solution and test to see whether you see the Product ID and other parameters in the embedded section of the Opportunity TI
PART B: HTML Mashup
You can follow the standard steps mentioned in the Studio documentation for creating an HTML mashup and adding to your floorplan. Below are snapshots to help you identify those steps
Step 1: Define Port Type Package
To create a mashup, you first define a Port Type Package which consists of a Port Type and the parameters you want the binding to be done for…
Step 2: Define the Port Binding.
Choose a Category that you would also use in the third step of creating a URL mashup. For the Package, choose the one created in the step above
Step 3: Create an Outport for your embedded Component.
This is where you control what parameters you want to pass to the mashup. Recall, that the Opportunity TI’s Outport cannot be enhanced, and for our usecase we needed more parameters. By introducing the Outport in our Embedded Component, we are able to achieve that.
Add parameters and bind them to the custom BO’s fields (recall that we had adjusted these fields in the action fillparams()
Step 4: Create an HTML mashup.
Choose the same Mashup Category as in step 2 above and the related Port Binding
Bind the parameters to the parameters of the Outport defined in step 3 above. By doing this,
we are ultimately passing values to the mashup from the values that are bound to the Outport of the EC, hence:
Note that here we have used the HTML Code option. This might be suitable when there are lots of values to be passed to the destination, much of which is also hard coded values…Below is the script that was used for this.
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name=”viewport” content=”initial-scale=1.0, user-scalable=no”>
<meta charset=”utf-8″>
<style> html, body, #map-canvas { height: 100%; margin: 0px; padding: 0px } </style>
<script src=”https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false“></script>
<script>
var map;
function initialize() {
//Test by outputting variables to the console..this ensures that your Outport-Inport bindings are
correct
document.write(“Hello World!”);
document.write(sap.byd.ui.mashup.context.inport.ParameterZ );
document.write( sap.byd.ui.mashup.context.inport.ParameterT);
var mapOptions = { zoom: 8, center: new google.maps.LatLng
(sap.byd.ui.mashup.context.inport.ParameterZ,sap.byd.ui.mashup.context.inport.ParameterT)
//(-34.397, 150.644) .. test using hard coded values if required
};
map = new google.maps.Map(document.getElementById(‘map-canvas’), mapOptions);
}
- google.maps.event.addDomListener(window, ‘load’, initialize);
</script>
</head>
<body>
<div id=”panel”>
</div>
<div id=”map-canvas”></div>
</body>
</html>
The text in bold above are the parameters that are being used instead of constants. These should hold the values passed to the mashup from the Outport of the Embedded component. To test whether the Inports have the correct values a simple statement like document.write would write to your screen the values that are there in the inport parameters.
In some cases, we might also have an HTML form along with the javascript. In this case, the form parameters cannot be directly assigned with the value as shown above, because it would be interpreted directly as a string. In this case, we should be able to assign the value to this id field later as part of the script..
Eg:
Code snippet from HTML form:
<input type=”hidden” id=”zoom” name=”zoom” value=”” >
<input type=”hidden” id=”mapType” name=”mapType” value=”” >
Note that there is an Id assigned, and the value is null. Later, in the javascript, we access this id, and assign a value to this using our context parameters.. eg:
Code snippet from javascript:
<SCRIPT LANGUAGE=”JavaScript” type=”text/javascript”>
document.getElementById(‘zoom’).value = sap.byd.ui.mashup.context.inport.ParameterZ;
document.getElementById(‘mapType’).value = sap.byd.ui.mashup.context.inport.ParameterT;
document.datapipe.submit();
</SCRIPT>
A handy feature to use for debugging the script is the Developer Tools that comes along with IE. Using F12, you can start the developer Tool, start debugging, and set a breakpoint anywhere in your code.. Another quick way to do this, is to write debugger; in your script where you want to check the values say.. eg: if you want to check the value of the inport parameters.. you could set a debugger; statement within your javascript and watch the inport parameters’ values
Step 5: Display Mashup
Now that the script is done, display the HTML mashup on your embedded component. For this, go back to your embedded component in the UI Designer.
Create an empty pane container by adding a row
Locate your mashup in the Configuration explorer and drag it to the Pane container as shown below
Click on Bind and Bind the Outport and Inport
Now that the binding is done, we need to display the mashup correctly. This relies on having the correct anchors. We basically need two things
· An anchor for the Outport itself
· An anchor for the Pane container and the Floorplan that would display it
For the outport anchor, click on the Outport from the controller tab, and create a new anchor as shown below
For the Pane container anchor, go to the Designer tab and select the Pane container in the properties window. Under the Anchor information, create a new anchor for the Pane Container
For the Floorplan anchor, select the Embedded Component option in the Properties Drop Downs and create an anchor as shown below
Now, in the Outport, add these 2 anchors as referenced anchors, and you’re done !!
Save and activate all.
Finally, you can test your mashup !! (Displayed in the attachment since i wasnt able to add more images in the blog 😉 )
Part C: Additional parameters from SAP BOs
As another variant of this scenario, if we want to pull other parameters from the SAP BOs, itself, we could do the following:
Example: We additionally need the Sales Org ID and the Distribution Channel information.
We declare additional elements in our Custom BO for the same:
[Label(“Sales Organisation”)] element salesOrg:OrganisationalCentreID;
[Label(“Distribution Channel”)] element distrChannel:DistributionChannelCode;
In our previously defined action fillparams(), We declare an association to be able to retrieve information for the same using the Item UUID handle we already have. we additionally assign values to these parameters using our association
association toItem to Opportunity.Item using UUID;
var itemInst = Opportunity.Item.Retrieve(this.itemUUID);
this.toItem = itemInst;
this.distrChannel.content = this.toItem.ToParent.SalesAndServiceBusinessArea.DistributionChannelCode.content;
this.salesOrg = this.toItem.ToParent.SalesAndServiceBusinessArea.SalesOrganisationID;
Once this is done, you need to adapt part B of the solution to be able to pass these new parameters as Outports of the EC, and receive them in the Inports of the mashup. Correct binding should be ensured.
Thank you Vinita for your time and all you efforts...:)
Such a very usefull blog for the us...:)
Hi Vinita,
Thanks, this is a very helpful article.
While following the steps I am facing an error in PartB Step5 "Display Mashup".
When I try to drag my Mashup Pipe to the screen the UI designer closes with an exception (screenshot below). Do you have any idea on why this migh be happening?
Warm Regards,
Manasi
Hi Manasi,
Havent encountered such an issue..were you able to resolve it ? If yes, could you tell us what was the issue ?
Kind Regards
Vinita
Hi Vinita,
I did not find an exact fix to my issue, but did a workaround.
I copied Access rights from Administration01 to my user.
A lot of work center assignments happened.
Not sure which work center was required, but I am able to drag the mashup now.
Warm Regards,
Manasi
Hi Vinita,
many thanks for your post. I tried the HTML mash up and it works perfectly.
Do you know how can I add a refresh button on the HTML mash up?
Thanks.
Cheers
Linh
Hi Linh,
You could perhaps try calling Reload method using Javascript ?
Have a Button control and call your function on its click ?
I havent tried it myself, but I guess it should be possible
Let me know if it works for you 🙂
Cheers !
Vinita
Thanks Vinita!!!!
It was a great idea, I'll try it and let you know.
Btw, I'm trying to show a list of address on the map and plan the route. Do you know how to bind not only one but multiple values of addresses to the outport?
Will it be an array? If not how can I check what type is it?
Many thanks.
Cheers
Linh
Hi Linh,
I would again suggest build an array using Javascript... As you loop through it, the current value would be what goes into the outport
Kind Regards
Vinita
Thanks for your suggestion.
Do you mean I should loop it in the step 3 create an Outport for your embedded component (from your article)? If so I don't know how to go to the point where I can integrate javascript code in it. Could you kindly explain these steps?
If you mean the I loop through the array on the user interface, then what outport should I choose?
Many thanks Vinita
Cheers
Linh
Hi Linh,
have you found a solution to your problem? I am facing quite a similar problem. I am having a bing map which is displaying mulitiple addresses from a table and now I don't know how to refresh my map in order to show my updated search results.
Thanks a lot in advance for your help.
Best regards,
Jan-Thomas
Hi Jan,
I found an solution after some tinkering. The problem for me was that I didn't have acces s to the javascript objects. The solution was that it wasn't possible to use all objects for all types of mashups. I am not sure what the easiest way is for you. Maybe you could use an ajax poller to load data from the table and redraw the map if any check value in the response have been changed.
Hopefully this was some help for you if you have any further questions let me know.
/ Anton
Hi Anton,
thanks for your reply. I just solved my problem this morning.
What I did is firing the outport once I click on my search button and In addition to that I added a setIntervall function in my javascript code to make sure my pushpins are being updatet every second.
Best regards,
Jan-Thomas
Hi Vinita! Great Tutorial, maybe you want to add some tags to your post so that it will be visible in our how-to collections: How-To Collection for SAP Cloud Applications Studio
Like:
cloudstudio_howto_usecase
cloudstudio_howto_ui
cloudstudio_howto_other
Cheers,
Jens
Thanks, Jens,
Did that now !!
Regards,
Vinita
Hi Vinita,
thanks for this tutorial! Unfortunately I am struggling in my html mashup with reading the inport parameters. It would be great, if you could have a look at my issue.
Here my example:
I used the copy-function to get access to the parameter and entered a sample value (see screenshot).
Shortened Code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Stopwatch</title>
</head>
<script type="text/javascript">
function startandstop()
{
document.getElementById('inputParam').value = sap.byd.ui.mashup.context.inport.WarrantyID; //value is not read
//document.getElementById('inputParam').value = "test"; //this works
}
</script>
<body onload="startandstop();" >
<input class="stopwatch" id="inputParam" type="text" style="color:sienna;margin-left:20px;"><br>
</body>
</html>
When executing "Preview" or "Update Parameter Values" the Sample Value is not read.
Do you have any advice how to achive reading the inport value correctly?
Thanks and best regards
Tom
Hi,
I am trying to add an mashup based on an html widget that loads the ERP account id from the current selected account and passes it as an argument to an iFrame.
I have written the following JavaScript that works if i use the preview function. But when I am adding the mashup to the account page I get an javascript error:
Uncaught TypeError: Cannot read property 'inport' of undefined.
Why couldn't I connect to the JavaScript function? If I call alert(sap.byd.ui.mashup.context.inport.ExternalID); from my code while testing the mashup everything works but when using the regular interface I only get "Undefined" response.
Hi Guys,
I had tried the HTML Mashup concept and was able to display the screen successfully.
Recently when I checked for the same the mashup doesn't display and it's the same case for newly created mashups.
Please provide your valuable suggestions.
Thanks,
Srinivasan
Hi all,
first of all, thank you Vinita Sinha for this documentation of implementing an html mashup using an embedded component!
I'am facing an issue a little bit apart from your solution. I'm trying to get address data from a SAP BO and using it with Google Geocoding API.
I've integrated the EC succesfully to an SAP Floorplan and the Mashup/Gmap displays on the floorplan. For testing reasons I've added some input fields to the EC to make sure that the binding is correct. And it works out fine.
So far so good, but...
...something does not work with the binding from the EC to the HTML Mashup, I guess. Although I was referring to your doocumentation.
Maybe it could be also the way I'am trying to use the Data Inport in my JavaScript code. To check this issue I tried the following:
There is a floating panel in my HTML with two input fields (textbox, button). I tried to assign the inport data to the input fields.
I guess that there was one time the salesorderid appeared at the button, at the textbox was nothing (empty). After that there was always an "UNDEFINED" in both of the fields.
I would be very thankful, if you could help me out.
Thanks and best regards,
Chris
Thanks for the post. Can this work in reverse where user clicks on an item on html mashup like icon on a map and we get the data back in the C4C screen using EC for additional/custom fields
Regards
Irfan
Hello Vinita. First, great post...thank you. I am trying to follow this for a data mashup I have that invokes a REST service and I'm encountering an issue with the inport I believe. My custom action is not being called but the mashup is still being invoked. I've set a breakpoint within the custom action and its not getting hit but my REST service is indeed being called because its invoking my functionality within ECC. At first I thought it was because I didn't have the "RequestFireOnInitialization" flagged on the InPort. So....I tried that as well and while I see the custom action now being hit (sporadically) the REST service is still being invoked ahead of the LaunchEC operations completing. Are there any specifics for Data Mashups that I should adhere to that are different from what you have above. First, should your pic above for Inport have had "RequestFireOnInitialization" checked? Next, is there any thing I need to do that holds up the data mashup from being called until the Inport and bound Events & Operations complete? Thank you for any feedback you can share.
James
I’ve done all steps as you mention in your document but the “pipes” folder under “Mashup” folder not It did not appear how to appear the pipes folder that contain all mashups??.
Hi,
Did you get answer to this??
Regards
Rituraj
I got the answer, basically u need to create mashup with pdi user not the functional user 🙂
Hello Vinita,
Where can I see the result attachments(attachment section) that you have mentioned in the blog?
Regards,
Nagaraj Naik
This was an extremely useful blog, thank you!
Thought it may be worth sharing some findings after implementing something similar in our tenant: