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

Thursday, October 26, 2017

Event Mapping Framework - Lifecycle Management (LCM) Considerations

Jim Marion wrote an excellent blog post demystifying the pros and cons of Event Mapping Framework (EMF) in PeopleTools. One of the concerns, that he rightly points out, is the lack of lifecycle management support. Knowing the fact that this framework is new, we can expect Oracle to soon follow suit and provide EMF support in App Designer - Compare Reports (for LCM purposes) and PeopleCode Editor (for troubleshooting purposes).

While we wait for these enhancements to arrive, here is a SQL query that will find a correlation between peoplecode events in a project and the EMF metadata. The query will return all component/page/component record/component record field peoplecode events in a project (think bundle, tax update, 'get-me-current' PUM application patching, etc.) that have corresponding Event Mapping App Classes configured. This SQL will help with LCM support concerns that might be holding us back from using Event Mapping Framework!

While you are here, please take a moment to login to My Oracle Support Community and vote on these ideas:
Event Mapping Framework Ideas

GitHub Project: https://github.com/SasankVemana/EMF-LCM-Support-Helper

Saturday, September 16, 2017

Fluid UI - Working with Grids

Grids are one of the more complex UI controls to work with in Fluid. This is because grids by design are in a tabular format which is not very conducive to responding to small form factors (particularly when there are a several columns).

I learnt a lot about grids in Fluid UI while chatting with Stefan van Liempt from CY2. He is one of the top Fluid developers and has several innovative ideas and designs. Watch his blog space here for interesting posts on Fluid (many more to come in the future)!

The following presentation on UI Controls is a must read for anyone who is starting to learn Fluid:
http://cy2.nl/wp-content/uploads/10-Fluid-UI-controls-you-should-know-about.pdf

In this post, I would like to share what I learnt from Stefan's presentation and how one of my colleagues used 'stacked columns' to create responsive grids simply by using Page Field Properties! At the end, I will share a project containing the demo pages with grids detailed in this post.

Classic Grid Layout:

To start off, I created a simple Fluid page containing a Grid with a 'Classic Grid Layout'.


Demo:

We can see that the 'Classic Grid Layout' in Fluid simply creates a grid much like in Classic UI. The grid is not responsive.



Flex Grid Layout:

Next, I changed the Grid Properties to use a 'Flex Grid Layout'.


Demo:

As we can see, the grid has a different (Fluid-like) style with the 'Flex Grid Layout' but the grid is still not responsive.


Flex Layout with Stacked Columns:

Next, I added a couple of group boxes to the grid in an effort to stack the columns and avoid the horizontal scrolling.


Demo:

By using the 'Stacked Columns' we can see how the horizontal scrolling can be avoided. This is great for a small form factor device. But the problem I have with the 'Stacked Columns' is that it is not maximizing the space available on a larger form factor. Notice all the empty space between the 'Location Details' and 'Status' columns when the grid is rendered on a desktop?


Responsive Flex Grid Layout with 2 Columns:

To avoid the empty space issue that I described in the previous section, one of my colleagues showed me a simple trick to disable column stacking on certain form factors. Simply use the 'Suppress On Form Factor' Fluid Page Field Property on the two group boxes!


Demo:

As we can see, the grid is displayed in a normal 'Flex Layout' when it is rendered on a Desktop (extra large form factor)  but is displayed with 'Stacked Columns' when it is rendered on a mobile device (small form factor).


Responsive Flex Layout with Single Column:

Just to provide another option, I wanted to show how we can use a single column display for small form factor. I simply removed the second group box so we only have one group box at the start of the grid.


Demo:

As we can see, by only using one group box in the grid, we can render the entire row in a single column format (if necessary).


Responsive Flex Layout with Labels:

Up until this point, you may have noticed that none of the stacked grid cells had any labels. The idea of using stacked grid is to not only stack the grid columns but also stack the labels. At least, that is what I have observed in some of the delivered pages. For example:


Labels cannot be taken lightly as they play a huge role in making a page accessible (consider screen readers, etc.). What if we want the labels to display beside the cell value while in stacked mode (SSF)? There is a grid field property that we can set to do just that!


This works great when the grid is stacked on a small form factor but causes redundant labels on other form factors (where we have suppressed the stacking).


To workaround this problem, I added page activate peoplecode to conditionally suppress the grid cell labels using css.

CSS - SV_GRID_CSS:

Note: LOCATION_TBL in the selector represents the page field name of the grid.

Workaround Option 2: Based on feedback from Stefan in comments below. I figured that we could simply use the Fluid properties to suppress the label in the larger form factors using the 'psc_nolabel' css. If we use this option, we don't need the page activate peoplecode with the conditional form factor logic as described above. Here is a screenshot of the Fluid property.


You might wonder how I figured that we could use 'psc_nolabel' style class? I found it in Appendix 4 (Delivered PeopleSoft Style Classes) of the following document on My Oracle Support:
Converting Classic PIA Components to PeopleSoft Fluid User Interface (Doc ID 1984833.1)
- This appendix has a table of commonly used delivered style classes

Demo:

As we can see, the cell labels appear conditionally in the stacked grid for small form factor.


Environment Details:

- HCM 9.2 PUM Image 23
- PeopleTools 8.56.01

Project Installation Details:

To make it easier for readers, I shared a project on GitHub which contains the 5 demo pages that were created for this post.

GitHub Project: https://github.com/SasankVemana/Fluid-UI-Grid-Demos

Installation Instructions:

- Download the project from GitHub.
- Load the project into your database using 'Tools > Copy Project > From File...' option in App Designer. Note: DO NOT load this in a Production environment.
- You may need to add these pages to a permission list for access.
- This project will create a folder under PeopleTools > Portal > Structure and Content > Fluid Structure and Content > Fluid Pages as follows:


- Finally add the Demo Tile to any Homepage using the Personalization option as shown below:


Demo Assumption/Dependency:

- The demo pages use PS_LOCATION_TBL as the record for the grids. This table should exist in most PeopleSoft Applications (HCM, FSCM, CS) and is required for the demo to work.

Other Fluid References:

Jim's PeopleSoft Journal
Jim and Sarah Marion's Book - PeopleSoft PeopleTools: Mobile Application Development
PeopleBooks: http://docs.oracle.com/cd/E65859_01/fluid_ux/index.html
CY2 Fluid Blog: http://cy2.nl/category/peopletools/fluid/

Icons made by Freepik from www.flaticon.com is licensed by CC 3.0 BY

Sunday, August 27, 2017

PeopleTools 8.56 - Branding Review

PeopleTools 8.56 has been out for a few months now. This is a review what is new in the Branding Framework for this release.

Review Environment Details:

- HCM 9.2 PUM Image 23
- PeopleTools 8.56.01

Branding Framework:

Not much has changed with the Branding Framework. I was expecting some improvements to the Theme Macro Set functionality which was introduced in 8.55. There are still some hard-coded references to images in javascript which would have been nice to move to Theme Macro Set CSS functionality. For example:


The delivered macro set, PT_DEFAULT_MACROSET_855, still contains 117 macros (same as in 8.55) with no changes in 8.56.


As you can see, there is a new Color Picker on the Theme Macro Set page which is a nice productivity enhancing feature! This Color Picker is based on HTML5 'color' input type element.

Icon Changes:

A notable change that we have already seen in demos prior to the release is the new 'Action Menu' icon. This has changed from the old 'hamburger' menu to a 'pea' (?) menu. Graham Smith thinks this is a healthy dietary change! We cannot argue with that. :)


Using Theme Macro Sets:

Since the framework has not changed, it was pretty much the same set of steps to use Theme Macro Sets to override Branding elements. One thing to note is that we definitely want to clone the 8.56 objects (style sheets, headers, themes, etc.) instead of moving objects from an 8.55 environment. This will make sure that we have the most current versions of the object in question.

