Quantcast
Channel: Sasank's PeopleSoft Log
Viewing all 132 articles
Browse latest View live

PeopleTools 8.54+ - Branding - Part 5D - Fluid Branding (Continued)

$
0
0
Overriding the "Processing" Icon:


This requirement is similar to overriding the Favorite Icon. The "Processing/Spinning" icon generally appears when the PeopleSoft PIA is still processing a request. This "Processing" icon is simply a GIF image - PT_PROCESSING_FMODE delivered image object. In some scenarios, this delivered icon may not really fit in with the custom Branding theme. If we want to override this icon then there are two options.

Option 1: Replace delivered GIF image object PT_PROCESSING_FMODE with a custom GIF image object. This is not something I would recommend but it is an option for those looking for a quick and dirty override (along the lines of Doc ID 2004996.1).

Option 2: Use the jQuery image replacement technique detailed in the previous post for overriding this delivered image PT_PROCESSING_FMODE with a custom image (CSK_PROCESSING_FMODE).

I am using the following image as my custom "Processing" icon:


Delivered PT_PROCESSING_FMODE image for reference:


I am updating my image replacement javascript object CSK_FL_IR_JS again. I am finding all the occurrences of PT_PROCESSING_FMODE (delivered image) with id = "processing" and replacing it with a custom image (CSK_PROCESSING_FMODE) using jQuery.


Updated javascript (CSK_FL_IR_JS) for reference:

// Get Image URL for CSK_LOGO (FavIcon);
document.write(unescape("%3Cscript src='/psc/" + site + "/EMPLOYEE/EMPL/s/WEBLIB_FL_CSK.ISCRIPT1.FieldFormula.IScript_Set_Image_URL_Variable?var=cskFavIcon&img=CSK_LOGO_FAVICON' type='text/javascript'%3E%3C/script%3E"));

// Get Image URL for CSK_LOGO (Fluid);
document.write(unescape("%3Cscript src='/psc/" + site + "/EMPLOYEE/EMPL/s/WEBLIB_FL_CSK.ISCRIPT1.FieldFormula.IScript_Set_Image_URL_Variable?var=cskLogo&img=CSK_LOGO_SVG' type='text/javascript'%3E%3C/script%3E"));

// Get Image URL for CSK_LOGO (Fluid SFF);
document.write(unescape("%3Cscript src='/psc/" + site + "/EMPLOYEE/EMPL/s/WEBLIB_FL_CSK.ISCRIPT1.FieldFormula.IScript_Set_Image_URL_Variable?var=cskLogoSFF&img=CSK_LOGO_SFF_SVG' type='text/javascript'%3E%3C/script%3E"));

// Get Image URL for CSK Custom Processing Icon for Fluid;
document.write(unescape("%3Cscript src='/psc/" + site + "/EMPLOYEE/EMPL/s/WEBLIB_FL_CSK.ISCRIPT1.FieldFormula.IScript_Set_Image_URL_Variable?var=cskProcessingFmode&img=CSK_PROCESSING_FMODE' type='text/javascript'%3E%3C/script%3E"));

var $jq = jQuery.noConflict();
$jq(document).ready(function(){

  // Get current Image Source;
  var imageSrc = $jq('#PTNUI_LP_HEADER_PTNUI_LOGO img').attr('src');

  if (imageSrc != null) {
    if (imageSrc.indexOf("PTNUI_ORACLE_LOGO_SFF") < 0) {

      // Use Regular Image;
      $jq('#PTNUI_LP_HEADER_PTNUI_LOGO img').attr('src', cskLogo);

    } else {

      // Use Small Form Factor Image;
      $jq('#PTNUI_LP_HEADER_PTNUI_LOGO img').attr('src', cskLogoSFF);

    }
  }

  // Replace Browser Favorite Icon(s);
  $jq('head link[href*=LOGO_FAVICON]').attr('href', cskFavIcon);

  // Fluid Processing Icon;
  $jq('#processing').attr('src', cskProcessingFmode);

});


Result:


Check out this demo video >>>>Override Processing Icon

Fluid UI - Native Device Features - Camera for Scanning Credit Card Details

$
0
0
While paying a bill on my phone (Samsung S4), I accessed a responsive web application and found an interesting feature that allowed me to scan my credit card details (card number, name and expiration date) using the device camera/scanner as an autofill option. I liked this functionality because I am not a great fan of typing on the mobile phone so I would welcome anything that would save me from doing that! Also, it is interesting particularly because this was just a web application without any native app wrapper (mobile app). So, it appears that we could still tap into some of the native device features with just a web application which means we should be able to implement this functionality with PeopleSoft Fluid as well - without any mobile/native app wrapper.

I started digging into similar features available in PayPal and Amazon and arrived at the following combinations of id, placeholderand autocompleteattributes for iOS/Safari and Android/Chrome. Note: This only works via HTTPS for both the scenarios. Please weigh in any security risks that might be associated with saving credit card details on the browser. This post is just a proof of concept to demonstrate the usage of the device camera as an image to text utility.

iOS/Safari:

I believe the minimum requirement to enable this feature in iOS/Safari is iOS 8.

You can test the code on an iPhone/iPad using the following jsFiddle web page which I created as a sample.
https://jsfiddle.net/SasankVemana/asam6hro/


Android/Chrome:

You can test the following code on any Android device using the following jsFiddle web page which I created a sample.
https://jsfiddle.net/SasankVemana/21zt0sbm/


How do we implement this in Fluid?

Let us assume that we have a Fluid page that is used as a form for credit card payments.

Fluid Credit Card Form:

A simple Fluid page based on PSL_APPS_CONTENT layout page.



Fluid Page Field Properties (Page Field Name and Placeholder):

CSK_CC_TEST_WRK.CSK_CC_NBR



Repeat for other fields on the page:

CSK_CC_TEST_WRK.CSK_CC_NAME
- Page Field Name: CCNAME
- Placeholder Text: Cardholder Name

CSK_CC_TEST_WRK.CSK_CC_EXP
- Page Field Name: CCEXP
- Placeholder Text: Expiration Date

CSK_CC_TEST_WRK.CSK_CC_CSC
- Page Field Name: CCCSC
- Placeholder Text: CVV (3-4 Digits)

Page Activate PeopleCode:

This takes care of couple of tasks:
- For safari browsers: Inject jQuery and a custom javascript (CSK_CC_SAFARI) which replaces the capitalized ID value (e.g.: id = 'CCNUMBER') with the mixed case ID value (e.g.: id = 'ccNumber'). Refer following section for more details.
- For chrome browsers: Include the autocomplete attribute for all the credit card form fields.


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 */

/* Get Browser Type */
Local string &browserType = %Request.BrowserTypeClass;

Evaluate &browserType
When "safari"
  
   /* Inject jQuery */
   AddJavaScript(HTML.PT_JQUERY_1_6_2_JS);
  
   /* jQuery to replace id attribute with mixed case */
   AddJavaScript(HTML.CSK_CC_SAFARI);
  
   Break;
When "chrome"
  
   /* Set autocomplete attributes */
   CSK_CC_TEST_WRK.CSK_CC_NBR.HtmlAttributes = "autocomplete=""cc-number""";
   CSK_CC_TEST_WRK.CSK_CC_NAME.HtmlAttributes = "autocomplete=""cc-name""";
   CSK_CC_TEST_WRK.CSK_CC_EXP.HtmlAttributes = "autocomplete=""cc-exp""";
   CSK_CC_TEST_WRK.CSK_CC_CSC.HtmlAttributes = "autocomplete=""cc-csc""";
  
   Break;
End-Evaluate;


CSK_CC_SAFARI Javascript:

As mentioned in the previous section, the ID attribute as implemented using PeopleSoft Page Field Name Property is always generated in a capitalized format. Potential tools enhancement???

E.g.:


CSK_CC_SAFARI javascript object is used to replace these ID values in a mixed case format using jQuery.


Javascript for reference:

Results:

iOS - iPad:


Android - Samsung Galaxy S4:


References:

https://www.paymentspring.com/blog/hacking-form-cardscan
http://stackoverflow.com/questions/25163891/when-scan-credit-card-option-is-available-on-ios8-safari
http://stackoverflow.com/questions/7223168/how-to-trigger-autofill-in-google-chrome/9795126#9795126
https://www.w3.org/TR/mediacapture-streams/
https://www.w3.org/Mobile/mobile-web-app-state/#Payment
https://html.spec.whatwg.org/multipage/forms.html

Fluid UI - CTRL+J - On Mobile Devices

$
0
0
Our fellow blogger, Frank Staheli, brought to our attention that the traditional CTRL+J (CONTROL+J hot key) does not work on all Fluid pages (refer blog post link). The alternative described by Frank is very useful! I had no idea that the CTRL+J data is actually part of the HTML rendered to the end user. So, if we "view source" on the browser, we can find all the creamy goodness in the HTML for troubleshooting purposes.

When I searched for more information on this topic on My Oracle Support, I found the following document which suggested the same approach for retrieving the CTRL+J information.

E-FLUID : How to view page information/ctrl+j in Android Mobile/Tablets (Doc ID 2094279.1)

I have two issues with suggesting this approach to a broader audience outside of technical folks: 

End Users: I am guessing that even some of the functional users (let alone end users) will not be very happy if we tell them that the traditional CTRL+J hot key is no longer available in Fluid/mobile devices and that they have to use "view source" on the browser to identify the "troubleshooting information". Not everyone is tech-savvy and would be happy to go under the hood of the web browser! I have seen many organizations use the CTRL+J hot key for production troubleshooting. For example, to identify what app server the end user is on. So this feature has more value than one might assume.

Mobile Devices: How do we make the "view source" instructions device agnostic? There could be several different scenarios depending on the device and the browser used. It could get pretty complex!

I wanted to take the elements which I learned on Frank's blog (pt_envinfo and pt_pageinfo buried in the HTML) and see how we can provide a device agnostic and an intuitive mechanism for all type of users to access this information.

I played with some jQuery/jQuery UI code and came up with the following script:
http://jsfiddle.net/SasankVemana/cfcxg5un/

You can access this code (jsfiddle sample webpage) on any device/browser and see how it works. If you either press the mouse (if you are on a PC/Mac) or touch the screen (if you are on a mobile device) and hold for 5 seconds anywhere on the webpage, then a responsive dialog will open up with the troubleshooting information. The javascript listens to mouse and touch events and displays the dialog message if 5 seconds have passed.

E.g.:

PC/Chrome:


Samsung Galaxy S4/Chrome:


Now that we have a proof of concept, how do we integrate it with Fluid? It is simple - we just need to inject the following globally across the application:

Javascripts: jQuery 1.7.2, jQuery UI 1.8.17 - PT_JQUERY_UI_1_8_17_JS, custom script from jsfiddle
CSS: jQuery UI CSS - PSJQUERY_BASE_1_8_17

Step 1: Inject Javascripts in Fluid

First, we need to create two custom javascript objects.

