Showing posts with label requireJS. Show all posts
Showing posts with label requireJS. Show all posts

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.

Sunday, August 14, 2016

PeopleTools 8.55+ - Fluid UI - Drop-Down Menu/Breadcrumb Navigation vs NavBar/Navigator Conundrum

In this post, I hope to bust some of the myths around the drop-down menu navigation which is "technically" going away in PeopleTools 8.55. There has been a lot of focus on the disappearance of the drop-down menu/breadcrumb navigation as it is not available by default in PeopleTools 8.55 which uses the Fluid header and navigation instead. I have seen several customers (here is a link to just one example of many in various forums) wanting to put it back just the way it was! Note: There are options to do so.

I could understand some of the reasons why customers might want to hold on to the older method of navigation. For example, project timelines and lack of time for managing the change, need to re-write user manuals/guides/documents, training/education, only a small subset of power users/admins use the system so why change?, etc.

A big part of the transition to the Fluid navigation is education which involves recognizing the reasons for the change and the benefits of using the Fluid navigation mechanisms which is very intuitive. For starters, Fluid navigation is more than just the drop-down menu! It involves Homepages, Tiles, Dashboards, WorkCenters, Activity Guides, Related Content, etc. There are plenty of very good resources that demystify the new navigation paradigm in Fluid. Here are a few:

PeopleSoft VFO: https://www.youtube.com/watch?v=oXdvD9rKO_U
PeopleSoft VFO: https://www.youtube.com/watch?v=o5-wQ2dHKsw
Oracle Blog: https://blogs.oracle.com/peopletools/entry/fluid_header_and_navigation_is
LeanItDesign: https://leanitdesigns.wordpress.com/2016/03/28/fluid-navigation-adopting-to-the-new-normal/

In spite of all these attempts to educate our customers and end-users, I am sure there will still be a few who simply insist on having the drop-down navigation. There may also be some users (e.g.: power users) who might legitimately require the drop-down menu style navigation. Here are couple of ways I would sell the Fluid navigation to those users:

Pitch 1: The drop-down navigation is not gone! It is now in a brand new location (NavBar > Navigator) and expands vertically in Fluid. When we use the Navigator, it also remembers the Folder location that was last visited - including 'Back to Previous Folder' and 'Back to Root' capabilities. Effectively, all the functions of the drop-down menu still exist!





Pitch 2: Let us say, my users are not impressed with my previous pitch. They tell me that we now have to click on the NavBar and then click on the Navigator to initiate the menu. Previously, we only had to click on 'Main Menu' and out pops the drop-down menu navigation. These are the hard to sell folks that I am talking about!

For example, let us compare the navigation to the 'Web Profile Configuration' page.
In Classic: Main Menu > PeopleTools > Web Profile > Web Profile Configuration
In Fluid: NavBar > Navigator > PeopleTools > Web Profile > Web Profile Configuration

Granted, they have a point! They have one extra click to complete the navigation (assuming the Navigator was not previously initialized/toggled).

Here is a simple workaround for that! What if we make the 'Navigator' active/selected and expanded when the NavBar is initiated (except for the Small Form Factor devices)? Will this make these users happy? Hopefully, because now the Navigator behaves exactly the same - if not better - when compared to the Classic drop-down menu!

This requires a minor customization as follows:

Step 1: Create a JavaScript Object

PeopleTools > Portal > Branding > Branding Objects


JavaScript: CSK_NB_INIT_JS


Note: I am using requireJS (for managing my jQuery module dependency) that is available as part of Oracle JET in PeopleTools 8.55. You don't necessarily have to use this approach but if you would like more details, then please refer to my posts on Oracle JET (Part 1, Part 2, Part 3 and Part 4).

Step 2: Inject CSK_NB_INIT_JS when PTNUI_NAVBAR page/component is loaded

