Showing posts with label jQuery. Show all posts
Showing posts with label jQuery. Show all posts

Tuesday, June 25, 2013

Using the PeopleTools 8.53 Version of jQuery "Safely"

Now that PeopleTools 8.53 includes jQuery, the question is, "how do I use it?" Probably the easiest way is to add something like this to your Pagelet or page where you want to use jQuery (see New PeopleTools 8.53 Branding Tools):

<script type="text/javascript" src="/psc/ps/EMPLOYEE/EMPL/s/WEBLIB_PTBR.ISCRIPT1.FieldFormula.IScript_GET_JS?ID=PT_JQUERY_1_6_2_JS"></script>

Some of you may have tried this. It works great if you have just one item that uses jQuery. If you add more (for example, if you add multiple pagelets) where some use plain jQuery, some use jQuery UI, and others use jQuery Cycle, you will see that each new inclusion overwrites your plugin list, rendering your new pagelet unusable. What about include protection? This concept is still relevant, but I would hate to manage it as a modification if there was another way. Here is what I came up with for 8.53:

<script type="text/javascript" src="/psc/ps/EMPLOYEE/EMPL/s/WEBLIB_PTBR.ISCRIPT1.FieldFormula.IScript_GET_JS?ID=PT_JQUERY_1_6_2_JS"></script>
<script type="text/javascript">
  // special variable to store "our" single jQuery instance
  if(!window.psjq$) {
    window.psjq$ = window.$ = window.jQuery;
  } else {
    // ignore recent import and use the global single instance
    window.jQuery = window.$ = psjq$;
  }
</script>

If you look at the PT_JQUERY_1_6_2_JS HTML definition in app designer, you will see that PeopleTools uses jQuery.noConflict() to free up $, but not jQuery. Using noConflict to move $ into a new variable named ptjq162 is appropriate, but doesn't help with plugins. Properly coded plugins use the global variable window.jQuery. Looking through jQuery UI, cycle, and many of the other plugins I use, they all use the global jQuery variable, with no mechanism for replacing it. As you can see here, my solution is to store jQuery in the custom global variable psjq$, and then override jQuery on each import of jQuery. This way all plugin scripts loaded after my script will always use the original, single instance jQuery copy of psjq$. Note: I tried using ptjq162.noConflict(true) to manage a single instance, but didn't get it working. My approach just seemed easier for me to understand, and, well, it just worked.

I don't have much "burn in" time with this, so I'm open to suggestions. One key difference between this approach and the Include Protection approach is this approach processes jQuery for each jQuery include. It drops it after processing it, but you still take the performance hit (you may not notice it, but it is still there). The include Protection approach only processes jQuery once.

Note: My script above assumes $ is for jQuery. The point of jQuery's noConflict is compatibility with other libraries that use $. If you find yourself in this situation, just remove $ from the assignments above. For compatibility reasons, you should probably never use $ except in a closure, but...

Warning: PT_JQUERY_1_6_2_JS is NOT safe for use with multiple versions of jQuery. The noConflict call at the end of the script is compatible with $, so if you have another, more recent version of jQuery, $ will still point to your newer version. The jQuery variable, however, will only point to the last version parsed (or the last assignment, as shown above). $ is nice, but it is really the jQuery variable that matters. To be compatible with other versions of jQuery, the HTML definition would have to use jQuery.noConflict(true). The jQuery docs don't recommend having two versions on the same page, but it is important to note.

Friday, May 31, 2013

jQuery in PeopleTools 8.53

A lot of customers are now working with PeopleTools 8.53. If you open Application Designer and search for HTML definitions named PT_JQUERY, you will see there are 2 (sometimes more) new jQuery JavaScript definitions included with PeopleTools 8.53:

  • jQuery 1.6.2
  • jQuery UI 1.8.17
  • Mobile jQuery (modules with mobile apps)

