Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Thursday, March 21, 2019

PSSpreadsheet Class Part 2 | Documentation Update, Date Format (converting to epoch) and more

This is a continuation of 'Using PSSpreadsheet Class in App Engine' where I demonstrated how we can use this new API to generate Excel spreadsheets using PeopleCode. While there were and still are a lot of gaps in the documentation of this API, it provides an easier method to create spreadsheets from PeopleCode.

Documentation Update

Previously, in the notes section, I explained the significance of the second parameter (rowset processing) in the Open method which was not documented in PeopleBooks at that point in time. This has been updated.

PSSpreadSheet - Open Method PeopleBook

This is also documented in the following My Oracle Support - Doc Id which clarifies the RangeApplyStyle method as well.
E-PC: There Is Missing Documentation In PeopleBooks For PeopleCode PSSpreadsheet Class - Methods Open And RangeApplyStyle (Doc ID 2357922.1)

Other useful documents on My Oracle Support are listed below.
E-PC: PSSpreadsheet SetColumnWidth Method Is Not Working (Doc ID 2354586.1)
E-NV: What is RangeApplyStyle() in PSSpreadsheet API ? (Doc ID 2288870.1)
E-PC: PeopleCode API PSSpreadSheet SetActiveSheetName method is not working (Doc ID 2511065.1)
E-PC/NV - Method RangeApplyStyle Of Class PSSpreadsheet Is Not Available On PT8.55 And PT8.56 (Doc ID 2516382.1)
Bug 29384267 : ERRORRETURN-> 255 - FILE IS ALREADY IN OPEN STATE! WITH PSSPREADSHEET

Needless to say, that while some of the reported issues are fixed/clarified, there are still improvements to be made which I hope will follow suit in subsequent releases/patches of PeopleTools.

Date Format for SetCellDate

After reviewing a comment thread on my previous post, I was curious to find out more about the SetCellDate method.

Comment thread
PSSpreadsheet - SetCellDate PeopleBook


If we see the example provided in PeopleBooks, a value (string) of 120223323 produces a cell (date format) with the following value.
1/2/1970  9:23:43 AM


So what is this mystery number/value 120223323 that magically converts to a date of 1/2/1970  9:23:43 AM? After many days of spinning my wheels, I finally found (thanks to Oracle Support) that this is actually the date in epoch format (date/time in milliseconds since epoch). Wow! Why? 😂

One reason I can think of is that behind the scenes PSSpreadSheet API is implemented in Java (Apache POI) and therefore may require this format to pass into appropriate java methods? My guess is as good as yours. In any case, there is potential for this to be improved where this date calculation/conversion can be masked from the API user (perhaps with an internal conversion) for the date parameter in the SetCellDate method.

Anyway, now how do we calculate the date in epoch timestamp format if we ever want to use this method successfully under the current circumstances? There are some online converters which we can use to get ourselves familiarized with the calculation.

https://www.epochconverter.com/
https://www.freeformatter.com/epoch-timestamp-to-date-converter.html

Note: Keep in mind that the SetCellDate method expects the epoch timestamp to be in milliseconds (some converts provide the timestamp value in seconds which might throw us off when used in PeopleCode).

That said, how do we do this calculation/conversion in PeopleCode? I have not found a delivered function and/or API that helps with this calculation/conversion. So, I resorted to using javascript and executing it on the server side using a very handy technique demonstrated by Jim Marion on his blog here.

JavaScript to convert date to epoch timestamp format (milliseconds)

Here is a simple JavaScript that converts a human readable date to epoch timestamp format. You can follow this link to test the code directly in jsFiddle.

https://jsfiddle.net/SasankVemana/bgLk8sez/



Sample PeopleCode Snippet with SetCellDate example

JavaScript in Message Catalog (29999, 1)

Message Catalog (29000, 1) for reference


GitHub Project Update

In my previous post, I shared a sample App Engine program that will simply generate Excel spreadsheet using data from a rowset. It was brought to my attention that if a column contains a date/datetime field, then the spreadsheet is not generated as expected. This is definitely a limiting factor when it comes to using the rowset processing option in the PSSpreadSheet class.