In my case, I am simply using the Global JavaScript Injection Bootstrap that I described in my previous blog posts. I updated my cskInjectJS function to include the following lines of javascript to load CSK_NB_INIT_JS (created in Step 1). I also check if the current request is not from a small form factor device to avoid auto-selecting the Navigator on small screens like phones (which would cover up the entire screen and might not be desirable).

Update JavaScript Function: cskInjectJS


Note: The following links provide the full JavaScript source code as of this post: CSK_FL_BOOTSTRAP_JS and CSK_INJECT_JS.

Results:

NavBar Initialization Before Customization:


NavBar Initialization After Customization:


Monday, June 13, 2016

PeopleTools 8.55 - Oracle JET - Using ACE Editor for Online Branding Objects (HTML, JavaScript, Style Sheets)

Have you ever wondered if there is a better way to edit the "Branding Objects" that are available online (PeopleTools > Portal > Branding > Branding Objects)?

If you have managed Branding Objects (JavaScript, HTML and CSS) online, you would have noticed that the editor is a simple 'textarea'. It is not a great UI and it makes it really difficult to manage/write anything more than a few lines.

E.g.:


Although it is great that, starting with PeopleTools 8.53, we now have the ability to manipulate javascript, html and css objects online (instead of using App Designer), the major part of reading/understanding/writing the code probably needs to be done outside on a text editor which has better support for the markup/syntax.

Why not a code editor for the web?

If you attended Jim Marion's popular session 'PeopleTools Tips and Techniques' either at Oracle OpenWorld 2015 conference or HEUG - Alliance 2016 conference, you might have seen him show us how he created a custom page to manage javascript content using ACE Editor. When I asked him how he built something like that, he mentioned that he used AJAX to marshal the content and the page itself is fronted by a component for searching, but is really an iScript for display and an iScript for saving. It was a brilliant idea to use a high performance code editor to manage such objects (some features/benefits include auto complete, syntax highlighter for over 100 languages, better maintenance/display of indending/outdending, folding function/code modules and overall better readability).

Jim's approach involved storing the javascript contents in a custom table and then referencing them as needed. I wanted to take the same idea and create a mechanism to integrate ACE Editor with any page field (textarea). At the same time, I did not want to customize anything. So, I want my approach to be very similar to creating/enabling Rich Text page fields but instead of using App Designer, I want to simply inject a custom javascript to the page and enable the ACE Editor. Another difference with my approach is that I want to use JavaScript and the component processor to take care of marshaling and saving the data instead of using the AJAX/IScripts option.

Do any challenges come to mind?

- How do we replace the existing 'textarea' on the page with the ACE Editor?
- Next, how do we transfer the contents of the ACE Editor to the page field 'textarea'?
- Next, how do we make the component processor accept and honor this change made to the buffer via JavaScript (especially because we are not customizing the page and the page field may not have the 'Modifiable by JavaScript' setting enabled)?

Here are steps I went through to integrate ACE Editor with the PeopleTools - Branding Objects Page. If you like this idea and implementation, then please click here to vote for it on My Oracle Support Community.

Note:
  1. A similar approach could be used to extend the ACE Editor functionality to any other page field - textarea.
  2. I used the latest version of my 'Global JavaScript/Style Sheet Injection Bootstrap' (using Oracle JET and more importantly requireJS) to inject a custom javascript into the 'Branding Objects' page. If you choose not to use this approach, then you will need to find an alternative way to inject the custom javascript but the core functionality of the js code should work as described. (Refer: 'Using Oracle JET' series - Part 1, Part 2, Part 3 and Part 4).
Step 1: Download the ACE Editor library and store it locally on the web server

I downloaded the ACE Editor library from the following github URL and placed it on my web server:
https://github.com/ajaxorg/ace-builds/archive/master.zip

Web Server:


Just to show the library folder structure, here is a screenshot highlighting the path to the ace.js file.


Step 2: Add new function cskGetFormName() to our JS Bootstrap (CSK_FL_BOOTSTRAP_JS)

Function Name: cskGetFormName


