Friday, December 22, 2017

Weekend Fluid Classes

Habit 7: Sharpen the saw. We all know we must sharpen our mental saw. The challenge is fitting saw sharpening into our schedule. If you are a billable consultant dedicated to a project, then you are often bound by contract to be onsite during regular business hours. If you find yourself in this situation, sharpening your technical skills can be challenging because most training courses happen during your committed working hours. We understand the struggle and want to do what we can to help. With that in mind, we are offering our popular Fluid training series over two consultant weekends (Friday and Saturday) of January:

  • Fluid 1: Jan 12-13, 2018
  • Fluid 2: Jan 26-27, 2018

Further details and registration information are available on our website

Wednesday, December 20, 2017

Using CSS Frameworks with PeopleSoft Fluid

Fluid is Oracle's strategic direction. If you have experience with Fluid development, you know that dragging, dropping, and aligning fields on a canvas isn't enough to develop a multi-form factor Fluid user interface. With Fluid comes an emphasis on CSS3 for multi-form factor support. This means you must add CSS class names to page fields to support different screen sizes. PeopleTools comes with an extensive list of predefined CSS class names. The challenge is identifying which CSS class to use. Fortunately, Oracle published two extremely helpful documents:

If you learn the style classes in these two documents, you will do quite well with Fluid layout (actually, just learn a few dozen of these classes and you will do quite well). But what if you want to use features of CSS that don't exist in Fluid-delivered CSS classes? Flexbox, for example, is one of the most powerful features of CSS3. When I find myself terribly annoyed with Fluid layout, I throw a Flexbox at my layout issue and the problem is solved. If we want to apply styling using CSS attributes that PeopleSoft hasn't already defined, we have two options:

  • Define our own CSS classes by creating a free-formed stylesheet or
  • Borrow someone else's CSS class names from a CSS framework.

Writing your own CSS can be a rewarding experience. I can often solve layout problems with just a few lines of CSS. My concern, however, is maintenance. What starts as a one-time CSS "fix" (or hack) for a layout often turns into a copy/paste exercise replicated at least a dozen times, with each page using some of the same CSS and some different CSS. Then what? Do we create a separate CSS file for each Fluid page? Do we refactor common CSS, moving similar code into a shared library?

Given the age and history of the internet, most web layout problems have already been solved. Since PeopleSoft is just another web application, we can leverage the work of the world wide web's pioneers. The solutions to most of our layout problems exist in today's common CSS frameworks, Boostrap being the most popular. There are many PeopleSoft consultants happily using Bootstrap to enhance PeopleSoft Fluid pages. Here is how they do it:

  1. Import Bootstrap into a Freeform Stylesheet
  2. Use AddStylesheet to insert Bootstrap into a Peoplesoft page
  3. Apply Bootstrap style classes to Fluid page elements
  4. Create a "reset stylesheet" to fix everything Bootstrap broke.

Yes, you read that last line correctly, "... fix everything Bootstrap broke." Please don't misread this. There are many developers successfully using Bootstrap with PeopleSoft. But here is the problem: Most CSS frameworks directly style HTML elements. This is actually good. Developers call this a "reset" stylesheet. What makes this a problem for PeopleSoft is that PeopleTools ALSO applies CSS directly to HTML elements. PeopleTools includes its own reset stylesheet. In a sense, we could say that Fluid is a CSS framework itself. The end result is a mixture of styles applied to HTML elements by two competing and complementing CSS frameworks. I call this "Fluid-strap." Consultants work around this problem by creating a reset for the competing reset stylesheets — a reset for the reset.

Here is another alternative: Use a CSS framework that does NOT style HTML elements, but instead relies on class names. This type of CSS framework was designed for compatibility. This type of framework understands that another CSS framework is in charge. My personal favorite CSS compatibility library is Oracle JET. In Oracle JET's GitHub repository, you will find oj-alta-notag.css, a CSS file containing a lot of CSS class names and no element declarations. To use this library, follow the first three steps described above, skipping the final step:

  1. Import oj-alta-notag.css into a Freeform Stylesheet
  2. Use AddStylesheet to insert the Oracle JET Stylesheet into a Peoplesoft page
  3. Apply Oracle JET style classes to Fluid page elements

The key difference is we don't have to create a reset for the reset. The Oracle JET stylesheet silently loads into a PeopleSoft page without changing any styling unless specifically asked to style an element through the element's Default Style Name (Style Classes on 8.56) property.

Consider a PeopleSoft page built with 4 group boxes aligned horizontally as demonstrated in the following screenshot.

In Classic, what you see is mostly what you get, so the online rendering would look nearly the same as the Application Designer screenshot. In Fluid when viewed online, however, each group box will render vertically as follows:

We can fix this by applying a CSS Flexbox to the 4 group boxes. With Flexbox, the 4 group boxes will align horizontally as long as the device has enough horizontal real estate. If the display is too small, any group boxes that don't fit horizontally will move to the next row. For this example, we will use Oracle Jet's Flex Layout.Here are the steps

  1. Add a Layout only Group Box around the 4 horizontal group boxes and mark the container group box as Layout Only
  2. While still setting container group box properties, set the group box's style class to oj-flex oj-sm-flex-items-1
  3. Likewise, to each of the 4 horizontal group boxes, add the Style Class oj-flex-item
  4. Create a Freeform stylesheet definition containing oj-alta-notag-min.css
  5. Use the AddStylesheet PeopleCode function in PageActivate to insert the Stylesheet into your page

The end result will look something like this:

Several years ago, I read the book Test Driven Development by Kent Beck. In that book, Kent identifies the first step of each project as the hardest step. Why? Because each new project contains significant uncertainty. Software development seems to involve a lot of unknowns (if the solution was known, someone would have created it, automated it, and published it). His advice? Start with what you know. You start with what you know and work torwards what you don't know. This is how we teach Fluid at JSMPros. Your developers understand Classic development and we use that knowledge to springboard students into a higher level of Fluid understanding. If you are ready to take the Fluid challenge, I encourage you to register for one of our monthly Fluid classes at Have a group of eight or more developers? Contact us to schedule your own personalized Fluid training event.

Monday, December 18, 2017

Is Your Fluid Custom Action Menu Page-based or Component-based?

In the upper right corner of the Fluid header you will find the "Hamburger" (or hamburger-light) menu. This 3-bar (or 3-dot) icon displays a list of component-specific actions. For the most part these actions are rather generic, allowing a user to add a tile to a homepage or view preferences. Occassionaly we see a component that has its own custom actions. The HCM My Team and Company Directory components are great examples of components with custom action menu items. In fact, the Fluid homepage itself is an example, with its Personalize Homepage custom action.

As developers, we can add custom component-specific actions to the header menu of a component by adding a special group box (Custom Action Menu) to one of the component's pages. When PeopleSoft loads a page with a Custom Action Menu group box, it moves the contents of that group box into the header action menu. Any actions loaded from a page stay resident in the menu as long as the component is in scope. So, technically, all Custom Action Menus are component-based. Here is my struggle:

Actions inserted into the header menu have component scope, not page scope, but are defined at the page level.

Custom action menu items are not visible (in fact, don't exist) until the page defining these menu items is loaded into the user's browser. If a component may have multiple pages, into which page would you insert the custom action menu? Logically, I might say, "The first page, of course." But here is the problem: there really is no "first page." There is a page that the component will load by default. We might call that the front door. PeopleSoft, however, lets users enter through the side door, back door, and all windows as well. By adding ?Page=... to a component URL, I can enter that component from any page within the component. For example, if I want to open the User Profile component to the User Queries page, I add PAGE=USER_QUERY to the end of the URL. If I enter a component through the wrong starting page, then I won't see the component's custom actions in my header menu.

You don't think your users will enter a page name in the URL? Probably not. Why worry about a scenario that will never happen? Actually, it isn't my users that concern me. It is system generated messages and processes with URLs. It is workflow notifications that attempt to simplify workflow by taking me to the next step in a business process.

If a user can enter a component through any page and component specific actions must be defined on a page, then into which page should I enter component-specific actions? While teaching a Fluid class and challenging students to find a solution to this problem, one of my students asked me, "What if you put the menu definition in a Footer page?" Wow! What a great idea! If you have component-scoped actions, why not define them in a component-scoped page? This page will load as soon as the component loads, regardless of the entry point. If you already have a footer page in your component, perfect! Just add the Custom Action Menu group box to your existing footer page. If you don't have a footer page, should you add one? I say, "Yes." Properly built, a footer page may be entirely invisible, used just for component-specific banner (also known as the header) changes (including Custom header left, right, and bottom sections). Seems ironic doesn't it? If you want to change the header, add content to the footer. Here is a sample footer page built specifically to hold a menu. By clearing the CSS class name from the outer container Group Box, the footer becomes invisible.

The following screenshot shows how the menu will appear when PeopleSoft reparents the menu's HTML from the footer into the header component action menu.

Interested in learning more about Fluid? I offer at least one virtual Fluid training class per month. You can learn more about our current offerings on our Live Virtual Training page. If your organization has more than 8 employees, you may derive cost savings by hosting your own training event. Learn more at

Follow my blog with Bloglovin