CSK_JQUERY_1_7_2_JS: I created a custom object with the contents of jQuery 1.7.2 because I did not find any delivered object with that particular jQuery version. I needed this version for the dialog display and styling (you could use other available libraries and adjust the custom javascript accordingly).


CSK_FL_CTRL_J_JS: This is to store the custom javascript from my jsfiddle example.


Note: We can adjust the number 5000 (ms => 5 seconds) in the above script to alter the hold time if necessary.

There are two options for injecting the required javascripts globally across the application.

Option 1:

Add the following code to the PT_HEADERPAGE.Activate Page PeopleCode event. This PeopleCode event is triggered on all Fluid pages.

/* CSK CONTROL+J Start */

AddJavaScript(HTML.CSK_JQUERY_1_7_2_JS);
AddJavaScript(HTML.PT_JQUERY_UI_1_8_17_JS);
AddJavaScript(HTML.CSK_FL_CTRL_J_JS);

/* CSK CONTROL+J End */

Option 2:

We can use the custom Fluid Bootstrap configuration for JS injection which I described in my previous post (refer: Fluid Branding Part 5B).


Step 2: Inject CSS in Fluid

We just need to inject the jQuery UI CSS which is already delivered as part of PSJQUERY_BASE_1_8_17 stylesheet object.

There are two options for injecting this CSS.

Option 1:

Append the contents of PSJQUERY_BASE_1_8_17 stylesheet to the Custom Fluid stylesheet on the Branding Theme (Refer: Fluid Branding Part 5A).

Option 2:

This is the easier option. To just add one line of code to PT_HEADERPAGE.Activate Page PeopleCode.

AddStyleSheet(StyleSheet.PSJQUERY_BASE_1_8_17);


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! I tested this on several devices (PC/Mac/Samsung S4/Samsung S5/iPhone 6/iPad), browsers (safari/firefox/chrome/IE) and Chrome Device Emulator and it seems to work. Please test thoroughly before you deploy this solution to any environment.

PC/FireFox


Chrome Device Emulator/iPhone 6


Chrome Device Emulator/Samsung S5


Note: This dialog box will not contain any useful information if the web profile which is in use has the 'Show Connection & Sys Info' setting turned off. This is the setting required for the CTRL+J information to be displayed.

Navigation: Main Menu > PeopleTools > Web Profile > Web Profile Configuration


Please help vote up this idea if you think it would be beneficial to include this as an enhancement rather than using a custom approach.
Refer:My Oracle Support Community Ideas

Fluid UI - Custom Development - Back Button History

$
0
0
I recently came across a requirement that made me aware of a new and interesting design consideration for Fluid development. When we design and develop Classic pages, we never had to worry about a 'Back' button and how it behaves in the context of user navigation.

Fluid 'Back' Button:



Let us say that we made a customization to the 'Personal Details' page that on page load, we redirect/transfer the users to a custom component/page and then once done with custom activity we redirect/transfer them back to the 'Personal Details' page. Now if the user clicks on the 'Back' button on the 'Personal Details' page, we expect them to go back to the Fluid Home Page. But since we had an additional custom navigation, the user navigation 'History' alters the behavior of the 'Back' button. Sometimes, it may be desirable but what if it is not how we wanted to navigation to flow? How do we control the 'Back' button behavior and user navigation 'History'?



In my example, the 'Personal Details' page redirects to 'Custom Activity' page. Once we click 'Continue' (custom activity) the user gets redirected to the 'Personal Details' page.




There is a very simple solution to this problem and it involves just invoking a delivered function. But before I provide that solution, I wanted to share what I learned in the process. It is interesting to know how it works behind the scenes. This is just for informational purposes and it is not recommended unless you have a really complex requirement!

My Initial Approach:

Since, I could tell that there is some javascript that is tracking the user navigation, my first thought was to write some custom javascript to manipulate the 'History'.

Basically, I realized that we had to either prevent or clean up behind this AddToHistory function in the page javascript.


After digging into delivered javascripts, I found the clearHistory() function in the delivered PT_COMMON HTML object.


If we use the delivered clearHistory function, then it would clear the entire 'History' except the last navigation. So, I created a custom function (cskClearHistory) based on the delivered code. My custom function removes everything from the 'pt_history' object except for the first item (which should be the Home Page). I am sure there could be a better way to manipulate the 'History' and make the javascript more efficient but this seems to work for a proof of concept!


Javascript for Reference:

function cskClearHistory() //can be called by app component
{
    var pt_history = getHistoryObject();
    if (!pt_history ||  pt_history.size() <=1) return;

    // Pop everything out except first item (Home Page)   
    while(pt_history.size() > 1) {
       var lastRec = pt_history.pop();
    }
    pt_history.save();
}

I just invoked this javascript on my custom page activate peoplecode event as follows:


Now, when I navigate the same route (Employee Self Service (Home Page) > Personal Details --redirect--> Custom Activity --continue--> Personal Details, the 'Back' button points back to the 'Home Page' as expected/desired.


After writing this javascript and getting this to work as expected, I realized that this is still not a very efficient way of managing the user navigation 'History'. Sure, the javascript manipulation of the 'History' might be useful for some more complex scenarios (which was the purpose of my demonstration above) but definitely not a great idea for simple page transfers. Eventually, after digging into some of the existing Fluid pages, I found that there is a delivered function called SetTransferAttributes that helps us with these sort of transfers.

PeopleBooks Reference


Recommended Approach:

I got rid off all the custom javascript that I injected on page activate peoplecode. I just added this one line of code to my 'Continue' button before the transfer to set the transfer attributes appropriately.


PeopleCode: SetTransferAttributes(False, False);

Working with Rich Text Editor - Custom Configuration, Toolbars and Plugins - Part 2

$
0
0
Modifying the Enter key (line breaking) behavior:

There was a question in the OTN forum asking if we could alter the default behavior of the ENTER key in the context of the CKEditor (RTE field) content area. Say, we want to change it to insert a line break <br/> element instead of the default paragraph <p> element?

We can refer to the following resource for the configuration change that is required:
Enter Key | CKEditor.com

In my previous post on CKEditor and RTE fields in PeopleSoft, I detailed how we can reference a custom configuration for RTE fields.

Assuming that we already have a custom configuration associated with our RTE field, we just need to add this line to our configuration (HTML) to change the ENTER key behavior to <br/> instead of <p>.

CKEDITOR.config.enterMode = CKEDITOR.ENTER_BR;

Setting a Default Style (Font) for the CKEditor:

There was also a follow up question asked which was removed by the author later. I am assuming that the author found a solution/workaround. But I have a copy of the question which describes the requirement.

If we enter any text in the Rich Text Editor as follows:


It gets stored in the database without any default styling:


This behavior might be desired in most cases but the requirement is to set a default font for the paragraph element so that it gets stored as follows (without users having to manually select the default font every time):


I tried to search for a custom configuration that allows us to set a default font to the editor and found the following useful resources:

http://ckeditor.com/forums/CKEditor-3.x/Setting-Default-Font-and-FontSize-Setting-Default-Labels
http://ckeditor.com/forums/CKEditor-3.x/CSS-style-sheet-for-content-area
http://ckeditor.com/forums/CKEditor-3.x/How-do-you-set-default-font-and-default-font-size
https://www.cotonti.com/forums?m=posts&q=6421

Based on a popular suggestion, I tried adding the following line to the custom RTE configuration:
CKEDITOR.config.font_defaultLabel = 'Arial';

But font_defaultLabel property only sets the default label for the Font in the RTE Toolbar but it does not affect the contents of the editor in any way unless we explicitly select the Font (manually).

The only workaround that I found was to write a 'script' to initialize a placeholder text and wrap it around a <span> attribute with the desired styling. This would make sure that the content area gets initialized with a default font.

Refer:http://stackoverflow.com/questions/16339258/ckeditor-4-how-to-set-default-font

I adjusted the 'script' to only trigger the default font initialization when there is no existing content in the editor (on add mode). This would ensure that we are not overwriting any of the existing contents with the placeholder text.

Script for reference:

CKEDITOR.on( 'instanceReady', function( ev ) {

     if (ev.editor.getData() == '') {
             ev.editor.setData('<span style="font-family:georgia,serif">PlaceHolder&nbsp;Text</span>');     
     };
});

Custom RTE Configuration:


Results - On Add Mode:


Results - After replacing the place holder text:


Results - Contents in the database:


Results - On Update Mode:


PeopleTools 8.55.x - Branding - Part II

$
0
0
This is a continuation of my previous post where I detailed some of the new Branding features and configuration options available in PeopleTools 8.55. This post is intended to provide guidelines for accomplishing some common Branding tasks in PeopleTools 8.55. You will notice that majority of the tasks would only require simple configuration changes as opposed to making customizations or even writing many custom styles (Branding - Part 5A - describes the steps involved in Branding Fluid applications in PeopleTools 8.54). There are also reference links on the following tasks to compare with the effort involved in 8.54. This might be quite lengthy but hopefully you will find the steps useful!

Changing the Header Background Color:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set to override PT_BANNER_BACKGROUND_IMAGE macro with an appropriate linear-gradient.


Results:



Steps in 8.54: Click here.

Changing the Hover Over and Active Background Color for the Home, Notifications and Action Menu Icons:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_BANNER_BUTTON_BACKGROUND_COLOR_ACTIVE
PT_BANNER_BUTTON_BOXSHADOW
PT_BANNER_BUTTON_BOXSHADOW_ACTIVE
PT_BANNER_BUTTON_TRUE_BG_COLOR_HOVER
PT_BANNER_BUTTON_TRUE_BXSHADOW_ACTIVE
PT_BANNER_BUTTON_TRUE_BXSHADOW_HOVER

Note: In my case, I set the box shadow color to be the same since I did not need a box shadow. You can adjust these macros as per your requirements.


Results:



Steps in 8.54: Click here.

Changing the Background and Hover Over Color for the NavBar Icon:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_BANNER_NAVBAR_BACKGROUND_ACTIVE
PT_BANNER_NAVBAR_BACKGROUND_HOVER
PT_BANNER_NAVBAR_BACKGROUND_IMAGE
PT_BANNER_NAVBAR_BOXSHADOW


Results:



Steps in 8.54: Click here.

Changing the Left Border for the NavBar Icon:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_BANNER_NAVBAR_SIDE_BORDER_COLOR


Results:


Steps in 8.54: Click here.

Changing the Background Color of the Fluid Landing Page - Tile Area:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_HOMEPAGE_BACKGROUND


Results:


Steps in 8.54: Click here.

Changing the Branding Header - Bottom Border:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_BANNER_BORDER_COLOR
PT_HOMEPAGE_BANNER_BORDER_COLOR


Results:



Steps in 8.54: Click here.

Changing the Fluid Homepage Title Selector Text Color:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_HOMEPAGE_TITLE_SELECTOR_TEXT_COLOR


Results:


Steps in 8.54: Click here.

Changing the Background Color on the Fluid Landing Page Footer:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_HOMEPAGE_FOOTER_BACKGROUND


Results:


Steps in 8.54: Click here.

Changing the Icons on the Header and Footer:

Let us use the following custom images for overriding the delivered icons:

Home: PT_HEADER_HOME > CSK_HEADER_HOME
Notification: PT_HEADER_ALERTS > CSK_HEADER_ALERTS
Search: PT_HEADER_SEARCH > CSK_HEADER_SEARCH
Actions List: PT_HEADER_ACTIONS > CSK_HEADER_ACTIONS
NavBar: PT_HEADER_NAVBAR > CSK_HEADER_NAVBAR
Homepage Selection Drop-Down: PTNUI_DOWN_ARW > CSK_NUI_DOWN_ARW
Refresh: PTNUI_REFRESH_ICN > CSK_NUI_REFRESH_ICN


NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_BANNER_HOME_IMAGE
PT_BANNER_NOTIFY_IMAGE
PT_BANNER_SEARCH_IMAGE
PT_BANNER_ACTIONLIST_IMAGE
PT_BANNER_NAVBAR_IMAGE
PT_TITLE_SELECTOR_IMAGE
PT_HOMEPAGE_REFRESH_IMAGE


Results:



Steps in 8.54: Click here.

Changing the color of the Content Page Title Text:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_BANNER_TEXT_COLOR


Results:

Note: This change only works for Fluid Page and does not override the Classic Page Titles.



To update the title text color on Classic pages, make the following style sheet overrides using the custom Classic - Theme Style Sheet - CSK_BRAND_CLASSIC_TEMPL_FLUID (Click here for more details).

NavBar > Navigator > PeopleTools > Portal > Branding > Branding Objects

Edit CSK_BRAND_CLASSIC_TEMPL_FLUID and set color to rgba(29,65,140, 0.95)for pthdr2pagetitle selector.


Results:


Steps in 8.54: Click here.

Changing the Icon and Styling on the 'Back' Button:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_BANNER_BACK_BACKGROUND_COLOR_ACTIVE
PT_BANNER_BACK_BACKGROUND_COLOR_HOVER
PT_BANNER_BACK_BACKGROUND_IMAGE
PT_BANNER_BACK_BACKGROUND_IMAGE_ACTIVE
PT_BANNER_BACK_BACKGROUND_IMAGE_HOVER
PT_BANNER_BACK_BORDER_BOTTOM_COLOR
PT_BANNER_BACK_BORDER_BOTTOM_COLOR_HOVER
PT_BANNER_BACK_BORDER_COLOR
PT_BANNER_BACK_BORDER_COLOR_HOVER
PT_BANNER_BACK_BOXSHADOW
PT_BANNER_BACK_BOXSHADOW_ACTIVE
PT_BANNER_BACK_BOXSHADOW_HOVER
PT_BANNER_BACK_IMAGE
PT_BANNER_BACK_TEXT_COLOR
PT_BANNER_BACK_TEXT_COLOR_HOVER
PT_BANNER_BACK_TEXT_COLOR_ACTIVE


Note: You may also need to adjust other PT_BANNER_BACK* macros depending on your custom styles.

Results:


Steps in 8.54: Click here.

Changing  the color of the new Notification Badge:

This seems to be a new feature of PeopleTools 8.55 and I don't recall seeing this in 8.54.


NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and override the following macros:
PT_BANNER_BUTTON_BADGE_BORDER_COLOR
PT_BANNER_BUTTON_BADGE_TEXT_COLOR


Results:


Changing the Dot Styling on the Fluid Landing Page Footer:

Unfortunately, this style override is not yet supported as part of the macros. So, we need to fall back to the previous method of overriding the styles.

NavBar > Navigator > PeopleTools > Portal > Branding > Branding Objects

Edit the custom Fluid - Global Override Style Sheet (CSK_BRAND_FLUID_TEMPLATE) and include the following style at the very end of the style sheet.

.lpfooter .dot.on {
  background: #EEEB4D;
}
.lpfooter .dot {
  background: #E8E29E;
  border: 2px solid #1d418c;
}


Results:


Steps in 8.54: Click here.

In the next post, I intend to cover some more advanced branding tasks including steps to create custom marcos using the Branding Theme Macro Sets framework.

PeopleTools 8.55.x - Branding - Part III - Custom Macros and More

$
0
0
In my previous blog posts, we saw how we can brand PeopleSoft applications which are on PeopleTools 8.55 using the new Theme Macro Sets functionality (Part I and Part II). The Theme Macro Sets provides a great way to override targeted styles (e.g.: Header Logo, Icon images, background colors, etc.) using online configuration. The delivered Them Macro Set contains 177 macros which targets specific styles for some common Branding tasks.

Creating Custom Macros:

The concept and functionality of the Macro Set are great, but what if the 177 macros that are available do not meet our requirements? In Part II, I demonstrated how we can fall back to using the Theme - Fluid Global Override Style Sheet under such circumstances. In this section, I will detail how we can still bring those custom style sheet overrides into the Theme Macro Set as custom macros. Once we create the macros, we don't need to update the style sheet anymore. All we need to do is update the macros if there are any further changes (I guess making it a little user friendly depending on who is making the changes). This is particularly useful for customers who have a more dynamic branding which changes frequently depending on the time of the year vs being static after implementation.

Macros in Theme Macro Sets are nothing but variables used in the Theme - Fluid Global Override Style Sheet which are substituted at runtime.

Going back to my example in Part II, we used the following styles in the Theme - Fluid Global Override Style Sheet for changing the Dot Styling on the Fluid Landing Page Footer:

.lpfooter .dot.on {
  background: #EEEB4D;
}
.lpfooter .dot {
  background: #E8E29E;
  border: 2px solid #1d418c;
}

Let us re-write the above styles using custom variables (macros).

NavBar > Navigator > PeopleTools > Portal > Branding > Branding Objects

Edit the custom Fluid - Global Override Style Sheet (CSK_BRAND_FLUID_TEMPLATE) and update the styles as follows:

.lpfooter .dot.on {
  %CSK_FOOTER_DOT_ON_CSS;
}
.lpfooter .dot {
  %CSK_FOOTER_DOT_CSS;
}


Now, let us add these macros (variables) to our Theme Macro Set:

NavBar > Navigator > PeopleTools > Portal > Branding > Theme Macro Set

Select the custom Theme Macro Set and add the custom variables in the 'Macro List' grid:


Results:


Similarly, we can add other Fluid Style Sheet overrides as custom macro definitions if necessary.

Moving along, the rest of this blog details some advanced branding tasks which can be done in PT 8.55 similar to PT 8.54. I am posting links for those items here for continuity.

Creating an environment specific header for Non-Production databases:

Fluid Housekeeping Steps: Fluid Branding - 8.54 - Part 5B
Task steps: Fluid Branding - 8.54 - Part 5C

We will notice that the above steps would only work for the "Fluid" pages. To make it work on "Classic" pages, we need to perform some additional steps.

Step 1: Update the javascript to modify the jQuery selectors

// Display Database Name using jQuery once the document is ready;

var $jq1 = jQuery.noConflict();

$jq1(document).ready(function(){

   // Make sure we are only adding the div once;
   if ( $jq1("#cskdbnamecontainer").length === 0 ) {

      // Add div to display DB Name;
      $jq1( "#PT_HEADER, #ptbr_header_container").prepend( "<div id='cskdbnamecontainer' align='center'><span id='cskdbname'>Test Environment: %dbname</span><a href='#' id='cskdbnamehide'>Hide</a></div>" );

      // Add jQuery to hide the DB Name when the 'Hide' link is clicked;
      $jq1("#cskdbnamehide").click(function(){
         $jq1("#cskdbnamecontainer").hide();
      });

   }

});



You can see that I added an additional selector (#ptbr_header_container) to the jQuery so that the contained javascript code executes for Classic as well.

Step 2: Inject custom styles into Classic - Theme Style Sheet

NavBar > Navigator > PeopleTools > Portal > Branding > Branding Objects

Append the following styles to CSK_BRAND_CLASSIC_TEMPL_FLUID


Custom styles for reference:

/* Fluid - Display DBName for non-Prod environments */
#cskdbnamecontainer {
   height: 26px; 
   background-color: rgb(204,204,204);
}
#cskdbname {
   color: rgba(229,47,0,1);
   line-height: 26px;
   font-weight: bold;
   padding-right: 10px;
}