This function helps us resolve the %FormName meta-html which is not available currently for client side javascript. So, we cannot use it, for example, as submitAction_%FormName in a client side javascript. The expectation is that it would resolve itself to submitAction_win0, submitAction_win1 or submitAction_winN depending on the current window. So, I wrote this function to determine the %FormName portion as a string, which I will be using in the next step as part of FSU_ACE_CFG_JS javascript code.

Step 3: Create Custom JavaScript Object (CSK_ACE_CFG_JS) to configure the ACE Editor on the desired page

JavaScript Object: CSK_ACE_CFG_JS


Explaining the Script:
  • First, you will notice that I am adding the ACE Editor library path to the requireJS configuration locally instead of using the requireJS configuration script object (CSK_REQUIIRE_CFG_JS). The reason I am appending to the requireJS paths locally is because, we don't want this library to get loaded for the entire application, rather just conditionally to a specific page. In step 4, I will detail how to achieve that using the Global Injection Bootstrap (CSK_FL_BOOTSTRAP_JS).
  • Next, I am defining jquery, ace.js and jqueryui as dependencies for the function execution using requireJS.
  • Inside the function execution, I included BOOTSTRAP 3.0.0 (which was downloaded from this link and stored in a custom object) and JQUERY 1.8.17 (delivered object) CSS. I am using the custom function cskLoadCSS to take care of the CSS loading.
  • Next, I search for the textarea (id="PTBR_MGOBJ_WRK_PTBR_HTMLAREA1"), hide it and replace it with the ACE Editor div.
  • Now the delivered textarea is hidden and our custom ACE Editor is in the DOM. Further, I used a basic set of configuration options for the Editor which we can certainly expand depending on our use case (ACE Editor is highly configurable). Also, I am dynamically setting the mode of the Editor to either html, javascript or css depending on the object type that we are updating. As part of the Editor configuration, I also initialized the contents of the ACE Editor with the contents of textarea.
  • Lastly and most importantly, we update the textarea (now hidden) with the latest contents of the ACE Editor any time there is a change in the editor contents. 
  • addchg_%FormName Function: The trick to make the component buffer accept and honor the changes made to the textarea (PTBR_MGOBJ_WRK_PTBR_HTMLAREA1) - via client side javascript - is to use the addchg_%FormName function. I had no idea about the existence of such a function and its significance. I learned about this gem from Chris Malek while discussing and troubleshooting an unrelated issue with Fluid!

Step 4: Conditionally Load ACE Editor Config JavaScript (CSK_ACE_CFG_JS) using the Global JavaScript Injection Bootstrap

The conditional logic to only load CSK_ACE_CFG_JS on the Secondary Page PTBR_ADDHTML_SEC, can be found in the cskInjectJS function which is part of CSK_FL_BOOTSTRAP_JS object. An updated version of CSK_FL_BOOTSTRAP_JS source code can be found here.


Results:

HTML:


JavaScript:


CSS:


Now we are ready to enjoy the ACE Editor for writing code! Once again, if you like this idea and implementation, then please click here to vote for it on My Oracle Support Community.

Monday, May 30, 2016

PeopleTools 8.55+ - Using Oracle JET (JQuery, JQueryUI, requireJS and more) - Part 3

This post is a continuation of PeopleTools 8.55+ - Using Oracle JET to leverage open-source libraries such as JQuery, JQueryUI, requireJS, etc. - Part 1 and Part 2.

In Part 1, I described how to create a JavaScript Injection Bootstrap framework particularly useful for Fluid UI since the Branding System Options only work for Classic. Similarly, let us assume we want to add custom styles to Fluid UI. How do we achieve something like that? We could use the 'Global Override Style Sheet' (CSK_BRAND_FLUID_TEMPLATE) which is part of our custom theme (CSK_THEME_FLUID). This would work just fine if we are either overriding a existing delivered Fluid style class or if we are adding some additional custom styles to the 'Global Override Style Sheet'. But what if we want to load entire style sheets from open source libraries such as JQueryUI? What if we want a configuration that allows us to inject style sheets globally as and when new requirements come up? Wouldn't it be great to have a global style sheet injection framework similar to the 'JavaScript Injection Bootstrap' from Part 1?