I created another GitHub project which generates a spreadsheet via an App Engine which uses non-rowset processing option. If you are looking for examples, the App Designer project can be downloaded and used evaluation purposes.

GitHub Project: https://github.com/SasankVemana/PSSpreadsheet-in-App-Engine-2

This sample App Engine will produce a spreadsheet as follows.

Tuesday, March 19, 2019

JavaScript Injection Framework - Updates, Bugs and Fixes

The reason I am writing this blog post is to make readers aware of the latest version of the JavaScript Injection Framework and known bugs/fixes associated with the older versions.

If you read some of my previous posts on Branding and other UI enhancements, you may have come across several attempts made by me to find a means to globally (system wide) inject JavaScript/CSS. Unfortunately, there is no way to do this via delivered configuration/code so I ended up writing custom javascript code.

Over the years, I have made iterative improvements to this code and created a framework of sorts with a minimally invasive customization.

Early (Beta) version
https://pe0ples0ft.blogspot.com/2015/11/peopletools-854-branding-part-5b-fluid.html#FluJSInjectionBootstrap

Updated version (using RequireJS)
https://pe0ples0ft.blogspot.com/p/javascript-injection-framework.html

As I was making further changes, I moved this framework to GitHub in an effort to better manage the code/versioning.

GitHub Project
https://github.com/SasankVemana/PeopleTools-JavaScript-Injection-Framework

Recently, the following Doc ID was brought to my attention via a twitter post.

Oracle Support Document 2294106.1
E-PIA: Run to HTML,Excel and XML links in Query Manager and Query Viewer spinning for ever while running a report having prompt criteria

Twitter Thread
https://twitter.com/ArcherHuck/status/1085635936053051394
After reviewing Doc ID 2294106.1, I realized that this issue is most likely caused by a customer who implemented this JavaScript Injection Framework. The issue reported in the Doc ID, is very similar to an existing issue identified with an older version of the framework.

Reported Issue: https://pe0ples0ft.blogspot.com/p/javascript-injection-framework.html#c6317103235239955618

The solution provided by Oracle in the Doc ID is to completely remove the custom framework which is understandable since this is not Oracle code. But this issue can be overcome by using the latest version of the JavaScript Injection Framework. In the latest version of the bootstrap javascript as shown below, the regex pattern is updated to account for an extended list of PeopleSoft URL types.


Additionally, the latest version of the framework that is available on GitHub also addresses and fixes some race conditions (which I ran into under certain circumstances) associated with RequireJS and other custom scripts.

Here are some resources that are very useful to understand common timing issues related to javascript functions and callbacks.

https://blog.kevinchisholm.com/functions-javascript/javascript-callback-functions-the-absolute-basics/
https://www.sitepoint.com/understanding-requirejs-for-effective-javascript-module-loading/

Wednesday, April 25, 2018

Adding Custom Links to Action Menu using DoURLWarning JavaScript Function

In the past, I wrote about how we can add custom links to the Branding - Action Menu at the system level.

Refer: Adding Custom Links to Fluid Branding

While testing this feature, I found that these custom links do not work in certain scenarios. For example, clicking those links from within the NUI Activity Guide framework (which is also used in Nav Collections).


I originally used the FieldChange event and the Response Class RedirectURL method to implement the redirection logic in Fluid Branding as shown below.


Since the Response Class RedirectURL method proved to be problematic in certain scenarios, I started investigating other options. In the process, I found this great delivered JavaScript function called DoURLWarning which is part of PT_HISTORY object in 8.55+ (PT_PAGESCRIPT_FMODE object in 8.54).


DoURLWarning function allows us to redirect to a URL using javascript. Additionally, the function will take care of checking for any unsaved data in the current page and if there is any it will display the "Save Warning" message. If not, it will redirect to the URL in the parameter list.

To use the DoURLWarning function, I removed all the redirect logic from the FieldChange Event. And added code in the RowInit event (as shown below) to utilize the DoURLWarning in combination with the Field Class JavaScriptEvents Property.


PeopleCode for reference

Demo

As we can see in the demo video, the custom link on the Action Menu works when invoked from the Activity Guide framework (which is also used in Nav Collections). The same approach described above can be used to implement custom links to internal PeopleSoft pages as well (e.g.: Process Monitor, Report Manager, etc.).


