Showing posts with label css3. Show all posts
Showing posts with label css3. Show all posts

Sunday, July 5, 2020

Classic Drop-Down List Styling

Recently, there was a question on my blog related to drop-down list styling.

Refer: Original Question

How do we apply different colors to drop-down list values?

In this post, I will walk through a few examples of how we can use CSS to apply different background colors to drop-down list values. As an example, we will be using the 'Branding System Options' classic page which contains two drop-down lists.

Navigation: PeopleTools > Portal > Branding > Branding System Options

Identifying the style classes to target

The first step to overriding delivered CSS is to identify the style class(es) to target. We can do this using the browser's developer tools.


Overriding CSS using Component Branding

Since we are focusing on Classic UI, we can use the Component Branding feature which is available via the Branding Framework configuration to apply a custom Stylesheet object to the Component (PTBRANDINGSYSTEMOP).

Navigation: PeopleTools > Portal > Branding > Component Branding


Zebra Striping

In this approach we will use the nth-child() CSS to alternate between two different background colors as shown below.


Option 1: All Drop-Down lists on the page/component

Option 2: Specific Drop-Down list on the page/component

Notice the #PSBRSYSTOPT_WRK_PTBRANDTHEME in the CSS selector.

Styling specific rows

In this scenario, we will assume that we already know the rows that we want to style differently. Let's say, we want to display the custom Themes (with "SV_" prefix) differently.


Option 1: If we know the row numbers

Option 2: CSS based on attribute value prefix

Monday, August 12, 2019

Fluid UI - Working with Grids - Part 4 - Styling Stacked Grids

There were some interesting requirements posted by a reader in the following blog post.

Refer: Fluid UI - Working with Grids

Requirement 1: How to align the elements in a column to 'top' in a Stacked Grid

Let us say, we have a two Stacked columns with different number of elements/fields in each Stack as shown in example - Responsive Flex Grid with 2 Columns. As we can see in the screenshot below, the first Stacked column contains 3 fields and the second Stacked column contains 2 fields.


Since the second Stacked column only contains 2 fields and they are centered from a vertical position point of view, they don't line up with the fields in the first Stacked column.

If we want to align the fields in the second Stacked column to the top, we can achieve that with the following CSS.

I really like the nth-child() CSS3 selector. The idea is to only apply the CSS to a particular child element and not all. In our case, I only wanted to apply the CSS to the second column <td> element with "ps_grid-cell" class as shown below.


You can find more details on the nth-child() selector in the following blog post.

https://support.awesome-table.com/hc/en-us/articles/115001393209-Add-style-to-specific-columns-or-rows-in-your-Table-view

Note: The CSS provided above is added to the page using the following Page Activate PeopleCode.


Requirement 2: How to align specific fields (elements) in a Stacked Column to the Right

Let us say, we want to right justify specific fields in a Stacked Column. For example, we want to right justify the EFF_STATUS field.


We can achieve this by simply identifying the the id value (or part of it) and apply a wildcard CSS selector that contains this value as shown in the following CSS.

The wildcard for the id is required in this case due to the window and grid row numbering that is prefixed and suffixed to the record field name to generate the id value.


Requirement 3: How to align a specific Stacked Column to the Right

Let us extend the previous requirement and say that we want to align the entire second Stacked column (including the Label) to the right.


We can simply achieve this by using the following updated CSS:

Result

Project Details

All examples in this blog post were built on the project provided in Fluid UI - Working with Grids.

Saturday, June 24, 2017

PeopleTools 8.55+ Branding: Using the Logo as a Hyperlink

It is a common practice in most social media and big brand websites to use the webpage logo as a hyperlink for navigation. This usually provides a mechanism for the users to 'return to home' in most cases. Here is a very interesting discussion on how this standard/convention originated:
https://ux.stackexchange.com/questions/81727/why-is-it-standard-for-a-website-logo-to-navigate-to-the-home-page

In the past, I have worked on requirements where we wanted the logo of a PeopleSoft application to hyperlink to the enterprise portal (which may or may not be PeopleSoft based). To generalize this requirement, let us assume that we want to hyperlink the PeopleSoft Logo to a configured URL (which could be any URL of our choice).

This post assumes that:
My environment details:
- CS 9.2 PUM Image 4
- PeopleTools 8.55.12

Adding a Hyperlink to the Logo on the Fluid Homepage:

The first step we need to do is to identify the HTML elements (divs, images, etc.) that are involved in generating the logo. It is very easy to identify this using the browser's developer tools (inspect element option).



As we can see, the logo image is added to the div (with the style class nuihdr_logo) as a pseudo-element using CSS. Here is a javascript object that selects this div (using the class selector) and adds a click event which redirects to a URL defined in a URL definition (CSK_LOGO_URL). This works well because the div element is completely enclosed within the image (psuedo-element) in terms of position on the webpage and as a result does not have any overflow issues. We will see how this can be an issue as we extent this functionality to the Classic Homepage (next section).

JavaScript Object: CSK_LOGO_URL_JS


I used the javascript injection framework to load this javascript object.