Global Style Sheet Injection:

I added a couple of javascript functions to my existing bootstrap javascript object (CSK_FL_BOOTSTRAP_JS).

JavaScript Functions: getCSSUrl(cssId) and cskLoadCSS(path)



As the names suggest, getCSSUrl uses the delivered IScript_GET_CSS to return the URL of a CSS object on the web server cache directory and cskLoadCSS would inject the CSS with a specified source path to the DOM.

CSK_FL_BOOTSTRAP_JS:


Now, we should be able to use the function cskLoadCSS and getCSSURL, (e.g.: cskLoadCSS(getCSSUrl('PSJQUERY_BASE_1_8_17'));...) from any javascript (e.g.: CSK_FL_BOOTSTRAP_JS), to inject style sheets globally across the application. I will demonstrate this in a use case as part of the next section.

Fluid UI - Control + J Alternative using JQuery, JQueryUI and requireJS:

In Part 1 and 2, although we used requireJS as part of Oracle JET, we only employed it for a simple use case of loading the JQuery library. In this section, I will demonstrate how we can use requireJS for a more complex requirement where we will need to load more than one version of the JQuery library along with JQueryUI. This use case is to create an alternative and a device agnostic approach for surfacing the Control + J information to the end users in Fluid UI (click here for more details).

As I mentioned previously, my requireJS configuration was very basic and derived from a delivered example for the purposes of Part I and Part 2. In this section, I will update my requireJS configuration (CSK_REQUIRE_CFG_JS) based on requireJS documentation.

Update JavaScript Object: CSK_REQUIRE_CFG_JS



You can see that I have added the two versions of JQuery to the path mapping as jquery for version 2.1.3 (part of Oracle JET) and jquery_1_7_2 for version 1.7.2 (stored as a custom javascript object CSK_JQUERY_1_7_2_JS and added via Branding Objects). I also added jqueryUI version 1.11.4 which is available as a delivered object - PT_JQUERY_1_X_JS. Lastly, jquery-private takes care of mapping modules to use NoConflict (click here for more details).

Note: The javascripts CSK_FL_DBNAME_JS and CSK_OVERRIDE_IMAGE_JS created in Part 1 and 2 will continue to work with the update version of CSK_REQUIRE_CFG_JS.

Next, I created an updated version of my CSK_FL_CTRL_J_JS javascript object.

JavaScript Object: CSK_FL_CTRL_J_JS



The main difference is that I am using requireJS to load jquery_1_7_2 and jqueryui as dependencies for this javascript. Also, notice that I am using cskLoadCSS function to inject the style sheet PSJQUERY_BASE_1_8_17 (delivered object that contains jQuery UI CSS Framework 1.8.17) and CSK_CONTROL_J_CSS (custom style sheet to manage some quirks with Control + J - JQueryUI Dialog styling).

Style Sheet Object: CSK_CONTROL_J_CSS



Why do we need CSK_CONTROL_J_CSS?

To handle quirks with JQueryUI styling due to using different versions of JQueryUI and JQueryUI CSS.

Quirk 1:


Quirk 2:


Load Fluid Control + J JavaScript (CSK_FL_CTRL_J_JS) using the Fluid JavaScript Injection Bootstrap:

Simply add CSK_FL_CTRL_JS to the cskInjectJS function in CSK_FL_BOOTSTRAP_JS object.


Results:

To invoke the "Troubleshooting Information" dialog, all we have to do is to press the mouse (PC/Mac) or touch the screen (mobile devices) - anywhere on the webpage - continuously for 5 seconds!



Sunday, May 29, 2016

PeopleTools 8.55+ - Using Oracle JET (JQuery, JQueryUI, requireJS and more) - Part 2