We can follow the steps detailed in my previous posts describing how to use Theme Macro Sets to override Branding Elements:
PeopleTools 8.55 Branding - Theme Macro Sets - Part 1
PeopleTools 8.55 Branding - Theme Macro Sets - Part 2

One of the issues I noticed was the position of the 'Pea' icon was a little off after applying the Theme Macro Set overrides. This issue occurred only on the Classic Pages. For example:


I fixed this by adding the following a top property to the #pthdr2ActionList:after style selector which is part of the Classic Theme Style Sheet.


Using Oracle JET:

I noticed that Oracle JET version 2.1.0 is available with PeopleTools 8.56. I found that the JavaScript Injection Framework that I built using Oracle JET in 8.55, works without any issues in 8.56 as well. Only thing to note is that, due to the version change, we may need to review the requireJS configuration to make sure the javascript library paths are pointing to the correct version.

Resources:

JavaScript Injection Framework
Framework is based on my experience with Oracle JET - Part 1, Part 2, Part 3 and Part 4
GitHub Project: https://github.com/SasankVemana/PeopleTools-JavaScript-Injection-Framework

Using Classic Plus:

I wanted to test the delivered Classic Plus pages that were available in this PUM image. But when I navigated to the Process Monitor page - which is in the list of PeopleTools Components delivered as Classic Plus - I was still seeing the good old Classic.


To activate Classic Plus, we must update the Branding System Options to use "Fluid like theme for Classic" as the "Theme Style Type". This is the system level setting that enables "Classic Plus".


Process Monitor after setting 'Theme Style Type'.


More information on Classic Plus:
PeopleBooks - Classic Plus

Related Branding Posts:

Fluid UI - New Window Feature - Workaround
Using Different Branding Themes for Different Portals
Using the Logo as a Hyperlink
Fluid Global Search - Setting Focus on the Search Box
Adding Userid to 'Sign out' Action Menu Item Label 

Friday, August 25, 2017

PeopleTools Branding - Adding Userid to Sign out Label

In this post, I want to share how we can add the current userid to the 'Sign out' action menu item which is part of the branding.

Fluid:



Classic:


What is the benefit?

The reason I find this useful is because we can quickly hover over the action menu on any page and find out who we are logged in as (particularly when we are testing with multiple userids). Further, in the past we had a lot more real estate in the Branding header and we could add a greeting message to provide some flavor of personalization/user identification. But with the New User Interface (NUI) navigation and branding, it is not ideal to use up the Branding header to display a lengthy (space consuming) greeting. This 'Sign out' customization will provide a user specific label.

Implementation Details:

Environment:
- CS 9.2 PUM Image 4
- PeopleTools 8.54.12

Project on GitHub:
https://github.com/SasankVemana/Branding-Signout-Label-Customization

'Sign out' label customization in Fluid:

Record: PT_WORK
Field: PT_BUTTON_LOGOUT
Event: RowInit

Note: Add the peoplecode to PT_WORK.PT_BUTTON_LOGOUT.RowInit

'Sign out' label in Classic:

In Classic, we can update the 'Sign out' label without any customization using the Branding Framework.

App Package Implementation for Custom Sign out:

Note: This App Class was cloned from PTBR_BRANDING.SystemElement.SignOutLink and updated to include the %operatorid on the label.

App Package:


Create New Branding Element Type:
PeopleTools > Branding > System Data > Define Element Types


Remove delivered 'Sign out' from the Custom Branding Header:

Note: This is assuming we used a custom branding header to define our Branding Theme. In my case, I used the following approach: PeopleTools 8.55 Branding

- Delete 'pthdr2signout' element from the custom header (CSK_HEADER_FLUID).
- Save the custom header (CSK_HEADER_FLUID).


Add Custom 'Sign out' element to the Branding Header:



Sunday, August 20, 2017

Fluid UI - Responsive and Mobile-Friendly Tooltip


A good friend asked me if we can add a descriptive tooltip to Fluid UI elements. This reminded me that adding tooltips to page field elements has not been very straight forward with PeopleTools. In Classic, we had a few  options (there may be more):

1. Use the field class - HoverText property. This has many limitations - only works for push buttons or hyperlinks, maximum length of 100 characters, to name a few.
2. Use the page field property (use) - Mouse Over Popup settings. This again is limited to push buttons or hyperlinks. It also involves creating Popup page object.
3. Use application delivered Mouse Over Popup Pages. For example, HCM delivers some configuration that can be used for setting up mouse over popup fields.
4. Custom approach: http://peoplesoftdotnet.blogspot.com/2015/06/hovertext-in-to-edit-box.html

Needless to say, these options may not be very flexible to use with Fluid.

The good news is that in Fluid, we could use the HtmlAttributes field class property to add/update attributes to the page field element. This allows us to add/update the text attribute which is used to display the tooltip. Let us try this and see how it may work.

Test Environment Details:

Application: CS 9.2 PUM Image 4
PeopleTools Release: 8.55.12
Test Component/Page: AV_OUTR_SRCH_S_FL/AV_OUTR_SRCH_FL
Navigation: Fluid Home > Contributor Relations Homepage > Donor Prospects

Using HtmlAttribute to update the text attribute:

The page activate code for AV_OUTR_SRCH_FL page is written the following App Package Method:
App Package Class: AV_OUTR_FL.COMPONENTS.AV_OUTR_S_FL.OnExecute
Method: pageActivate


Let us add some custom code to update the text attribute for page field AV_SRCH_FLDS_WK.LAST_NAME_SRCH.


Delivered Tooltip on larger viewport:


Delivered Tooltip on smaller viewport:


With the hoverover text overflowing the smaller viewport, we can see that the tooltip is neither user-friendly nor responsive.

In a quest to find a user-friendly/responsive option, I stumbled on this resource:
https://osvaldas.info/elegant-css-and-jquery-tooltip-responsive-mobile-friendly
Demo: http://osvaldas.info/examples/elegant-css-and-jquery-tooltip-responsive-mobile-friendly/

The steps provided in Osvaldas's blog are very simple. We just need to load the CSS and javascript provided in the blog and then add the rel="tooltip" attribute to the target page field element. I wanted to take this idea and apply it to PeopleTools (using the above example).

Responsive and Mobile-Friendly Tooltip:

I updated the previous custom peoplecode and added the rel="tooltip" property. Further, I added a javascript object that is improvised on Osvaldas's code.


Custom Tooltip on larger viewport:


Custom Tooltip on smaller viewport:


Implementation Details:

I shared my code - which is based on the blog post by Osvaldo Valutis - on GitHub.
https://github.com/SasankVemana/Fluid-UI-Responsive-Tooltip

PeopleCode:

In the sample peoplecode provided above, you can see that along with the text attribute we have also added the rel="tooltip" attribute to the page field element using the HtmlAttributes property.

CSS:

I modified the CSS provided in Osvaldo's blog to update the tooltip text and background colors. You can make additional modifications if necessary based on your requirement. Create a Free-Form Style Sheet object in App Designer using the CSS (CSK_TOOLTIP_CSS) in the GitHub project.

JavaScript:

I extended the javascript provided in Osvaldo's blog to wrap the code in a require block to facilitate the loading of jQuery using requireJS - which I have detailed in the past as part of a javascript injection framework. You could use an alternate approach for the javascript injection but you need to make sure that jQuery is loaded prior to execution of this javascript. Additionally, this javascript also takes care of loading the CSS (CSK_TOOLTIP_CSS) using helper functions - again part of the javascript injection framework. Create a JavaScript (HTML) object in App Designer using the javascript (CSK_TOOLTIP_JS) in the GitHub project.