Step 3: Inject the custom javascript into Classic using Branding System Options

NavBar > Navigator > PeopleTools > Portal > Branding > Branding System Options


Results:



Adding Custom Links to Actions List Menu:

Fluid  Branding - 8.54 - Part 5C

Again, we will notice that the above steps would only work for the "Fluid" pages. In order to add custom links on "Classic" pages, we need to perform some additional steps to update the header definition (CSK_HEADER_FLUID).

NavBar > Navigator > PeopleTools > Portal > Branding > Define Headers and Footers





Note: The reason I am using a Static URL as the means to add the custom URL is because the URL object option does not seem to substitute the URL correctly. It appears to be a bug in 8.55.

Results:


Overriding the Favorite Icon:

Fluid Branding - 8.54 - Part 5C

Again, this will only work for "Fluid" pages.

Here are the steps to create a Favorite Icon for Classic Pages:

Step 1: Update custom javascript - CSK_FL_IR_JS

NavBar > Navigator > PeopleTools > Portal > Branding > Branding Objects

Update CSK_FL_IR_JS javascript object as follows:


Javascript for reference:

// Get Image URL for CSK_LOGO (FavIcon);
document.write(unescape("%3Cscript src='/psc/" + site + "/EMPLOYEE/EMPL/s/WEBLIB_FL_CSK.ISCRIPT1.FieldFormula.IScript_Set_Image_URL_Variable?var=cskFavIcon&img=CSK_LOGO_FAVICON' type='text/javascript'%3E%3C/script%3E"));