In my recent post (click here), I detailed how we could use Oracle JET to safely and efficiently take advantage of some the common open source libraries such as JQuery, JQueryUI, requireJS, etc. I also created a cleaner version of my JavaScript Injection Bootstrap and used it to inject a custom javascript (which uses JQuery) to add an environment specific header for both Fluid and Classic in PeopleTools 8.55.

In this post, I want to continue with that process and re-write the configurable image replacement technique that I described for PeopleTools 8.54 (click here for more details).

IScript for Image Object Source URL Resolution:
 
Reference to the previous version of the IScript: Click here.

Since using meta-HTML such as %Image and %JavaScript does not work in JavaScript objects, I created my own version of  an IScript which returns the URL referencing an image object on the web server (loaded on the cache directory).

WEBLIB_FL_CSK.ISCRIPT1.FieldFormula - IScript_CSK_GET_IMG


PeopleCode for reference:

Function IScript_CSK_GET_IMG
  
   Local string &img = %Request.GetParameter("img");
  
   &url = %Response.GetImageURL(@("Image." | &img));
   %Response.RedirectURL(&url);
 
End-Function;


Create a custom javascript function and add it to the JavaScript Injection Bootstrap (CSK_FL_BOOTSTRAP_JS):

This function would help us to mask some of the details to access the preceding IScript to get the Image URL (similar to the getScriptURL function which I borrowed from Jim Marion's blog).

Function Name: getImageURL


Let us add this function to the JavaScript Injection Bootstrap:


Configurable JavaScript for Image Replacement (CSK_OVERRIDE_IMAGE_JS):

Object Name: CSK_OVERRIDE_IMAGE_JS



This javascript object CSK_OVERRIDE_IMAGE_JS is a re-write of my previous version which was called CSK_FL_IR_JS. You will notice that I am using requireJS to load the JQuery library that I need for this function execution. I am also using the getImageUrl function which I previously detailed to get the URL of the custom images. These URLs will be used to override the corresponding delivered counterparts. Right now, I have two examples for image replacement: 1) Replace the delivered Favorite Icon with a custom image (CSK_LOGO_FAVICON) and replace the delivered 'Processing' icon for Fluid with a custom image (CSK_PROCESSING_FMODE).

LOGO_FAVICON (delivered):


CSK_LOGO_FAVICON (custom):


PT_PROCESSING_FMODE (delivered):


CSK_PROCESSING_FMODE (custom):


Similarly, we can configure additional image replacements by simply appending code to the CSK_OVERRIDE_IMAGE_JS javascript object.

Load Image Replacement JavaScript using the Fluid JavaScript Injection Bootstrap:

Simply add CSK_OVERRIDE_IMAGE_JS to the cskInjectJS function in CSK_FL_BOOTSTRAP_JS object.


Results:



Saturday, May 28, 2016

PeopleTools 8.54+ - Branding System Options - Additional JavaScript Objects

I noticed something interesting with the Branding System Options - Additional JavaScript Objects feature in PeopleTools 8.54+ environments that allows us to inject javascripts in all Classic pages/components.

If we add javascript objects to the Branding System Options, then it is possible that the javascript could fire more than once.


For the purpose of this demonstration, the javascript just does a simple print to the console.


Let us see this in action.


As you can see above, I first navigated to the Classic Homepage and found that the javascript may have fired more than once - notice the 2 preceding the 'Hello...' message in the Console. Let us now inspect the document elements and find our script in the DOM.

Classic Homepage:

You can see that there are 3 occurrences of the script name (CSK_CLASSIC_TEST_JS) in the DOM. The first one is in the head element (which is probably the expected location), the second one is again in the head element (with an ID of HC_UX_SRCH_PLT_GBL_8_HAScript) and the last one is in the body under HC_UX_SRCH_PLT_GBL pagelet which I am assuming is part of the Company Directory pagelet.




 Now, let us navigate further to a Classic component. We can see in the console again that the javascript has fired more than once.


Let us now inspect the document elements and find our script in the DOM.

Classic Component:

You can see that there are 2 occurrences of the script name (CSK_CLASSIC_TEST_JS) in the DOM. The first one is as expected in the head element and the second one is in the 'Target Content' frame.



What is the problem?

Well, there is nothing wrong with the way it works. In some cases, it may be desired that the javascript gets fired several times, once per header, pagelet, target frame, etc.

But it is good to keep this in mind when we are trying to inject javascript libraries into the application which we generally want to load only once per page. In such cases, we might find some inconsistent results if we use the Branding System Options. In such scenarios, it is probably best to utilize requireJS - one of the most popular frameworks around for managing dependencies between modules which is now delivered with 8.55 as part of Oracle JET. Click here for an example of how to use requireJS in PeopleTools 8.55+ applications.

Friday, May 27, 2016

PeopleTools 8.55+ - Using Oracle JET (JQuery, JQueryUI, requireJS and more) - Part 1

If you followed some of my previous posts related to Fluid Branding, you would have noticed that I complained a fair bit about 8.54 and 8.55 not delivering jQuery by default for Fluid UI. Although, I still think that it is a missing feature in 8.54, I found that Oracle has delivered something better in 8.55. This is not really mentioned in great detail anywhere, but if you look on the web server, you will find that Oracle JET (Oracle JavaScript Extension Toolkit) is available. For those who are not aware, it is like a package of all the commonly used open-source js and css libraries put together. In addition to the open-source libraries, Oracle JET also contains a set of Oracle contributed js libraries.

Web Server:


Oracle JET usage in charts:

I also noticed this in a few Fluid pages containing charts, when I inspected the DOM elements. I have not seen widespread usage in other areas.


If you have read some of my previous Fluid Branding posts (Part 5B and Part 5C) where I described how I created a Fluid JavaScript Injection Bootstrap and few other advanced Branding topics using JavaScript and JQuery, you would notice that I hacked (for lack of a better term) my way through the requirements. I will admit that my js code was probably not the most efficient. In this post and perhaps other follow up posts (Part 2 and Part 3), I plan to revisit some of the javascript and rewrite the logic using Oracle JET (e.g.: Fluid JavaScript Injection Bootstrap and Environment Specific Header for Non-Prod databases).

In the following sections, I intend to cover the topic of using JQuery and JQueryUI libraries safely in conjunction with requireJS - available in Oracle JET on PeopleTools 8.55+ applications. When I say 'safely', I mean to safely manage dependencies using requireJS. Jim Marion has already written about how to achieve this in an 8.54 environment (and probably in several other posts on his blog where he covered the usage in previous tools versions as well).

If you are a fan and a follower of Jim Marion's PeopleSoft Journal blog (like myself) and if you are wondering why he has been relatively quiet (for his standards) in the past few months, he has been blogging all along at a ferocious pace and putting out some great content on Oracle JET in his new blog Jim's JavaScript Journal - tailored for javascript and Oracle JET applicable to all users and not specific to PeopleSoft!!! :)

Global JavaScript Injection Bootstrap for Fluid UI:

My requirements for this bootstrap are still the same as in 8.54. Since there was and still is no way to inject custom javascripts globally in Fluid, I want to create a least intrusive and highly configurable bootstrap to easily inject javascripts on the fly.

Step 1: Create a custom javascript object for the Bootstrap code

Navigation: Navigator > PeopleTools > Portal > Branding > Branding Objects (JavaScript Tab)

Note: This javascript object needs to be added online so that it provides a configuration to inject additional javascript objects.

Object Name: CSK_FL_BOOTSTRAP_JS


