Omnis Technical Note TNJC0009Aug 2017

Adding Ready-made JavaScript components to Omnis

for Omnis Studio 8.1 or above
By Omnis Engineering

Omnis Studio 8.1 allows you to create JavaScript components from JSON. Previously, you needed to write the Omnis side of components using C++, however with the release of Studio 8.1, this barrier has been removed. Instead you can use the new JSON Control Editor to generate the JSON required to allow Omnis Studio to interface to the component you wish to use.

For further information on using the JSON Control Editor, see the JSON Components chapter in the Creating Web & Mobile Apps manual. If you wish to create your own JSON defined controls, you will also need to refer to the JavaScript Control Reference in the Omnis JS SDK docs which you can find here:
http://sdkdocs.omnis.net/jssdk

This tech note explores wrapping the Five Stars JavaScript component using the JSON editor to provide a new component you can use in Omnis JavaScript applications.

The original JavaScript implementation of this comes from www.callmenick.com

Source files

You will need to download all the files from here: https://github.com/OmnisStudio/Omnis-FiveStars
(or download the archive: fivestars-jscomp.zip)

/net.omnis.fivestars/ four *.png files used
/rating.css - css file used
/rating.js - js file used
/stars.svg - svg image used

/ctl_net_omnis_fivestars.js - example JavaScript file with the edits described above
/net.omnis.fivestars/control.json - example json file generated by the JSON Control Editor with the properties and event parameters used in this tech note
/fivestars.lbs - example Omnis library
/jsFiveStars.htm - htm file for example library

There are also minified versions of the rating.css and rating.js files.

Creating the JSON Component

In Omnis Studio 8.1 (or above), open the JSON Control Editor from the Tools / Add-Ons menu. Omnis Studio includes a default example component called mycontrol and the JSON file for this loads automatically when you open the editor.

Change the control name to net.omnis.fivestars and press Save As to save this as a new template. The Five Stars component needs to have 2 new properties added to allow you to set the maximum number of stars and to set the current number. Go to the Properties tab and enter maxrating as the name. Remember to use lowercase as all Omnis property names are lowercase. Enter a description and select the type as integer. Scroll along to the end of the grid and enter 1 as the min value, 5 as the max and 5 as the initial values. This will mean that the maximum number of stars we will allow is 5 and we are going to use 5 as the default.

Now, enter another property for currentrating. Again, make sure it the type is set to integer. This time we will set the min value as 0, the max as 5 and the initial to 0. This will mean when we come to use the component, by default there will be no stars selected.

JSON Component

After adding the properties, we need to go to the “Events” tab. When users click the stars to set their rating, we need to know the number of stars they have selected, so we need to add a parameter to the evClick event. By default, there are 2 parameters already, xPos and yPos. These are to show you how to return parameters in the JavaScript code. Add a third parameter called numStars and give it a type of integer.

JSON Component

We have now defined all that is required in the editor, so press Save / Save As and then Build to build the base JavaScript. You will be also be prompted to allow the editor to update the template file jsctempl.htm with your new JavaScript file. If you do not allow this now, you will need to add it manually later on before testing the component.

A JSON file control.json is then created in a folder named after the control name within the path /html/controls, e.g. in our example, the file should be in the path /html/controls/net.omnis.fivestars/
There will also be 4 pngs of varying sizes files that Omnis uses within the Component Store and design environment. By default, they will be based on the Omnis logo. You can replace them with your own to match the style of your component. You can use the star logo png files supplied in the ZIP with this tech note.

A JavaScript file ctl_net_omnis_fivestars.js should have been created in /html/scripts. This is a template file containing placeholders which correspond to the properties, events and parameters which we defined in the JSON editor. Before it can be used, we will need to make some edits to this file.

Before we look at that though, close and re-start Omnis. This will then allow Omnis to recognise our new component.

Using the JSON component

After re-starting Omnis, create an Omnis library (e.g. fivestars.lbs) containing a remote task (needed to run the form) and remote form (e.g. jsFiveStars) to test your new JSON component. When you open the remote form in design mode, there will be a new tab available in the Component Store, called JSON Components. Switch to this tab and our new component is now displayed.