URL Definition Configuration:


Results:

Here is a demo of the Fluid Homepage Logo hyperlink.


Adding a Hyperlink to the Logo on the Classic Homepage:

In this section, we will extent the functionality discussed above to the logo on the Classic Homepage. Let us use the same approach and try to identify the HTML elements (divs, images, etc.) that are involved in generating the logo.



As we can see, the div element (with id pthdr2logofluid) spans the entire width of the page whereas the logo image which is added as a pseudo-element using css obviously does not. So, if we were to use the previous approach and add a click event function for this div (id pthdr2logofluid), then the entire div (which spans the width of the page) would become a hyperlink.

It is not very easy to selectively fire the click event function only on the pseudo element because pseudo elements are not part of the DOM and therefore cannot be manipulated using javascript. After a long search where I almost gave up, I found the following discussion where there was a solution for a similar requirement.

Refer: https://stackoverflow.com/questions/7478336/only-detect-click-event-on-pseudo-element
JSFiddle: http://jsfiddle.net/ZWw3Z/70/

We can take this idea and apply it to the Classic Homepage Logo by updating the javascript as follows:

Updated JavaScript Object: CSK_LOGO_URL_JS


The updated javascript code selects the div element (with id pthdr2logofluid) and sets all pointer-events to none using css. The javascript also has the click event function to redirect users to the URL configured in the URL definition (CSK_LOGO_URL).

Finally, the Classic stylesheet (CSK_BRAND_CLASSIC_TEMPLTE_FL) which is part of the Branding Theme in my environment which uses Theme Macro Set (click here for more details), was updated to set the cursor and pointer-events properties for the pseudo-element.


Results:

Here is a demo of the Classic Homepage Logo hyperlink.


Saturday, September 10, 2016

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

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

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

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


Development Environment: HCM 9.2 PUM Image 17 - PeopleTools 8.55.03

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

Step 1: Add Oracle JET paths to requireJS configuration

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

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


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

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

For complete javascript code, please refer jsFiddle link: CSK_REQUIRE_CFG_JS

Note:

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

Step 2: Create a Fluid Page

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

Further, let us add the following page field elements:

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


Edit Box (Input Field):

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



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

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



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

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

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


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

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

HTML: ojStatusMeterGauge Component DIV


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


PeopleCode For Reference:

Declare Function SetViewport PeopleCode PTLAYOUT.FUNCLIB FieldFormula;

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

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


Step 4: Apply Knockout Bindings to the ViewModel

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


JavaScript: CSK_OJ_GAUGE_INIT_JS


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

JavaScript: CSK_OJ_GAUGE_MAIN_JS


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

Step 5: Create ViewModel JavaScript Object - CSK_OJ_GAUGE_VIEWMODEL_JS

JavaScript: CSK_OJ_GAUGE_VIEWMODEL_JS


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

Step 6: Create the FieldChange PeopleCode Event

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


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

Results:

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


Demo of Quirks:

Why do we need cskOJKORefresh function in CSK_OJ_GAUGE_MAIN_JS?

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


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

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


Reference Links:

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

Tuesday, September 6, 2016

Fluid UI - Oracle JET - Using KnockoutJS for Data Binding - Demo

Continuing on my experimentation with Oracle JET in Fluid UI, I will demo how we can use KnockoutJS available as part of Oracle JET for data binding. This demonstration is based on the following Oracle JET MOOC - Lesson 1, Part 4: Data Binding.

Development Environment: HCM 9.2 PUM Image 17 - PeopleTools 8.55.03

Step 1: Create a Fluid Page

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

Further, let us add the following page field elements (group box, edit box - input field and edit box - display only):


Group Box Properties:


Edit Box (Input Field):



Edit Box (Display Only):




Step 2: Add KnockoutJS path to requireJS configuration

Next, we need to update our global requireJS configuration to include the path for knockout.


For complete javascript code, refer jsFiddle link: CSK_REQUIRE_CFG_JS

For more details on using requireJS refer:PeopleTools 8.55+ - Using Oracle JET (JQuery, JQueryUI, requireJS and more) - Part 1, Part 2, Part 3, Part 4.

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

In our infrastructure (PeopleSoft - Pure Internet Architecture), the "View" is the page (CSK_KO_DATA_BIND) which generates the HTML. As a next step, we can write some PageActivate PeopleCode to add the data-bind attributes to the Fluid page fields using the Field Class HtmlAttributes property.


PeopleCode for Reference:
/* Setting the data-binds in the "View" */
CSK_OJ_WRK.DESCR1.HtmlAttributes = "data-bind='value: userText'";
CSK_OJ_WRK.DESCR2.HtmlAttributes = "data-bind='value: userTextCaps'";


Step 4: Apply the KnockOut Bindings to the ViewModel

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


JavaScript: CSK_KO_MAIN_JS