- This javascript object might seem a lot lengthier than my previous version but it should be cleaner and a lot more efficient.
- getScriptUrl: I borrowed this function from Jim Marion's post. It provides a nice and clean way to derive the URL for a javascript object.
- cskLoadJS: I improvised this function from the delivered loadScript function (PT_CHART_LOAD). It helps with adding a javascript (with URL to the source code) as a script element to the DOM - head section.
- cskInjectJS: I created this function just to separate the actual configuration to add/load a list of custom javascripts. Right now it only has one custom javascript.
- Immediately invoked javascript code:
  1.  Load requireJS: The first thing I do is to load requireJS. You will notice that I am not referencing any object from the database (as a javascript object) and instead I am pointing directly to the require.js library on the web server where Oracle JET resides. Much easier to render directly from the web server!
  2. Load CSK_REQUIRE_CFG_JS: Next I load a custom javascript object (again added online so it can be updated in the future). My requirejs.config is very simple at this stage and I only included couple of library paths (JQuery and JQueryUI). We could configure additional paths in the future based on other requirements.
  3. You will notice that I am passing cskInjectJS as a callback function parameter to cskLoadJS function when I load the CSK_REQUIRE_CFG_JS object. This would ensure that cskInjectJS would get fired after the CSK_REQUIRE_CFG_JS javascript is loaded.
Object Name: CSK_REQUIRE_CFG_JS


Step 2: Add custom code to PT_HEADERPAGE.Activate (Page Activate PeopleCode)

This step is the same as what I did in 8.54. PT_HEADERPAGE is a header page that is part of all Fluid UI components and is mainly used for navigation purposes. We will be adding a line of code to inject our bootstrap javascript using peoplecode.


Custom PeopleCode:

/* CSK Custom Javascript Bootstrap for Fluid - Start */
AddJavaScript(HTML.CSK_FL_BOOTSTRAP_JS);
/* CSK Custom Javascript Bootstrap for Fluid - End */


Step 3: Add CSK_FL_BOOTSTRAP_JS to the custom Homepage Header (Classic)

Step 2 takes care of the Fluid UI and associated components. Although, in 8.55, the navigation header is unified and consistent across Classic and Fluid, the way Classic and Fluid get rendered are slightly different. The PT_HEADER page object is not used in Classic. This means that step 2 would have no effect in the Classic homepages and components. We could just add CSK_FL_BOOTSTRAP_JS to the Branding System Options (as I previously showed in my Branding 8.55 post). But I want to avoid that because I found that adding scripts to Branding System Options could invoke them more than once which is not desired in this case (I will write about this topic in a separate post later). Alternatively, I simply add CSK_FL_BOOTSTRAP_JS to my custom homepage header configured on my theme (refer: Branding 8.55 - Part 1).


Step 4: Inject Javascript

Now that we have our custom javascript object (CSK_FL_BOOTSTRAP_JS) injected into all Fluid UI and Classic homepages and components, we can use that as a configuration to further inject other javascript objects.

 
Right now, I only added one javascript object CSK_FL_DBNAME_JS (which I will describe in the next section) to cskInjectJS. But you can see how we can easily inject additional javascript objects as needed.

Creating an environment specific header for Non-Production databases:

In the previous section, I described how to create a javascript injection bootstrap for Fluid. I used Oracle JET to load JQuery and JQueryUI while managing dependencies using requireJS. Now, let us see an example of how we can inject a custom javascript using the bootstrap. The custom javascript is a rewrite of my previous javascript (created for 8.54 and extended for 8.55), to create an environment specific header for Non-Production databases.

Object Name: CSK_FL_DATABASE_JS


You can see how I used requireJS to take care of loading JQuery for me. All I am doing is mentioning the libraries that I need and let requireJS do the dependency management! A lot cleaner!

Note: Please remember to add the custom styles to both the Classic - Theme Style Sheet (CSK_BRAND_CLASSIC_TEMPL_FLUID) and the Global Override Style Sheet for Fluid (CSK_BRAND_FLUID_TEMPLATE). Refer Branding PT 8.55 - Part III for more details.

Results:

Classic:


Fluid:


Notes:

  1. Details of the environment used for this post: HCM 9.2 - PUM Image 17 - PeopleTools 8.55.03.
  2. If you find any inconsistent results while going through any of the steps detailed in this post then please make sure you bounce your web and app servers and purge the cache.