Save Warning Demo


Fluid UI New Window Feature Implementation

I used a similar technique as described above to implement the 'New Window' feature in Fluid UI as a custom link on the Branding - Action Menu.

Refer: Fluid UI - New Window Feature - Workaround

The only difference in the implementation is that instead of using the Response Class RedirectURL method (which would redirect/replace within the current window), I used the ViewContentURL method to open a new window as shown below.


We can see in the demonstration below, that the same problem described for the custom links also exists for this New Window implementation.


To workaround the problem, I took a similar approach and removed the existing logic from the FieldChange event and moved it to the RowInit event. In the RowInit event, I used the Field Class JavaScriptEvents Property in combination with the Window interface's open method as shown below. Additionally, I also updated the logic to include the %Request.QueryString to the URL to make sure that none of the additonal parameters are lost when opening the new window.


PeopleCode for reference

Demo


Monday, November 20, 2017

Commenting JavaScript in PeopleTools

If we look at some of the HTML objects which store JavaScript in PeopleTools, we will find many styles of comments. Here are a few options.

Option 1
// Option 1 - Single Line Comment;

/*
Option 1 - Multi-line Comment 1;
Option 1 - Multi-line Comment 2;
*/

Option 2
//% Option 2 - Single Line Comment;

<!%
Option 2 - Multi-line Comment 1;
Option 2 - Multi-line Comment 2;
 -->

What is the benefit of using % meta-html?

The screenshot below shows how the javascript is rendered at runtime. We can see that using the % sign allows the meta-HTML processor to recognize the comments and delete them during runtime.


PeopleBooks: Comments in HTML

Does commenting style (% meta-html) really matter for JavaScript?

Not really. PeopleTools 8.53 introduced JavaScript Minification by default. The screenshot in the previous section was generated by disabling minification (using Signon - Page Generation trace settings). Therefore, the commenting style in JavaScript does not really matter if we don't override/disable the PeopleTools (8.53+) default minification which will delete all comments (regardless of style) in JavaScripts.

PeopleBooks: Working with JavaScript in HTML Definitions


Sunday, November 19, 2017

PeopleTools 8.56 Hidden Gem | HTMLAREA 'Respond Only Once' Property

While working on some quirks with reCAPTCHA implementation in a PeopleSoft PIA page, I stumbled on this scarcely documented, hidden gem in PeopleTools 8.56. For many years, we struggled with HTMLAREAs and how they behave with AJAX requests in PeopleSoft. Basically, HTMLAREAs get reloaded every time there is an AJAX request on the page which puts the responsibility on the developer to make sure any javascript code in the HTMLAREA continues to work as expected. Jim's post dating back to 2006 illustrates how long this has been a problem!

I ran into a similar problem with the reCAPTCHA implementation and I wrote additional javascript code to workaround the issue. In the process, I found this HTMLAREA page field property called 'Respond Only Once' which is new in PeopleTools 8.56. This property is not documented in PeopleBooks except for this one location as a related topic:
PeopleBooks - PeopleTools 8.56 - Field Class Properties

Based on what I found, this property when selected will exclude the HTMLAREA from AJAX requests. A total life saver! :)

Of course, the HTMLAREA will be included in the Save event (postback).

Demonstration of Problem

In this demo we can see how the reCAPTCHA plugin (as an example) which is generated by a HTMLAREA gets reloaded/refreshed on every AJAX requests. On the second server trip, the reCAPTCHA div will disappear because the reCAPTCHA API javascript is no longer loaded as expected.

HTMLAREA


Demo

We can see how the HTMLAREA is reloaded every server trip resulting the disappearance of the  reCAPTCHA plugin.


Respond Only Once Property

Let us set the 'Respond Only Once' property in the HTMLAREA.


Demo

In the following demo, we can see how the 'Respond Only Once' property helps to exclude the HTMLAREA from the AJAX requests and to avoid reloading its contents.


Saturday, November 18, 2017

reCAPTCHA in PeopleSoft PIA Pages