You no longer need to download, upload, or otherwise install jQuery to use it with PeopleSoft applications. One interesting thing I noted in the PeopleTools jQuery file is that the end of the jQuery file uses jQuery.noConflict() to replace $ with ptjq162. Unfortunately, it doesn't take advantage of the include protection I described in my post jQuery Plugin Include Protection, so be careful using it in pagelets directly.

Monday, April 01, 2013

jQuery Plugin Include Protection

I have a few blog posts that show how to use jQuery plugins on PeopleSoft homepages. When designing those pagelets in Pagelet Wizard, it is important that your XSL/HTML include jQuery and any necessary plugins within your pagelet's HTML/XSL. This is how my Slideshow and Accordion Navigation templates work. Including jQuery and required plugins in each pagelet, however, means that a homepage using these pagelets will have multiple instances of jQuery. jQuery is designed to load once, with plugin scripts loaded as needed. Since each pagelet has its own pointer to jQuery, as each pagelet loads, the browser tries to reload jQuery, redefining the jQuery and $ global variables and resetting the collection of previously loaded plugins. The end result is that a homepage with multiple jQuery based pagelets will only have one working pagelet. The rest will have been invalidated by the last pagelet to load jQuery.

The jQuery documentation discourages the presence of multiple instances of jQuery within the same page. The theoretical concept is that each page should load jQuery once, and sites should be written to include only one jQuery script tag. The nature of homepages with their independently managed fragments doesn't allow for this. The way I work around this is to wrap the jQuery JavaScript library in something akin to the C-style header #ifndef include guards.

After downloading the jQuery JavaScript library, I wrap the contents of the file in a conditional block that looks something like this:

if(!window.jQuery) {
/* downloaded, compressed/minified jQuery content goes here */
}

I make the same change to jQuery plugins because they often include their own setup and usage data, but, of course, testing for a different variable. Here is my jQuery UI processing protection:

if(!window.jQuery.ui) {
/* downloaded, compressed/minified jQuery UI content goes here */
}

This minor change to the jQuery JavaScript library and plugin files keeps the browser from re-interpreting these JavaScript libraries. The browser interprets these file once, and then fails the conditional for each subsequent script tag that points to that particular library. This allows plugins to load as needed and all plugin setup and usage data to persist across multiple pagelets.

Of course, the best solution would be to just have each JavaScript file referenced once. Since that isn't practical on a homepage, this solution at least ensures the files are only processed once.

Thursday, October 20, 2011

Slideshow News Publications

This post follows my Accordion Navigation Collections post and contains the XSL I used at OpenWorld to convert an Applications (formerly Enterprise) Portal news publication into a slideshow. The XSL assumes you have images associated with your news content. Even though the XSL and JavaScript will operate fine with images of different sizes, I recommend that each of the images used with this XSL be of the same size. Here is the XSL: slideshow-hosted.xsl

All of the usual disclaimers apply. Don't trust anyone else's code -- Understand what it is doing before you use it. You take full responsibility for the code once you download it. Don't delegate your responsibility, especially to someone that offers you code for free.

Disclaimer: I make no warranty regarding the use of this XSL.

Security Warning: To make sure the XSL will work "out of the box," I pointed the JavaScript at Google's hosted JavaScript API's and the jQuery Cycle download site. Since this code is used on your enterprise home pages, I suggest you replace these references with references to your own site's versions of these libraries. The thought of allowing some external service to run code on my pages makes me a bit nervous.

Monday, October 03, 2011

Accordion Navigation Collections

A few months ago we released a White paper about PeopleSoft Applications Portal and WorkCenter Pages that showed screen shots of an accordion menu. A lot of you asked how we created these pagelets. Tomorrow in our OOW session PeopleSoft Answers: How to Create a Great PeopleSoft UI, I will demonstrate creating the pagelet, but we won't have time to walk through the XSL -- the critical piece. For those of you that will be there (and those that won't but know how to use Pagelet Wizard), here is the XSL: accordion-nav-hosted.xsl.

