Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
david_stocker
Contributor
This is part of a tutorial series on developing your first custom widget.  The landing post for the series can be found here.

This is part 4 of the Your first SAP Analytics Cloud Custom Widget tutorial series. As usual, the final results are on GitHub, for your perusal. If you have not been following since the beginning, I suggest going back to the introduction post and start from the beginning. Last time, we added our first property and configured it, so that it could be edited from the styling panel. This time, we will add our first script API methods, so that designers working with your widget can interact with them in scripts.  Our work until now is valid for both applications and stories as well, when custom widgets are enabled for stories.   Stories don't have a JavaScript framework, so what you will be doing this time is only relevant for apps.

When you add script methods, they are in the context of the object. For example, one of the script methods that we’ll create is a setText() method. This will be called against the widget and used to change the text value.
HelloWorld4_1.setText(thetext);

 

At a high level, we are going to do three things, each of which will have its own subtasks:

  • We will add a headingType property. Previously, we always used the h1 HTML header tag.

  • Now we will make the choice of hX tag (h1, h2 or h3) dynamic.

  • We will make it possible to change the widget text and header tag type via script.


As usual, we’ll start by making minor edits to the metadata and the web components to ensure that the version and tag id of the widget is unique, as far as SAP Analytics Cloud is concerned. Please increment the numeric suffixes of name, id, and newInstancePrefix. Inside the web component element, increment the the tag element, so that it reads com-sap-sample-helloworld4. Repeat the incrementation to 4 for the stylesheet web component.


Define the headingType Property in the Metadata


 

Add a property element, for the heading type. Call it headingType. Our type will be a “string” and we’ll set the default value to “h1
"headingType": {
"type": "string",
"description": "The heading level of the widget; h1-h3. Default is h1.",
"default" : "h1"
}

 

Getters and Setters for headingType in the main web component


 

This is also similar to how we did it for widgetText.
//Getters and Setters
get widgetText() {
return this._tagType;
}

set widgetText(value) {
this._tagText = value;
}

 

Go ahead and host the new JavaScript file. You are done working in the web component for this step.

 

Metadata for Script Methods


Script methods are defined entirely in the metadata JSON, so let’s switch back there to define our script methods. We’ll do this in the “methods” object. Each child object of “methods” defines a script method. The name of the object is the name of the method. All properties are optional

  • body – The value is a script, which will be executed when the script method is called. With this, you can work in the scripting framework, where the designer is. If you want to execute JavaScript that is inside the web component instead, leave this property out and add a method to your “main” web component with the same name. If there is no script, the SDK framework will look for a method in the main web component and call it.

  • description – this optional attribute gives a bit of documentation to the designer.

  • returnType – the type of variable returned by the script. If this property is missing, then nothing will be retuned.

  • parameters – an array of parameters. The parameter objects are defined below:


 

  • name – Every parameter has a name

  • description - as above

  • type – parameter types are the same as property types. Additionally, you can use script API data types. We won’t use any in our simple widget, but if you are interested in using them, you can have a look at that section in the official developer’s guide.


Let’s add three nearly identical methods. Each will change the hX tag type in our widget:

  • setH1()

  • setH2()

  • setH3()


All three follow the same pattern. You’ll give a description for the designer and you’ll change headingType. We won’t need any parameters, because each heading type has its own method. These are the “simplest” methods. We’ll change headingType in the body of the text, by updating the property. E.g.
"body": "this.headingType = 'h1';"

 

The three methods together will look like this:
"setH1": {
"description": "Update the hX tag of the KPI field to h1",
"body": "this.headingType = 'h1';"
},
"setH2": {
"description": "Update the hX tag of the KPI field to h2",
"body": "this.headingType = 'h2';"
},
"setH3": {
"description": "Update the hX tag of the KPI field to h3",
"body": "this.headingType = 'h3';"
}

 

Next, we’ll add a script method that returns a value. This will be getH() and it will return the current header tag. getH() has a returnType attribute and it will be a string.
"getH": {
"description": "Get the hX tag of the KPI field",
"body": "return this.headingType;",
"returnType": "string"
}

 

Lastly, we’ll add a method for changing the text, in case we want to do this dynamically, at runtime. We’ll call it setText(). It uses a single parameter, with the name newTextValue. newTextValue will be a string. In the body, we’ll set the widgetText property to whatever was passed as the newTextValue parameter.
"setText": {
"description": "Set the text value of the widget",
"parameters": [
{
"name": "newTextValue",
"type": "string",
"description": "The displayed angle of the gauge"
}
],
"body": "this.widgetText = newTextValue;"
}

 

Altogether, our new methods blocks looks like this:
"methods": {
"setH1": {
"description": "Update the hX tag of the KPI field to h1",
"body": "this.headingType = 'h1';"
},
"setH2": {
"description": "Update the hX tag of the KPI field to h2",
"body": "this.headingType = 'h2';"
},
"setH3": {
"description": "Update the hX tag of the KPI field to h3",
"body": "this.headingType = 'h3';"
},
"getH": {
"description": "Get the hX tag of the KPI field",
"body": "return this.headingType;",
"returnType": "string"
},
"setText": {
"description": "Set the text value of the widget",
"parameters": [
{
"name": "newTextValue",
"type": "string",
"description": "The displayed angle of the gauge"
}
],
"body": "this.widgetText = newTextValue;"
}
}

 

 

Testing the Widget


 

Load the new .json and add the new widget to your app. You will notice that we have an extended script API on our new widget.



getLayout(), isVisible() and setVisible() are always there.

To test the setH family of methods, we’ll add a radio button to choose between the header values and add an entry for each.



 

In its onSelect scripting event, let’s call the setH method appropriate to our choice.
var theval = this.getSelectedKey();
if (theval === "h1"){
HelloWorld4_1.setH1();
} else if (theval === "h2"){
HelloWorld4_1.setH2();
} else if (theval === "h3"){
HelloWorld4_1.setH3();
};

 

To set the text, let’s add an input field. In its onChange scripting event, we can pass the entered value to the setText() method.
var thetext = this.getValue();
HelloWorld4_1.setText(thetext);

 

At runtime, you can now change the text and header tag at will.



 

Next time, we’ll dive into eventing!