In one of my previous blog posts, I showed how to implement reCAPTCHA 2.0 in PeopleSoft. My blog post only covered setting up the reCAPTCHA plugin on the PeopleSoft login page as a workaround for DOS, bot attacks, etc. I also mentioned that the effort to implement reCAPTCHA in a PeopleSoft PIA page (Classic/Fluid) should be very similar. But I found that there is one challenge with implementing the same client side code in the PIA (as noted by some comments in the post). The issue is a common problem we routinely run into when we combine a HTMLAREA (with JavaScript) and a PIA page! Every time there is an event that posts back to the server, the entire page is refreshed. Obviously and unfortunately for us, this will cause the HTMLAREA to reload as well. If there is javascript in the HTMLAREA and if we are referencing external scripts (as we do in reCAPTCHA), there is a risk that the script will be reloaded and any variables may be reset. In order to workaround this problem, we need to be extra careful with writing javascript in HTMLAREA making sure we properly 'manage' how our code is executed during such events. This is true for all cases not specific to this reCAPTCHA implementation.

To demonstrate the problem, I added the reCAPTCHA plugin (client side) code to a Classic PIA Page using a HTMLAREA.

Classic Page


HTMLAREA and Page Activate PeopleCode

The HTMLAREA is populated dynamically using Page Activate PeopleCode.


JavaScript and HTML for reCAPTCHA

The javascript and HTML needed to display the reCAPTCHA plugin is stored in a HTML object (CSK_RECAPTCHA).


Result

We can see that the reCAPTCHA plugin is displayed successfully on the page.


Demonstration of Problem

Basically, on the second postback the reCAPTCHA API javascript will no longer load and therefore result in the reCAPTCHA div to disappear. In the demo, we can see the problem occurs during the FieldChange (Server Trip) and the Save events.


Solution

To solve this problem, instead of directly using the script element in the HTMLAREA to reference the reCAPTCHA API javascript, I wrote a javascript function to load the script in the DOM.

Result


reCAPTCHA Callback Function

You may notice that there is another function called svRecaptchaCallback and it is used as the data-callback attribute value in the reCAPTCHA div element. This callback function is a great feature that is available with reCAPTCHA which allows us to execute our custom code upon a successful reCAPTCHA event. You can see in the following demo that the message is printed on the console once we complete a successful reCAPTCHA verification. As an example, this could be used to conditionally activate/display certain page field elements only after a successful reCAPTCHA verification. Please note that this is purely on the client side. That is, the callback function is available and executed on the browser as part of our HTMLAREA. This is not the same as the server-side validation!


Notes

- Environment Details: HCM 9.2 PUM Image 23, PeopleTools 8.56.01.
- The main focus of this post is the client-side implementation. The server side validation logic can be implemented based on the code provided in my previous post. Only difference here is that we will be executing the PeopleCode in a event such as SavePreChange or similar instead of the SignOn PeopleCode event.
- The implementation in this post is done as a proof of concept only. When implementing reCAPTCHA in a PIA page, we may also want to consider only prompting the user with the reCAPTCHA validation once. Prompting the users to confirm that they are not robots on every Save event might not result in a great user experience.

Sample Project on GitHub

https://github.com/SasankVemana/reCAPTCHA-in-PIA

Tuesday, June 27, 2017

Fluid Global Search - Setting Focus on the Search Box

Dan Iverson from psadmin.io created a new Idea on MOSC:

Fluid global search box should default the cursor:
https://community.oracle.com/ideas/18507

Workaround:

If the current behavior is causing issues and you would like to set the focus on the search box, then it can be achieved by adding one line of custom code to the following delivered objects (depending on your tools release):

PeopleTools 8.55+:

HTML Object: PT_SEARCH_FMODE
Function: toggleGBLSearchTray
Custom Code:
    /* CSK Customization - Start */
    document.getElementById("PTS_KEYWORDS_GLB").focus();
    /* CSK Customization - End */


PeopleTools 8.54:

If you are using PeopleTools 8.54, then you will not find this function toggleGBLSearchTray in PT_SEARCH_FMODE (since that object does not exist). Look for the same function in PT_PAGE_SCRIPT_FMODE.