var $jq = jQuery.noConflict();
$jq(document).ready(function(){

  // If Classic;
  if ( $jq("#ptbr_header_container").length > 0) {

     // create div for favIcon
     var favIcon = document.createElement("LINK");

     // set attributes and innerHTML
     favIcon.setAttribute("rel","shortcut icon");
     favIcon.setAttribute("href", cskFavIcon);

     // insert favIcon div in the head element
     document.getElementsByTagName('head')[0].appendChild(favIcon);

  } else {

 
     // Replace Browser Favorite Icon(s);
     $jq('head link[href*=LOGO_FAVICON]').attr('href', cskFavIcon);
 
  }

});


Results:



Overriding the "Processing" Icon:

PT_PROCESSING_FMODE:


Fluid Branding - 8.54 - Part 5D

PeopleTools 8.54+ - Branding - Part 4E - Customizing DEFAULT_THEME_TANGERINE_ALT Theme (Continued)

$
0
0
In my previous post (Branding Part 3), there were a series of questions/comments on how to add an external link to the Classic Branding header in PeopleTools 8.54.

In this link, I demonstrated how we could add an external link and open it in a new window using the Header definition.

But what if we wanted to add the 'New Window' link that is generally available at the component level to the Classic Branding header in PeopleTools 8.54? Assuming that is what the following comment suggests.