Disclaimer: I make no warranty regarding the use of this XSL.

Security Warning: To make sure the XSL will work "out of the box," I pointed the JavaScript at Google's hosted JavaScript API's. Since this code is used on your enterprise home pages, I suggest you replace these references with references to your own site's versions of these libraries. The thought of allowing some external service to run code on my pages makes me a bit nervous.

I have to point out a minor difference between the output of this XSL and the output shown in the white paper: This XSL opens links in the current window or a new window. It does not use modal dialogs. Navigation Collection XML contains absolute PSP URL's, which don't display well in a modal dialog. The version shown in the White paper actually uses a custom transformer and some PeopleCode to convert psp URL's into psc URL's for dialogs.

Update March 5, 2012: Leandro, a reader of this blog, posted his derivative of this stylesheet. You can download it here. Leandro wants to make sure you know that it works on the single nav collection for which he tested, but other exceptions may arise. I looked through the XSL, and it looks good. Here is a list of the differences between Leandro's version and mine:

  • Updated the links to jQuery and jQuery UI (JS and CSS) to the latest versions.
  • Commented out the custom dialog framework code that would open jQuery UI dialog IFrames (because the code to make the iframe is not present in Jim's original).
  • Included the description of the top-level folders in the H3 tag's title attribute, so mouse-over of the accordion items will display the description of the menu. (This was already done by you for inner folders and shortcuts.)
  • The resulting accordion menu will be sorted as you would typically find in a PeopleSoft navigation collection: all folders before all shortcuts, and the "# more..." pseudofolder (if any) at the end.

Tuesday, April 05, 2011

Pagelets, WorkCenters, etc in White Paper

Some of my friends from sales and product strategy just put together a very nice white paper on some of the new features in PeopleTools and Applications Portal (formerly known as Enterprise Portal). I created some of the content in the screen shots (home page layout, accordion navigation collections, slide show news publications, etc) and they did all the writing. Download a copy and see what you can do with your PeopleSoft application. The paper is titled PeopleSoft Applications Portal and WorkCenter Pages.

Thursday, October 15, 2009

Change the Advanced Search Page Default Search Operator

In my OOW presentation yesterday I showed that it is possible to change the default search operator for a specific advanced search page. The JavaScript required to implement this behavior follows:

<script type="text/javascript">
$(document).ready(function() {
var newValue = 9;
var coll = $("select[name='APT_UI_SCRIPTS_MENUNAME$op']");
if(coll.val() != newValue) {
coll.val(newValue).change();
}
});
</script>

Note: The code above uses jQuery for event handling and therefore requires that you inject jQuery along with the JavaScript above. I demonstrate how to accomplish this in the injection blog post referenced below.

In my PeopleTools book I provide full details for implementing this behavior, but if you want to get a head start, I'll give you some hints. First, you need a mechanism for injecting this JavaScript into a search page. To learn more about injection, read my post Injecting JavaScript Libraries into PeopleSoft Pages. Next, you need a way to target a specific component. For this, see my post JavaScript complement of PeopleCode Global Vars. Your final step is to write some JavaScript to determine if the open page is a search page. I determine this by testing for the existence of an object named #ICSearch.

To determine the numerical code for a search page operator (9 = between), open the HTML source of any advanced search page and search for the option child nodes of PSDROPDOWNLIST.

Update (April 15, 2010)

The code above works great with PeopleTools 8.49 and lower. PeopleTools 8.50 uses Ajax to switch from the basic to the advanced search page. The 8.50 Ajax does not trigger the $(document).ready code. I have another solution for PeopleTools 8.50 (documented in my book). I'll post it soon.

Wednesday, January 31, 2007

Importing Custom Stylesheets into PeopleSoft Pages

Adding Web 2.0 behaviors to a PeopleSoft application usually requires adding Javascript, CSS, and HTML to a delivered PeopleSoft page. One way to do this (besides Monkeygrease) is to add an HTML area to a page and place your custom Javascript, CSS, and HTML inside that HTML Area. For more dynamic, data-driven customizations, you can use PeopleCode, HTML definitions, and a derived/work record to set and modify the contents of the HTML Area.

An issue that needs to be resolved when adding Web 2.0 behavior to PeopleSoft pages is how to style those custom HTML elements. If the elements are standard HTML form elements and you want to maintain a consistent look and feel with the PeopleSoft UI, then you can use the standard PeopleSoft CSS class names. However, if you want to go beyond the standard form elements, then you are going to need to add some additional style classes that may or may not be available through PeopleTools stylesheets. For example, the jQuery Thickbox plugin requires additional styles to implement the Thickbox behavior. If you were a web developer in complete control of the rendered HTML, you would either add these styles as a style element inside the head element or you would link them into the document by adding a link element inside the HTML document's head element. The problem is, even though you may be a web developer, you are not in complete control of the HTML rendered by the PeopleSoft application. Instead, you are a web developer that is in complete control of a piece of HTML that will be rendered inside the body element. Therefore, to comply with standards, you must avoid adding style and link elements using a PeopleTools HTML Area. Fortunately, we can use Javascript to import stylesheets. Here is a function I use to import custom jQuery plugin stylesheets:

function importStylesheet(sheetUrl) {
var ss = document.createElement("link");
ss.rel = "stylesheet";
ss.href = sheetUrl;
ss.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(ss);
}

If you plan on reusing this function, then place it in a file on your web server and call it like this:

<script type="text/javascript">
importStylesheet("/css/thickbox.css");
</script>

I tested this on both IE 6.0 and Firefox. I believe this is a standards compliant DOM manipulation. However, you may need to modify this for other browsers.

Thursday, September 14, 2006

Where am I?

Highlighting the active text field in PeopleSoft.

This past week I have been working with Monkeygrease. Monkeygrease is a very powerful tool for developers that want to enhance their existing PeopleSoft application user interface. In the next few paragraphs I will demonstrate how I used Monkeygrease and jQuery to highlight the active user input control on PeopleSoft pages without modifying any pages. To implement this example, you will need access to your PeopleSoft web server's PORTAL web application folder.

The most common file location for JavaScript and CSS files is the /scripts and /css directories. In keeping with this standard, I created the scripts and css folders in the root of the PORTAL web application. The only file location requirement for your scripts and css files is that they must be accessible to the client through your web server. The script and css file locations shown below are suggestions. If you place these files in different locations, then be sure to modify the monkeygrease.xml file accordingly.

Since this example depends on jQuery, download the compressed jQuery library from the jQuery website and save it in your web server's /scripts/ directory.

The JavaScript -- saved in file /scripts/highlight-active.js:


$(document).ready(function(){
$("input[@type='text'], input[@type='password'], select, textarea").focus(function(e) {
$(this).addClass("hasfocus");
}).blur(function(e) {
$(this).removeClass("hasfocus");
});
});




The CSS -- saved in file /css/highlight-active.css


.hasfocus {
background-color: #FFFF99;
}



Download the monkeygrease.xml file to your web server's WEB-INF directory. The only thing interesting about the monkeygrease rules file is the url patterns. The first url pattern, /ps[cp].*\?cmd=(?:loginlogout).*, matches the login and logout pages. The second url pattern, /ps[cp].*/h/.+tab=.*, matches homepage tabs. The third url pattern, /ps[cp].*/c/[^/]+, matches all components. If you use a pattern like /.*, then you will match all URL's. While that may be preferable, I chose not to match IScript, worklist, and external file URL's.

Since Monkeygrease is a Servlet Filter, you will need to modify the portal web application's web.xml file. See the Monkeygrease documentation for details. I was able to paste the web.xml code snippet from the documentation directly into my web.xml file without any modifications.


That's it!