HTML Object:  PT_PAGE_SCRIPT_FMODE
Function: toggleGBLSearchTray
Custom Code:
    /* CSK Customization - Start */
    document.getElementById("PTS_KEYWORDS_GLB").focus();
    /* CSK Customization - End */
 

Sunday, April 23, 2017

LinkedIn-style Smart Notifications in PeopleSoft: Integrating FavIcon and Page Title with Push Notifications

As part of the latest wave of changes that were done to the LinkedIn UI, I noticed that they also made a change to their FavIcon. The FavIcon alerts us if there is a new notification. Of course, the Page Title also shows us the number of new notifications similar to most modern websites (Twitter, Facebook, etc.). This is great feature especially when we are off "working" on other browser tabs to grab our attention.


Push Notification Framework has been part of PeopleSoft since PeopleTools 8.54 release. So, why not integrate the FavIcon and the Page Title with Push Notifications? This will help the users to return to their work if they receive a notification. Perhaps a UX/UI productivity feature?

Demo:

Here is a demo of how we can subscribe to the Push Notification events and dynamically update the FavIcon and the Page Title.


Environment Details:
- CS 9.2
- PUM Image 4
- PeopleTools 8.55.12

Step 1: Create a Custom FavIcon in Classic and Fluid

I wrote about this topic in the past (as part of my Branding articles). Currently, there is no delivered option to use a custom FavIcon in Classic and Fluid consistently.

Refer: Overriding FavIcon

Related Posts and Reference Documents:
PeopleTools 8.55+ - Using Oracle JET Series: Part 1, Part 2, Part 3 and Part 4
Global JavaScript Injection Framework
My Oracle Support > E-PIA: Does PeopleSoft Use Favicon ? (Doc ID 1226503.1)
My Oracle Support > E:FLUID- How To Access Favicon On Fluid Landing Pages? (Doc ID 2004996.1)

Step 2: Create a custom JavasScript to Subscribe to Push Notifications

JavaScript Object: CSK_SUB_PN_JS


Notes:

The script contains three main parts
- cskSmartFavIcon function takes care of replacing the custom FavIcon with an alternative custom alert FavIcon. It also takes care of pre-pending the Page Title with the notification counter in (n) format.
- The Push Notifications - Subscribe function is used to subscribe to the desired Push Notifications events.
- Finally, cskFavIconPNJS function (called from PTPN_NOTIFICATION_MSG_JS > DoNotify function) takes care of toggling the FavIcon and the Page Title when the user has clicked on the Notification Icon.

Step 3: Inject CSK_SUB_PN_JS globally across the application

As mentioned in reference documents in Step 1, I used my custom framework to inject CSK_SUB_PN_JS globally.


Step 4: Update delivered JS - PTPN_NOTIFICATION_MSG_JS

This will take care of toggling the FavIcon and resetting the Page Title when the user clicks on the Notification Icon.


Tuesday, November 22, 2016

Piwik: Open-Source Web Analytics Platform

While presenting at Oracle OpenWorld 2016, I demonstrated the integration of Google Analytics (GA) with PeopleSoft Applications for generating usage metrics. One of the big reasons that many find GA an attractive option aside from its superior features, is the fact that it is free. Of course, there are some limits to the term 'free'. After my presentation, I had an informative conversation with Greg Kelly from Oracle, who pointed out that just because a product is free, it does not necessarily mean it is the right solution for everyone. Greg also mentioned Piwik (hat tip), which is one of the most popular open-source web analytics platform and has an unique selling proposition of 100% data ownership.

In my personal opinion, Google Analytics is far more superior when it comes to functionality and features but I am aware that not everyone would be able to leverage Google Analytics due to various reasons (primarily data ownership). That said, Piwik is a great alternative for such customers to create a locally or cloud hosted web analytics platform which provides full control of their data. I am stating the obvious but Piwik does come with the cost of setting up and maintaining the infrastructure to host it somewhere.

Here are some resources that I found interesting and relevant to this topic (there may be many more out there):
https://zenincognito.com/piwik-vs-google-analytics-a-detailed-review/
https://piwik.pro/2016/05/infographic-piwik-vs-google-analytics/
http://www.kaushik.net/avinash/how-to-choose-a-web-analytics-tool-a-radical-alternative/