The steps would be very similar to adding an external link but we would be using javascript instead of using a static URL.

Adding 'New Window' link on the Classic Branding Header in PeopleTools 8.54:

- Add an element to the Header definition under pthdr2syslinks.


- Add JavaScript in URL attribute under the Static URL section.




Note: The 'Target' attribute value does not matter and we can leave it as the default (_top).

Custom JavaScript for reference:



- Element Properties - Set Order.


Results:





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

$
0
0
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 another follow up (Part 2), 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.

PeopleTools 8.54+ - Branding System Options - Additional JavaScript Objects

$
0
0
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.

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

$
0
0
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:



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

$
0
0
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 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 version 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!



PeopleTools 8.55: What is %include Meta-HTML function?

$
0
0
I found this gem of a Meta-HTML function that has been hiding deep in the bowels of PeopleTools javascript.

I was digging into some of the delivered javascript functions in a HCM 9.2 PUM Image 17 which is on PeopleTools 8.55.03. When I looked in the PT_COMMON HTML object, I almost jumped out of my couch. :)



Just to be sure, I checked if this function exists in 8.54 or prior tools releases. Correction: I found one occurrence in 8.54 (PT_PAGESCRIPT_FMODE) which leads me to believe that this function was probably introduced in PeopleTools 8.54 (so it is not new to 8.55 as I previously thought).

It appears that this undocumented (since it is not referenced anywhere in PeopleBooks) Meta-HTML function can be used to include other javascripts objects inline. This can be very handy!

Let us see how this works.

I created a custom JavaScript object (CSK_TEST) using Branding Objects.


Next, I added this to my Bootstrap JavaScript (CSK_FL_BOOTSTRAP_JS) as follows (Refer: PeopleTools 8.55+ - Using Oracle JET (JQuery, JQueryUI, requireJS and more) - Part 1).


Let us see this in action.


Here is how the %include function gets resolved at runtime:


I can see many great uses for this Meta-HTML function! :)

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

$
0
0
This post is a continuation of my 'PeopleTools 8.55+ - Using Oracle JET' series (refer: Part 1, Part 2 and Part 3).

In Part 1 (refer: Global JavaScript Injection Bootstrap for Fluid UI - Step 3), I pointed out that using 'Branding System Options' for injecting javascript in Classic pages would result in them getting invoked more than once (per header, pagelet, target frame, etc.). For most Branding Tasks, this might not be necessary since we are only dealing with the header portion of the HTML and other general styling.

All the topics described so far in this series worked fine with the 'Global JavaScript Injection Bootstrap' getting invoked just once as detailed in Step 2 and Step 3. But there may be some advanced requirements possibly outside the scope of Branding where we may intend to inject the Global JavaScript once per header, pagelet, target frame, etc. in order to manipulate the target content area, form data/component buffer and so on. For such cases (to be detailed in a subsequent post), we could use the following alternative step to include our 'Global JavaScript Injection' Bootstrap JS.

Note: The following step would replace Step 2 and Step 3 (which means we need to revert both those changes).

Add CSK_FL_BOOTSTRAP_JS to Classic and Fluid using PT_UTIL JS object:

PT_UTIL is a delivered javascript object that is included in Fluid (via PT_COMMON_FMODE) and Classic (via PT_COMMON). My thought was to simply include our custom bootstrap javascript object in PT_UTIL (using the %include meta-html).


Additionally, I updated the javascript CSK_FL_DBNAME_JS as follows:

Object Name: CSK_FL_DBNAME_JS


The only change was the window.self == window.top condition to avoid the following 'custom header repetition' problem.


The rest of the javascript objects detailed so far in this series should work as-is without any issues.

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

$
0
0
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 the 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_%FormNameFunction: 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!

Fluid UI - Custom Development - Styling Tiles

$
0
0
In this post, I will write about how we can style any custom tiles that we might be creating for Fluid UI.

Why would we want to do that?

I created a custom Fluid component/page and created a Fluid Content Reference.


Now my icon1 image (CSK_CC_SCAN) for my custom tile ended up as follows:


Notice how the icon is not position appropriately? Sure, I can create an image with the desired alignment and spacing. But wouldn't it be better to just adjust the style on the tile image to add some alignment/margin properties?

If you see the Content Reference - Fluid Attributes - Tile Information, there is no way to assign a custom style to the Tile.

How do we associate styles to custom tiles?

I simply added the following custom style at the very end of my 'Fluid - Global Override Style Sheet' (CSK_BRAND_FLUID_TEMPLATE) referenced on my custom Branding Theme (CSK_THEME_FLUID). Refer: PeopleTools 8.55.x - Branding - Part I for more details.


CSK_CC_SCAN$30 is the id attribute generated on the HTML for my custom tile.


Now, we can see the results from the image above that my custom tile icon is displayed in the desired position with a top margin of 25px.

If you think this would be a good feature to add to the 'Fluid Content Reference - Tile Information' section, then please vote for this idea on My Oracle Support.

1 - Icon made by Freepik from www.flaticon.com

Fluid UI - Custom Development - Twitter Feed As a Tile

$
0
0
Fluid Tiles can display dynamic content. I was curious how we can use the Fluid Tiles to display dynamic content from an external source, e.g.: Twitter Feed.

Here are the steps I followed to create a Fluid Tile which displays a Twitter Feed.

Step 1: Create a Twitter Widget using your Twitter account

Twitter > Settings > Widgets

Enter your Search Query and configure your widget settings as per your requirement. Copy the HTML code that is provided at the bottom right of the page.


Step 2: Store the Twitter HTML in a HTML Object