- As you can see, we added the requireJS configuration path to the "ViewModel" javascript in the main (CSK_KO_MAIN_JS), instead of using the global requireJS configuration in Step 2 (while setting up Knockout JS path). This is because we do not want this app (page) specific path to clutter our global requireJS configuration.
- In the require block, we injected the Alta CSS to enable the oj-flex and oj-flex-item styling that we used in Step 1.
- Finally, the Knockout binding is applied to the "ViewModel" which resides in CSK_KO_VIEWMODEL_JS.

Step 5: Create ViewModel JavaScript Object - CSK_KO_VIEWMODEL_JS

JavaScript: CSK_KO_VIEWMODEL_JS


The ViewModel has the define block as described in the Oracle JET MOOC lesson example.

Results:


Monday, September 5, 2016

Fluid UI - Oracle JET - Using Oracle Alta UI and Flex Layouts

In my previous posts, I showed how we could use Oracle JET with PeopleTools (and client side javascript) to take advantage of some robust solutions for file loading and modularity. Since I started attending the Oracle JET MOOC, I wanted to see if we could leverage Oracle JET for enhancing the UI in PeopleTools Fluid. Why would we want to do that? Well, why not? Oracle JET has a very well documented CookBook and pre-built UI components, so we could just plug and play the UI functionality to Fluid (without reinventing the wheel). Sounds good in theory! Let us see how we could use Oracle Alta UI and Flex Layout (part of CSS3) in Fluid as a starting exercise.

Development Environment: HCM 9.2 PUM Image 17 - PeopleTools 8.55.03

Step 1: Install the latest version of Oracle JET

As I have shown in the past already, Oracle JET is available on the web server starting with PeopleTools 8.55. This is great for using requireJS, jQuery and other libraries (that are part of Oracle JET), but if we want to venture into the UI layer, it is better to install the latest version of Oracle JET to take advantage of the newer capabilities (since the delivered version - at least as of PeopeTools 8.55.06 - is still referencing a much older release).

I used bower to automatically download, install and place the latest version of Oracle JET onto my bower_components folder - which is mounted on my web server. For more details on how to use bower, please refer - Using Bower to manage javascript packages in PeopleSoft Applications.

Oracle JET Installation:


Oracle JET 2.1.0 on the web server (bower components):


Note: You don't necessarily have to use bower for placing Oracle JET on the web server. You could use other options that might be convenient and accessible to you.

Step 2: Create a simple Fluid Page using PSL_APPS_CONTENT Layout Page

There is nothing fancy about this page (at least as of now). It is basically empty right now.

Fluid Page Object - App Designer:


Fluid Page:


Step 3: Inject Alta UI CSS to the Fluid Page

I am using the Page Activate PeopleCode event to execute an OnLoad javascript which will take care of loading the Alta UI CSS file located on the web server (Oracle JET directory).


JavaScript: CSK_OJ_LOAD_CSS


You can see that I am adding the oj-alta-notag-min.css instead of oj-alta-min.css. This is to avoid conflicting with some of the other basic PeopleSoft styles. For more details review - Understanding Oracle JET Theming For Compatibility.

Note: For more details on the cskLoadCSS function, refer PeopleTools 8.55+ - Using Oracle JET (JQuery, JQueryUI, requireJS and more) - Part 3.

Result:

We can now see the oj-alta-notag-min.css file injected to the head when 'oj Layout' page is loaded.


Step 4: Use Flex Layout in Fluid

Now that we completed all the logistics, we are ready to start using the 'Flex Layout' in Fluid.

Let us add a few group boxes to the Fluid page that would provide us a mechanism to add 'Layout Only DIVs' to the page which would in turn allow us to use the Oracle JET - Flex Layout styles.


oj-flex Group Box Properties:

You can see that in the Group Box Properties, I have set the 'Override PeopleTools Style?' to Yes. This is required specifically for these type of cases where we use CSS from external libraries. Otherwise, there will be some undesired PeopleTools styles automatically added to this DIV. Also, we need to make sure that we set the Group Box Type to 'Layout Only' and Html Tag Type to 'DIV'. The Default Style Name (oj-flex oj-sm-only-flex-direction-column) was directly copied from this lesson: Oracle JET MOOC: Lesson 1, Part 10 - Oracle JET Layouts - I recommend reviewing this video to get a good understanding of Alta UI and Flex Layouts.


oj-flex-item Group Box Properties:

Default Style Name: oj-panel oj-margin oj-flex-item


Results:

Let us now see this in action and also compare it with the same Flex layout implemented in an Oracle JET QuickStart Template.

Watch Demo Here: Oracle JET QuickStart Template Demo

Watch Demo Here: Fluid UI - Flex Layout Implementation

Step 5: Adding Fluid Elements to the Flex Items

What is the benefit of all these steps? We are using a well documented, stable set of responsive styles and UI components delivered by Oracle JET instead of developing them from scratch or trying to find appropriate Fluid styles (which is not very easy!). Now, let us employ this in a more realistic use case. Let us add some Fluid elements (input fields) to the Flex Items.


Group Box Properties:


Input Field (Edit Box) Properties:



Note: I repeated the same elements in the other two flex items.

Results:

Watch demo here: Fluid UI - Flex Layout Implementation with Input Fields