Here is my recent blog on how to integrate Google Analytics with PeopleSoft Applications:
https://pe0ples0ft.blogspot.com/2016/09/peopletools-using-ga-analytics-js.html

Here are the steps that I followed to setup and integrate Piwik with a PeopleSoft instance (HCM 9.2 PUM 17 - PeopleTools 8.55.06).

Step 1: Download and install Piwik

Resource: http://piwik.org/docs/installation/

In my cases, I downloaded Piwik from the Microsoft Windows Web App Gallery.
http://piwik.org/blog/2013/02/piwik-microsoft-windows-web-app-gallery/

Then, I followed the installation wizard to install Piwik on my Windows 7 desktop computer where my PUM image is also running.

Some gotchas for Windows installation based on my experience.

Windows Firewall Inbound Rules:

I had to punch a hole in the Windows Firewall and set up an inbound rule to allow requests on a port of choice.

Windows Firewall > Advanced Settings > Inbound Rules


IISExpress - Site Binding Configuration (applicationhost.cfg):

I also had to add site bindings to the IISExpress applicationhost.cfg to handle URL binding failures.
https://www.iis.net/learn/extensions/using-iis-express/handling-url-binding-failures-in-iis-express


Add trusted hosts to Piwik config.ini.php:

Finally, I had to add my localhost ip+port combination to the config.ini.php file as a trusted host.

WebMatrix > Piwik > config > environment > config.ini.php > trusted_hosts


Step 2: Login to the Piwik Admin Console and add a new site

Reference: http://piwik.org/docs/manage-websites/

Step 3: Obtain Piwik Tracking Code JavaScript snippet

Piwik > Administration > Websites > Manage Websites > View Tracking Code

You will find code similar to the following screenshot:


Next, I created a Branding Object in PeopleTools with the preceding javascript:

Navigation: PeopleTools > Portal > Branding > Branding Objects


Note: I only used the code snippet inside the script tag and also commented out the noscript portion for this proof of concept.

Step 4: Inject custom javascript in PeopleSoft

This part is similar to the Google Analytics javascript injection. To inject this custom javascript object across the PeopleSoft application, I used a custom framework for Global JS Injection. Details are in the following link:
Global JavasScript Injection Framework


Note: You don't have to use the same Global JS Injection Framework. You could use any other technique that might work best for your environment. The idea is to make sure the javascript is executed on every single page across the PeopleSoft application to send the usage metrics to the Piwik server.

Results:

Here is a screenshot of the Piwik Dashboard.


Saturday, September 10, 2016

Fluid UI - Using Oracle JET - UI Components - Visualizations - Status Meter Gauge

While exploring the use of Oracle JET to enhance the UI capabilities of PeopleSoft Fluid, we saw how we could employ basic responsive layout/styling (Alta UI css) and data binding (KnockoutJS) functionality.

Based on what we learned so far, does it appear like PeopleTools natively (via App Designer) support Oracle JET? Probably not. But are there enough built-in functions/tools/workarounds to integrate Oracle JET with Fluid UI? Yes, yes and yes!

In this post, I will demonstrate how we can integrate an Oracle JET - Visualization Component (Status Meter Gauge) in a Fluid page to enrich the UI (more than what we could normally achieve within the confines of App Designer). By the way, this post is inspired by the Oracle JET MOOC - Lesson 2 - Part 2: Data Visualization Components. I highly recommend watching the video to get an understanding of the Status Meter Gauge. We will try to replicate the following behavior demonstrated on an Oracle JET QuickStart Template website (see oj Module section in the below animation).


Development Environment: HCM 9.2 PUM Image 17 - PeopleTools 8.55.03

Assumptions: For the purposes of this demo, it is assumed that the latest version of Oracle JET is installed on the web server.

Step 1: Add Oracle JET paths to requireJS configuration

If we work with the Oracle JET QuickStart Template (especially using NetBeans), we will realize that the entire framework to develop and run Oracle JET applications is pre-configured for us. So there is not much we have to do other than plug and play the modules, components, etc.

