Sunday, August 20, 2017

Fluid UI - Responsive and Mobile-Friendly Tooltip


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

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

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

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

Test Environment Details:

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

Using HtmlAttribute to update the text attribute:

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


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


Delivered Tooltip on larger viewport:


Delivered Tooltip on smaller viewport:


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

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

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

Responsive and Mobile-Friendly Tooltip:

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


Custom Tooltip on larger viewport:


Custom Tooltip on smaller viewport:


Implementation Details:

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

PeopleCode:

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

CSS:

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

JavaScript:

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

24 comments:

  1. Hi Sasank!

    This is great! Javascript to the max again. especially how relatively easy the implementation is on the people code side. Well done. Thanks for sharing.

    Your idea gives me more inspiration of creating a setup page were you tie RECORD.FIELD together with a DESCR. In your code you can than loop over your page fields and attach the title dynamically which is obtained from your DESCR. You might even use MESSAGECAT for this.

    Stefan

    ReplyDelete
    Replies
    1. @Stefan - Thanks!

      That sounds like a great idea. Further, we could eliminate the custom code by using Event Mapping Framework for the page activate peoplecode!

      Delete
  2. HI, I followed all steps meticuously. yet my Custom tooltip is not visible.
    Did I missed anything ?

    ReplyDelete
  3. Needless to Mention its a one off achievement.

    ReplyDelete
    Replies
    1. It is hard to say what steps you are missing.

      - First, check if you are seeing the html attributes on the browser using the developer tools option.
      - Then check if you custom javascript is firing by adding some console.log('Enter Debug Message Here'); messages.
      - Also, check your browser console for any javscript errors.

      Thanks!

      Delete
  4. Many Thanks Sasank,

    I am getting Javascript error: 'require' is undefined.

    ReplyDelete
    Replies
    1. Hi Sasank,

      I was able to solve this error. The code above is not referring to jQuery Source.
      I modified the code like this

      window.onload = function () {

      require(['http://code.jquery.com/jquery-latest.min.js'], function (JetCSKJQ) {

      var $ = JetCSKJQ;
      cskLoadCSS(getCSSUrl('TY_TOOLTIP'));

      $( function()......

      Delete
    2. Yes. That is the problem.

      The details on how I use requireJS is in this link(which I also mentioned in this blog post):
      https://pe0ples0ft.blogspot.com/p/javascript-injection-framework.html

      Delete
  5. Does this Tooltip not support Checkboxes in Fluid UI ?

    ReplyDelete
    Replies
    1. I have not tried it on a Checkbox in Fluid but I would imagine it would work as long as the rel attribute is added.

      Delete
    2. its not working for checkbox. Have you tried it yet on checkbox field?

      Delete
  6. It seems to work on regular Field and on a Checkbox (Classic in Fluid Box vs Slider) BUT the CSS looks like the PS HOVER (White Shadowed box small font). Which is strange.. I wanted to use it for Putting error info on lines , So user can mouse over field or row to see errors instead of going deeper for all the errors. But it is sooo generic.. I want it to pop... Is Tooltip

    ReplyDelete
  7. Please Note , the JavaScript I just added to page activate and used the simple version instead of your injection. Thus I am just adjusting one component.

    ReplyDelete
    Replies
    1. Adding the javascript using AddJavaScript function in Page Activate PeopleCode might potentially cause some timing issues with respect to when the javascript is executed.

      To rule that out, you could simply append the following line in PT_UTIL (HTML).
      %include(YOUR_JAVASCRIPT_OBJECT_NAME);

      This will make sure your javascript executes correctly. If this works, then you can add appropriate conditional logic to only include your javascript for your component by inspecting the request URL.

      Delete
  8. If I did that would it not effect All Tool Tips Globally. Thus Someone would start screaming,,,
    I have had issue in past PT update just get loaded and wipe my Code away....

    And If I added just to see what it looks like Which version would I add

    ReplyDelete
  9. Hi Sasank

    Does this work with transferpages? That is i have a Master/Detail application and when transferring to the page where i need this to work, it is not working. I can see the Javascript is being loaded correctly because i have added console messages and those are showing up in the console window of chrome when the page is initially loaded. Any advice is appreciated

    Thanks
    Nitin

    ReplyDelete
    Replies
    1. Hi Nitin - If the javascript is loaded, I don't see why it would not work in a master/detail application.

      Just to be sure, are the console messages appearing after the transfer?

      Delete
    2. Hi Sasank

      Unfortunately the console message is not getting triggered on the transfer. The only time i see it is when i first go into the page. I would think it would think the AddJavaScript would load each time it went to that page.

      Nitin

      Delete
    3. I am assuming you are already triggering the AddJavaScript on the target page?

      If there is a timing issue with the script, you could look at this JavaScript Injection Framework to get some ideas:
      https://pe0ples0ft.blogspot.com/2019/03/javascript-injection-framework-updates.html

      Delete
    4. Hi Sasank

      I noticed and interesting thing here, when using the Master/Detail framework my url is like as following
      /psc/ps/EMPLOYEE/ERP/c/PSW_SMARTWIZARD_MENU_FL.PSW_MD_STARTPG_NUI.GBL?GMenu=PSW_SMARTWIZARD_MENU_FL&GComp=PSW_SMRTWZ_L_FL&GPage=PSW_SMRTWZ_FL_L_PG#

      So when i load the JS in PSW_MD_STARTPG_NUI it gets loaded when i first go to the component. The thing is that i need it to load on another page called PSw_SMRTWZ_R_FL. Maybe that is the reason why it is not triggering because the system still thinks it is on the PSW_MD_STARTPG_NUI?

      Thanks
      Nitin

      Delete
  10. Hi Sasank

    So i used the injection framework and followed what you had on the blog post you have mentioned. The funny this is that the JS gets loaded as soon as i enter the page the first time. I would think it would load every time we transfer to the page, but that does not look like to be the case. I will keep trying

    Thanks for the reply and appreciate your help
    Thanks
    Nitin

    ReplyDelete
    Replies
    1. That is right. I have experienced similar issues with the Framework to be honest. It does not work for AJAX requests.

      Do share any tips if you find ways to workaround this! I know this can be achieved but I have not spent a lot of time investigating this scenario. I will keep you posted if I have additional ideas!

      Delete
    2. Hi Sasank,

      finally heard back from Oracle
      Here is their reply

      "This works as designed. So the Master/Detail (as well as Activity Guide) infrastructures as designed as WRAPPER components.
      The exist ONLY TO CREATE A SHELL (FRAMEWORK) to display content from different components. So what you are describing is exactly correct.
      If you put onloadscript in the master/detail component, it will fire ONLY ONCE and that is while the master/detail component is BUILDING THE WRAPPER COMPONENT.
      Once the wrapper is built, the master/detail component is gone -- it's purpose is over.
      At that point, the grouplets (javascript based) are responsible for DRIVING THE WRAPPER CONTENTS.

      So if you want something to run every time a COMPONENT loads, then you must perform this within the COMPONENT not within the MASTER/DETAIL component."

      Thanks
      Nitin

      Delete
  11. Quick Question with DoModalPopup(&sPopupOptions, "", False, False, @("Page." | &sModalPage), &sModalTitle, - 2, 100);

    In fluid Approvals it Pops up a Confirmation Box. Fine...
    But users are complaining that it is in the middle of the screen. They want it close to the Initial Approval Button . So I adjusted Xpos and Ypos ... And it dos not move...

    &sPopupOptions = "width@500;height@150;bAutoClose@0;bAutoCloseWarn@0;bTail@0;bVertical@0;bCenter@0"; This does nothing

    ReplyDelete