JSON Component

Drag the new JSON component to the form and then re-size it as required. If you look at the Custom tab in the Component Store, you can see the 2 properties that were defined in the JSON editor. You can set $maxrating to a value of between 1 and 5 as these were the limits we set in the editor. Any value outside of these will then get reversed when you tab out of the field and the default resets to 5.

JSON Component

Double-click on the component, to enter the method editor and create a $event method. Add an On evClick event and look at the Catalog. You can then see the event parameter pNumStars that was defined in the editor. Add the following lines of code:

Calculate iNumStars as pNumStars
Do $cinst.$showmessage(con("You selected",kSp,iNumStars,kSp,"stars"))

JSON Component

Make sure the evClick event is enabled in the $events property for the component which you can do in the Property Manager.

Editing the JavaScript File

Before, we can test the component in the browser, we need to edit the generated JavaScript file.
Go to /html/scripts and open the ctl_net_omnis_fivestars.js file in a text editor. (You might like to make a copy of the ctl_net_omnis_fivestars.js file so you can reference the line numbers used below.)

Replace lines 68 & 69 within the function ctrl.init_ctrl_inst with the following code:

var maxratingValue = datapropsobj.maxrating;                     // find the max value

var fiveStars = document.createElement('div');                     // create a div for our object

var html = '<div class="fiveStars__img"></div>' +               //create the html using the css class
'<ul class="c-rating"></ul>' +
'</div>';

fiveStars.innerHTML = html;                                          // apply the html
client_elem.appendChild(fiveStars);                                // add the div to the client element

var rating_elem = client_elem.querySelector('.c-rating');
this.ratingObj = rating(rating_elem,0,maxratingValue);                         // initialise the object

this.setProperty(PROPERTIES.maxrating, maxratingValue);              // set the max

This identifies the maximum value for the rating and passes that to the DOM element which we create with a snippet of html that uses a css class to to display the stars.

Although our control does not need a $dataname to work, if you did set a variable with a value of 0, the default JavaScript would display the word EMPTY instead of the stars. To avoid this you should change the default code in the function ctrl.updateCtrl (originally on lines 114 & 115) to this:

if (dataname || dataname == 0)  {                                          // if value of dataname is 0 do not show value
//             elem.innerHTML = this.mData;

To update the number of stars shown as selected, we need to insert a line after (original) line 209 of setProperty. This would allow us to use Omnis code to initialise the number of stars selected.

this.ratingObj.setRating(this.mcurrentrating);                     //update the number of stars displayed

Finally we need to update the handleClick function, by adding 2 lines after (original) line 235.

numStars = this.ratingObj.getRating();                            //get the selected number of stars from control
this.eventParamsAdd("pNumStars",numStars);              //send this to Omnis

The changed lines are clearly marked in the JavaScript file that comes with this tech note. Alternatively, you could replace the .js file generated by Omnis with the updated ctl_net_omnis_fivestars.js file supplied in the ZIP.

Testing the Component

Once all the JavaScript changes have been made, you also need to ensure that the file rating.css is placed in /html/css and the file stars.svg is in css/images.

Ensure also that the template file /html/jsctempl.htm has had the following lines added to the <head>:

<link type="text/css" href="css/rating.css" rel="stylesheet" />
<script type="text/javascript" src="scripts/rating.js"></script>
<script type="text/javascript" src=“scripts/ctl_net_omnis_fivestars.js"></script>

After checking all this, we are now ready to test the component.

Go back to Omnis and test the form using Ctrl-T. If everything has worked successfully, you should get something like:

JSON Component

You can then mouseover and select the number of stars you want.

JSON Component

Something Amiss

If you do not get these results, you may need to invoke the debug tools on your Browser and step through the JavaScript code to identify where the problems lay. The techniques of doing this lays outside the scope of this tech note.

Check that you have placed all the files in the correct location, including rating.css, rating.js, and stars.svg, as outlined above.

Further example

A further example of a JSON defined control can be found at https://github.com/OmnisStudio/Omnis-Signature which demonstrates additional functionality such as calling custom methods.