As part of the pre-configured framework, the requireJS config for the QuickStart Template can be found in the main.js:


Because we are trying to wire this into the PeopleSoft architecture, we need to make sure the Oracle JET related libraries are added to the requireJS path configuration. So, let us update our global requireJS configuration to include the following Oracle JET paths.

        'knockout': cskBowerCompsPath+'/knockout/dist/knockout',
        'ojs':cskBowerCompsPath+'/oraclejet/dist/js/libs/oj/debug',
        'ojL10n':cskBowerCompsPath+'/oraclejet/dist/js/libs/oj/ojL10n',
        'ojtranslations':cskBowerCompsPath+'/oraclejet/dist/js/libs/oj/resources',
        'promise':cskBowerCompsPath+'/es6-promise/promise.min',
        'ojdnd':cskBowerCompsPath+'/oraclejet/dist/js/libs/dnd-polyfill/dnd-polyfill-1.0.0.min',
        'jqueryui-amd':cskBowerCompsPath+'/jquery-ui/ui/minified',
        'signals':cskBowerCompsPath+'/js-signals/dist/signals.min'

For complete javascript code, please refer jsFiddle link: CSK_REQUIRE_CFG_JS

Note:

- The library paths for Oracle JET (installed using bower or direct download) might not be the same as what we normally find in the Oracle JET QuickStart Template. Please make sure the paths are referenced appropriately.
- For more details on using requireJS refer: PeopleTools 8.55+ - Using Oracle JET (JQuery, JQueryUI, requireJS and more): Part 1, Part 2, Part 3, Part 4

Step 2: Create a Fluid Page

Let us create a simple Fluid page - CSK_OJ_GAUGE_DEMO - using PSL_APPS_CONTENT layout. And add a couple of group boxes for creating a flex layout (oj-flex and oj-flex-item). Adding the flex layout is optional but you can refer to Fluid UI - Oracle JET - Using Oracle Alta UI and Flex Layouts for more details.

Further, let us add the following page field elements:

Group Box (Layout Only to group page field elements):


Edit Box (Input Field):

This field will represent the 'Sales Percentage' input element for our demonstration.



Group Box (Layout Only placeholder for the ojStatusMeterGauge component):

This is just a placeholder group box to generate the DIV where we will eventually add the ojStatusMeterGauge "View" data-bind attributes. Notice the 'Override PeopleTools Style?' is selected? This is to ensure that none of the delivered styles will interfere with this element.



Push Button (To Send Gauge/Input value back to PeopleSoft):

The reason why we have this push button here is to demonstrate how Oracle JET integrates with the PeopleSoft architecture (PIA). We will evaluate how certain events on the page ("View") might possibly disturb (mutate) the knockout bindings and how we can work around those issues.

Note: There may be more efficient ways (than the methods described) to workaround these quirks and I would be happy to hear from others on this topic! Please feel free to leave a comment.


Step 3: Add the ojStatusMeterGauge related data binding to the View (Page HTML)

As shown in the MOOC lesson, we will be using the div on line 252 from this Oracle JET - Cookbook - HTML code for the Status Meter Gauge. Let us adjust the attribute values slightly (to give an appropriate custom value (cskValue) for the data-bind and to update the style margin to work effectively on our Fluid page).

HTML: ojStatusMeterGauge Component DIV


Now, we need to apply the data-bind and style attributes from the above sample DIV to the gauge-container group box on our Fluid page.We can do that with the following Page Activate PeopleCode. While we are at it, we can also add the data-bind attribute to the edit box (input field). This is specifically to establish a two way data-bind between the gauge and the input field.


PeopleCode For Reference:

Declare Function SetViewport PeopleCode PTLAYOUT.FUNCLIB FieldFormula;

/* Set ViewPort Meta for SFF Scaling */
SetViewport("width=device-width,user-scalable=yes,initial-scale=1.0,minimum-scale=1.0"); /* apply the system default viewport setting */