Step 3: Create an IScript that renders the Twitter HTML


PeopleCode for Reference:

Function IScript_Twitter_Feed()
   %Response.Write(GetHTMLText(HTML.CSK_TWITTER_FEED));
End-Function;

Step 4: Create a Fluid Content Reference with Tile Properties referencing the Twitter IScript

I created a Content Reference as a Non-Peoplesoft URL and referenced the custom IScript (created in Step 3) in the Content Reference > Fluid Attributes > Dynamic Tile Content section.



Results:

Now we are ready to test this tile. I added it to a custom homepage and voila!



Using Bower to manage javascript packages in PeopleSoft Applications

$
0
0
I previously experimented with several open source javascript libraries in PeopleSoft (E.g.: Using ACE Editor for Branding Objects). In most instances, I manually downloaded the js libraries and placed them on my web server domain folder.

I wanted to see if we could use Bower for managing such js packages in PeopleSoft. We may not use it as heavily in PeopleSoft as others do in the web development world. Nevertheless, Bower drastically simplifies the task of downloading the packages (taking into account all the dependencies, etc.) and managing them (including keeping them updated as required).

Further, I wanted to create a seamless/dynamic method to load these packages by mounting the bower_components folder on the PeopleSoft web server domain folder. For the proof of concept, I will be installing Bower on my local desktop and then mounting my bower_components folder (which contains all the libraries installed) to the web server of a HCM 9.2 PUM Image 17 installed as a VBox Image on the same desktop machine.

Note: The following steps are a proof of concept only. It is intended to create a seamless javascript package manager for a PUM Virtual Box Image which is primarily used as a development playground. The same concept could be extended to other development environments.

Step 1: Install Node.js, Git and Bower on the destination machine

In my case, I installed them on my desktop which is running Windows 7 as the OS. I will be using my desktop as the location to run Bower.
  1. To download and install Node.js click here.
  2. To download and install Git click here.
  3. I used an online resource (click here) for instructions to install Bower. Note: While the blog title states Windows 8, the steps work for Windows 7 as well.
Finally, make sure that the Git bin and cmd directories are also added to the PATH system variable. In my case, my Git directories were in the following location:
C:\Program Files\Git\bin;
C:\Program Files\Git\cmd;


Step 2: Using Bower - Installing Packages

Run 'Power Shell' as an Administrator. Then navigate to the directory where we want to install our bower packages.

Bower Init (Optional)


This should created our bower.json file.

Bower Search and Install

As an example, I will be using the ACE Editor as the package to search and install.


After executing, bower install ace --save, we should now see the ace editor library installed under the bower_components folder in the current directory. If there are dependencies for the library, then they will also be installed automatically. In this case, there are none for ACE Editor.


Also, the bower install ace --save, should update the bower.json file (if bower init was executed).


Step 3: Mount the bower_components directory on the PeopleSoft Web Server

Thanks to Michael Ripley who helped me with this part of the requirement on the psadmin.io Slack community.

Before starting the VM (PUM Virtual Box Image), create a Shared Folder (that points to our bower_components folder) using Virtual Box Manager Settings.


Now, start the VM and create a bower_components folder on the web server domain (ps - in my case) folder as follows:


Then, update /etc/fstab file to add the following line:

bower_components /home/psadm2/psft/pt/8.55/webserv/peoplesoft/applications/peoplesoft/PORTAL.war/ps/bower_components vboxsf defaults 0 0


This should take care of mounting the shared folder, bower_components, on to the web server during boot up.

Finally, once we restart the VM, we should now see the shared bower_components directory contents on the web server.


Now, we can start referencing and using the libraries under the bower_components directory just like any other js library on the web server!

Fluid UI - Custom Development - Invoke JavaScript from PeopleCode

$
0
0
There are some notable additions to PeopleCode support for Fluid UI in terms of the built-in functions and properties that are delivered.

In Classic, if we had a requirement to invoke a JavaScript function from PeopleCode, then one option would be to use a HTMLAREA on the page and dynamically populate the HTMLAREA value with the JavaScript code.

In Fluid, we can very easily use the AddOnLoadScript function to invoke JavaScript in the onload event and the Field Class - JavaScriptEvents property to associate JavaScript events to a Field.

For the purposes of a demonstration, I created a simple Fluid page with 3 button fields.


I added the following Page Activate PeopleCode:

Declare Function SetViewport PeopleCode PTLAYOUT.FUNCLIB FieldFormula;

/* Set ViewPort Meta for SFF Scaling */

SetViewport(""); /* apply the system default viewport setting */

AddStyleSheet(StyleSheet.PSBASE_LAYOUT);

AddJavaScript(HTML.CSK_PC2JS_FLU);

AddOnLoadScript("pageActivate();");
CSK_FL_PC2JS_WK.BUTTON1.JavaScriptEvents = "onclick='javascript:button1();'";
CSK_FL_PC2JS_WK.BUTTON2.JavaScriptEvents = "onclick='javascript:button2();'";
CSK_FL_PC2JS_WK.BUTTON3.JavaScriptEvents = "onclick='javascript:button3();'";



Here is the JavaScript in the HTML Object CSK_PC2JS_FLU:

var pageActivate = function() {
    console.log('JS invoked from Page Activate');
};
var button1 = function() {
    console.log('JS invoked by Button 1 OnClick');
};
var button2 = function() {
    console.log('JS invoked by Button 2 OnClick');
};
var button3 = function() {
    console.log('JS invoked by Button 3 OnClick');
};


Click here to check out a demo video >>>>SWF File

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

$
0
0
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:


Viewing all 132 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>