/* Setting the data-binds in the "View" */
CSK_OJ_WRK.GROUPBOX.HtmlAttributes = "data-bind=""ojComponent: {component: 'ojStatusMeterGauge', min: 0, max: 100, value: cskValue, orientation: 'circular', plotArea: {rendered: 'on'}, metricLabel: {rendered: 'on'}, title: {text: 'Sales'}, readOnly: false}"" style=""margin: 5px auto; height:100px; width:45%;""";
CSK_OJ_WRK.PERCENT_COMPLETE.HtmlAttributes = "data-bind=""value: cskValue""";


Step 4: Apply Knockout Bindings to the ViewModel

Let us update the PageActivate PeopleCode to include a javascript object (CSK_OJ_GAUGE_MAIN_JS) on page load. This javascript will serve the same purpose as a traditional 'main.js' in the javascript/Oracle JET architecture.


JavaScript: CSK_OJ_GAUGE_INIT_JS


The reason I introduced this new javascript object (CSK_OJ_GAUGE_INIT_JS) is because if we create global variables in the CSK_OJ_GAUGE_MAIN_JS which is loaded as an AddOnLoadScript, the variables would not persist and appear as undefined subsequently. As a workaround, CSK_OJ_GAUGE_INIT_JS was created and loaded using the AddJavaScript function instead of AddOnLoadScript function - prior to the execution of our main.

JavaScript: CSK_OJ_GAUGE_MAIN_JS


- As you can see, we added the requireJS configuration path to the "ViewModel" javascript in the main (CSK_OJ_GAUGE_MAIN_JS), instead of using the global requireJS configuration in Step 1 (while setting up Oracle JET paths). This is because we do not want this app (page) specific path to clutter our global requireJS configuration.
- In the require block, we injected the Alta css to enable the oj-flex and oj-flex-item styling that we used in Step 2.
- Then, the Knockout bindings are applied to the "ViewModel" which resides in CSK_OJ_GAUGE_VIEWMODEL_JS.
- The cskOJKORefresh function was created to take care of page events that might require a server trip (e.g.: Clicking on 'Send To Server' button would trigger the FieldChange event). Since PeopleSoft automatically reloads the page field element(s) on every server trip, we will find that the Knockout data-bindings are lost when such events are triggered. For more details on this quirk, click here.

Step 5: Create ViewModel JavaScript Object - CSK_OJ_GAUGE_VIEWMODEL_JS

JavaScript: CSK_OJ_GAUGE_VIEWMODEL_JS


- The define block for the ViewModel includes all the Oracle JET libraries that are dependencies (including knockout) for ojgauge.
- The subscribe function on cskValue calls the delivered addchg_%formname function to take care of a PeopleSoft quirk once again. After a server trip, if we don't highlight/activate the edit box (input field) and simply use the gauge to modify the value, then the new value will not get propagated to the server subsequently via the component buffer (input field). This function tricks/forces the component buffer to notice the change in the input field value. For more details on this quirk, click here.

Step 6: Create the FieldChange PeopleCode Event

This code will take care of handling the 'Send To Server' push button event.


- The FieldChange event on the server side simply returns a confirmation message with the value it received for the Sales Percentage.
- Additionally, the cskOJKORefresh javascript function is invoked as part of this PeopleCode event to take care of the quirk mentioned in Step 4 (part of CSK_OJ_GAUGE_MAIN_JS).

Results:

Presto! We can see that the user can now interact with the gauge/input field in several ways:
- Directly with the input field (keyboard - numbers)
- Using the keyboard arrow keys to increment/decrement the value
- Using the mouse (or touch) to slide the gauge value


Demo of Quirks:

Why do we need cskOJKORefresh function in CSK_OJ_GAUGE_MAIN_JS?

This function is invoked every time the 'Send To Server' FieldChange event is triggered to take care of following data-binding issue after a server trip.


Why do we need to the addchg_%formname function invoked in the ViewModel?

After a server trip, if the input field is not highlighted and if we try to use the gauge to alter the value and send back to server, the change will not be propagated to the component buffer.


Reference Links:

Fluid UI - Oracle JET - Using Oracle Alta UI and Flex Layouts
Fluid UI - Oracle JET - Using KnockoutJS for Data Binding - Demo
PeopleTools 8.55+ - Using Oracle JET (JQuery, JQueryUI, requireJS and more): Part 1, Part 2, Part 3, Part 4