A fellow developer ran into a problem recently when he tried creating a pagelet using the Pagelet Wizard. For the purposes of this post I'll simplify what he was doing in order to get to the heart of the problem. The underlying query he used for the pagelet had 2 prompts. The second prompt used the value of the first prompt to limit the values that are returned. You often see prompts like this where you first select a Business Unit first and then another value from a table where Business Unit is a key. And you need to select the Business Unit first or the 2nd prompt will return no values. When he ran this Query from Query Manager or Query Viewer, the prompts worked as expected.
Later he created the pagelet using this query in the Pagelet Wizard. The prompts from the query were picked up without any problem as Data Source parameters (Step 3 of 6 in the Pagelet Wizard.) By specifying them as "User Specified" for the Usage Type, you get the Customize Pagelet link (the pencil icon on the pagelet border) when it is published to the homepage. On the homepage he could click the pencil icon and the prompts were displayed correctly, but they didn't work. The first prompt could be selected. But the value returned had no impact on the second prompt. After we looked into it we discovered that it was an issue with this customize pagelet component (PTPPB_USER_PREF).
To get around this issue I suggested that a new component needed to be displayed whenever the pencil icon was clicked. Luckily this can be easily done. Whenever a homepage pagelet has been created using the Pagelet Wizard, a new content reference is added to the Portal Registry. One of the options that is available for a pagelet content reference is the content reference for the Edit URL Information. By default the Pagelet Wizard sets this to the delivered component (the one we discovered that doesn't work when using prompts where the first value should be used to limit the second prompt values.) So by overwriting this content reference, we can set it to anything we want. So that's what we did.
The new component was built using derived records and fields. So we could make the prompts work the way we needed them to. We had to write the values selected back to the table that is used to store Customise pagelet values for Pagelet Wizard built pagelets. This was easy enough to figure out. It's the PTPPB_USER_PRMS table, and is simply keyed on the Pagelet name, Pagelet Field and OPRID.
So problem solved, right? Not quite. The client we were working for had decided to allow quite a few users access to the Pagelet Wizard, not just developers or analysts. They figured if users could have access to Query Manager to build Queries, they could also have access to the Pagaelet Wizard to let them display their query results in a nice, easy to view format. This means that almost any Pagelet Wizard user could modify and redeploy this Pagelet. Each time this happens, the Customize content reference would get set to the default, over-writing our custom component's content reference.
This solution really is only an option where Pagelet Wizard is used by developers or analysts and is subject to change control, which is how it was at my previous employer. In this situation support documentation can be created to highlight the fact that if the pagelet is modified, the Customise content reference needs to be reset to our custom component.
In the end, my fellow developer had to customise the delivered Customise component, to make it work correctly. Sometimes you just have to customise, don't you?
16/03/2012
07/01/2011
Debugging the Save Warning
While developing pages and components, I'll sometimes get a Save Warning message, i.e. "You have unsaved data on this page. Click OK to go back and save, or Cancel to continue." when I try to leave a component with out having made any changes. This is often caused by PeopleCode updating the value of a field (often hidden) on your page. A quick way to figure out what is the offending field is to use JavaScript debugging. I often develop in FireFox and use the FireBug add-on. (Google Chrome and IE8 have their built-in debuggers.) After turning on your JavaScript debugger, go to the offending page and choose PT_SAVEWARNING JavaScript library. Find the checkFormChanged function and place breakpoints on both of the return true statements in this code block. (This is lines 181 and 184 in PeopleTools 8.50.)
Next add a new watch expression in your debugger:
Back in your browser window, do whatever you were doing to trigger the Save Warning message. This time the debugger should stop though and you can inspect your watch expression to see what Form element ID is the one that has changed. This normally matches the RECNAME_FIELDNAME of your field. You can then debug backwards from there in PeopleCode to find the code that is updating this field.
for (var j = 0; j < form.length; ++j) { bIsChanged = isChanged(form.elements[j], objFrame); if (bIsChanged && form.ICSaveWarningFilter) { if (form.ICSaveWarningFilter.value != "1") return true; } else if (bIsChanged) return true; }
Next add a new watch expression in your debugger:
form.elements[j].id
Back in your browser window, do whatever you were doing to trigger the Save Warning message. This time the debugger should stop though and you can inspect your watch expression to see what Form element ID is the one that has changed. This normally matches the RECNAME_FIELDNAME of your field. You can then debug backwards from there in PeopleCode to find the code that is updating this field.
02/12/2010
Improving PeopleSoft with jQuery - Some Examples (Part 2)
Making a Collapsible Data Area a Bit Better
Have you ever turned on the Collapsible Data Area property on a group box or grid? If you do, all you get on the page to expand or collapse your group box or grid is a little tiny triangle at the far left of the group box or grid label. It isn't that easy to click. Wouldn't it be better if you could click the entire bar to make your grid or group box expand or collapse? Well, here's a little snippet of JavaScript using jQuery that lets you do this.
Have you ever turned on the Collapsible Data Area property on a group box or grid? If you do, all you get on the page to expand or collapse your group box or grid is a little tiny triangle at the far left of the group box or grid label. It isn't that easy to click. Wouldn't it be better if you could click the entire bar to make your grid or group box expand or collapse? Well, here's a little snippet of JavaScript using jQuery that lets you do this.
//% New JavaScript used for making the entire bar of an Expandable/Collapsible Group Box clickable.
$(document).ready(function(){
//%This line finds all <img> elements with a title of "Expand section" or "Collapse Section", then gets the parent <a>,
//%then the parent <td>. On this <td> it 1.) updates the css to make the cursor a pointer and 2.) adds a click handler
$("img[title='Expand section'],img[title='Collapse section']").parent('a').parent('td').css('cursor','pointer').click(function(){
//%The click handler added to this <td> is a new function taken from the first <a> element that can be found in relation to this <td>
var theClick=new Function($("a img[title='Expand section'], a img[title='Collapse section']", this).parent('a').attr("href"));
theClick();
});
});
Points to Consider
- Based on PeopleTools 8.50 with a SWAN stylesheet.
- This code works on group boxes with a title positioned on the left of the group box. With group boxes where the title is positioned in the center or to the right it might not work. Or with grids that have any of the navigation bar items displayed then this will likely not work.
- Because of these limitations, I would not include this code on PT_PAGESCRIPT to make it a system wide feature. I instead would only include it on specific pages where I know the group box(es) or grid(s) will be formatted in the correct manner.
Summary
This has been another relatively simple example of how jQuery can make your PeopleSoft pages that much better.
25/11/2010
Improving PeopleSoft with jQuery - Some Examples (Part 1)
I must thank Jim Marion for turning me on to jQuery. He has made various posts over the last 3 or 4 years about it (see here.) I've also sat in on one or 2 presentations he's made where he's mentioned it. It's a great JavaScript library that lets you make even more improvements to your PeopleSoft application.
Since PeopleTools 8.50 (or maybe it was a late patch of tools 8.49) there is no longer a size limit on HTML Definitions. PT_PAGESCRIPT is the JavaScript definition that is included in all (or at least most) pages served up by PeopleSoft. This is now the best place for including the jQuery library.
So now that we have access to jQuery, what kind of things can we do with it? Here's the first of a couple of examples I've come up with.
Add options to the Page Bar
Have you ever tried to print a PeopleSoft page using your browsers print functionality. It doesn't always look good. Depending on the browser and what exactly has the focus when you choose Print, it may include the Portal Heading and the target content may have scroll bars included. I think it would be great if the Page Bar had an option to print the page. Here's a way of getting JavaScript and jQuery to do it for you.
Why do you need jQuery to do it? Because as a PeopleSoft developer, you don't have access to the Page Bar. It is not generated via an iScript, HTML Definition or an Application Package. You could use something like MonkeyGrease on your web servers to rewrite the response to include a new link on the Page Bar. But that seems to be a bit overkill. By using jQuery, everything is under control within Application Designer like most any PeopleSoft customisation.
So onto the code! Add the following to PT_PAGESCRIPT after the jQuery library. (I hope it is self documented well enough for you to follow through.)
Here's what it looks like
Since PeopleTools 8.50 (or maybe it was a late patch of tools 8.49) there is no longer a size limit on HTML Definitions. PT_PAGESCRIPT is the JavaScript definition that is included in all (or at least most) pages served up by PeopleSoft. This is now the best place for including the jQuery library.
So now that we have access to jQuery, what kind of things can we do with it? Here's the first of a couple of examples I've come up with.
Add options to the Page Bar
Have you ever tried to print a PeopleSoft page using your browsers print functionality. It doesn't always look good. Depending on the browser and what exactly has the focus when you choose Print, it may include the Portal Heading and the target content may have scroll bars included. I think it would be great if the Page Bar had an option to print the page. Here's a way of getting JavaScript and jQuery to do it for you.
So onto the code! Add the following to PT_PAGESCRIPT after the jQuery library. (I hope it is self documented well enough for you to follow through.)
//%New Print button added to Page Bar
//%Ensure that document is ready before proceeding
$(document).ready(function() {
//%Check if the Page Bar is on the page
if($("#PAGEBAR").length==1) {
//% Declare local variables
var printAnchor;
var printImg;
var newText = "Print Page";
//%Add new style to prevent #PAGEBAR from displaying when printing
$('<style media="print"> #PAGEBAR {display: none} </style>').appendTo('head');
//%Get the Page Bar div and table cell
var pgBar = $("#PAGEBAR");
var pgBarLinksCell = $("table > tbody > tr:eq(0) > td:eq(2)", pgBar);
//%Check if there are any anchors on the Page Bar
//%Though it seems if there is a Page Bar then there is always an anchor
if ( $("a", pgBarLinksCell).length > 0 ) {
//% If it is, clone the last one and separate the image from the anchor
printAnchor = $("a:last", pgBarLinksCell).clone();
printImg = $("img", printAnchor);
printAnchor.html("");
} else {
//%otherwise build it manually
printAnchor = $("<a tabindex='0'></a>");
printImg = $("<img hspace='0' border='0' align='absmiddle' vspace='0' ></img>");
var cssObj = {
'font-size' : '9pt',
'font-weight' : 'normal',
'font-style' : 'normal',
'color' : 'rgb(51, 102, 153)',
'text-decoration' : 'none'
}
printAnchor.css(cssObj);
}
//%set (or overwrite) the anchor attributes
printAnchor.attr("id", "OXFPRINT");
printAnchor.attr("name", "OXFPRINT");
printAnchor.attr("href", "");
printAnchor.attr("tabindex", parseInt(printAnchor.attr("tabindex"))+1);
//%set (or overwrite) the image attributes
printImg.attr("title", newText);
printImg.attr("alt", newText);
printImg.attr("src","/cs/FSQA850/cache/PT_PRINT_1.gif");
//%Add a click event to the anchor
printAnchor.click(function(event) {
//%prevent the default from occuring
event.preventDefault();
//%IE work-around printing in an iframe
try {
document.execCommand('print', false, null);
}
catch(e) {
window.print();
}
return false;
});
//%Combine (or recombine) anchor, image and text
printAnchor.wrapInner(printImg).append(" "+newText);
//%append the new Print Anchor to the end of the Page Bar
$(pgBarLinksCell).append(" ").append(printAnchor);
}
else {
//%write the code to include a Page Bar
}
});
Here's what it looks like

Points to Consider
- The path to the Printer image is hard coded. Meta-HTML %Image won't work in this situation because it is a JavaScript library. To make it better, you could use %URL or create an iScript that uses %Request.GetImageURL to return the path to the image and use jQuery within the script to make an AJAX call to the iScript.
- Also, I think the image is too gray. It's based on the older style. To match the newer swan style it should have more blue.
- I've tested this on IE7, FireFox 3.6 and Google Chrome 7.0.5. It's possible it won't work with other browsers.
Summary
With jQuery you have an extra layer of control over your user's interface. This was just one example of what can be done using the jQuery JavaScript library. I hope to post another couple examples soon.
30/09/2010
PeopleSoft Branding
Here's one way to change your PeopleSoft Portal Header from this
to something like this
Preface
I was grateful I discovered @peoplesoftwiki's great post about PeopleSoft Branding. It meant that this post wouldn't have to be quite as long. Because as it turned out I followed the same steps as @peoplesoftwiki (extending Application Package PT_BRANDING and overriding the Branding Package on PeopleTools Options page.) I went one or 2 steps further it seems so I'd like to expand on that.
Before I begin, I need to tell you the main assumption I made. We are moving to PeopleTools 8.50 and we have decided to use the new Swan style. This is important as there is code in PT_BRANDING methods that is wrapped in if statements checking whether the style = "swan". That meant I only had to focus on making changes to items where this was true.
And one more thing before going any further: configuration good, customisation bad. (Though I don't always follow that mantra.)
Application Package
So just like @peoplesoftwiki, I extended PT_BRANDING. I made a few changes, including:
HTML Definition
To make use of all this, I would either need to change the delievered HTML definition or create my own. So I created my own by opening the delivered PT_IFRAME_HDR_SWAN and doing a Save As to create OXF_IFRAME_HDR_SWAN. By doing this I had complete control over the HTML I wanted displayed. The main change I made was to the pthdr2container <div>, changing it from
to
The main changes were adding new <div> oxfblend, oxfheaderLine3 and clearer, new <span> oxfps and oxfgreeting and new <ul> oxfhdrlinks. I also removed %bind(:16), the search box, which we didn't think made any sense to have in the Portal Header.
Stylesheets
To make all these new elements on the page look any good, I had to update the Stylesheet. PSHDR2_SWAN held all the styles to control the Portal Header. For example, it defined the style pthdr2logoswan which has the background image as the Oracle Logo. Well we wanted to use the Oxfam Logo so I made a copy of PSHDR2_SWAN to create OXF_HDR2_SWAN and I made my changes to that.
Remember, configuration good, customisation bad. So I copied PSSTYLEDEF_SWAN to create OXF_STYLEDEF_SWAN. And in OXF_STYLEDEF_SWAN, I replaced PSHDR2_SWAN with OXF_HDR2_SWAN. When you switch to the new swan style, you update Default Stylesheet on PeopleTools Options to PSSTYLEDEF_SWAN. I instead switched it to OXF_STYLEDEF_SWAN.
Images
I had to create 4 image definitions in App Designer. Each of these are referenced in the stylesheet OXF_HDR2_SWAN as background images for 4 different elements.

Bringing it all Together
So here's how it all works together. The PT_BRANDING extended Application Package (with new methods) calls the new HTML Definitions. Updated or newly created bind parameters are passed to the custom HTML Definition to generate the content of the Portal Header. The new stylesheets and images provide the formatting for the Portal Header HTML. What you can come up with is only limited by your imagination.
to something like this
PrefaceI was grateful I discovered @peoplesoftwiki's great post about PeopleSoft Branding. It meant that this post wouldn't have to be quite as long. Because as it turned out I followed the same steps as @peoplesoftwiki (extending Application Package PT_BRANDING and overriding the Branding Package on PeopleTools Options page.) I went one or 2 steps further it seems so I'd like to expand on that.
Before I begin, I need to tell you the main assumption I made. We are moving to PeopleTools 8.50 and we have decided to use the new Swan style. This is important as there is code in PT_BRANDING methods that is wrapped in if statements checking whether the style = "swan". That meant I only had to focus on making changes to items where this was true.
And one more thing before going any further: configuration good, customisation bad. (Though I don't always follow that mantra.)
Application Package
So just like @peoplesoftwiki, I extended PT_BRANDING. I made a few changes, including:
- adding new methods to get data out of the system that I wanted to display in the Portal Header
- setGreeting, to prefix the Users greeting as set in Personalize Content with the description of the Environment as set in PeopleTools Options
- getOxfamLinks, to read and labels and links from the message catalog (labels being the message, and the links being the explanation text) to be displayed along the top of our branded portal.
- replacing calls to the delivered HTML Definitions that formed the basis of the Portal Header. Those 3 methods and the HTML defintions are
- getIframeHeaderHTML - PT_IFRAME_HDR_SWAN
- GetExpPasswordHdrHTML - PORTAL_EXP_PASSWORD_HDR
- GetUniHeaderHTML - PORTAL_UNI_HEADER_NNS_SWAN
HTML Definition
To make use of all this, I would either need to change the delievered HTML definition or create my own. So I created my own by opening the delivered PT_IFRAME_HDR_SWAN and doing a Save As to create OXF_IFRAME_HDR_SWAN. By doing this I had complete control over the HTML I wanted displayed. The main change I made was to the pthdr2container <div>, changing it from
<div id="pthdr2container">
<div id="pthdr2logoswan"> </div>
<div id="pthdr2greeting">
<span class="greeting">%bind(:15)</span>
</div>
%bind(:16)
<ul id="pthdr2links">
%bind(:17)
</ul>
</div>
<div id="pthdr2container">
<div class="oxfblend">
<div id="pthdr2logoswan"
onclick="javascript:window.location='%bind(:27)';return false;">
</div>
<div id="pthdr2greeting">
<span class="oxfps">%bind(:26)</span>
<span class="oxfgreeting">%bind(:15)</span>
</div>
<ul id="oxfhdrlinks">
%bind(:25)
</ul>
<ul id="pthdr2links">
<span>%bind(:17) </span>
</ul>
</div>
<div id="oxfheaderLine3">
<div class="clearer"></div><!--Important - ensures floats
are contained-->
</div>
</div>
Stylesheets
To make all these new elements on the page look any good, I had to update the Stylesheet. PSHDR2_SWAN held all the styles to control the Portal Header. For example, it defined the style pthdr2logoswan which has the background image as the Oracle Logo. Well we wanted to use the Oxfam Logo so I made a copy of PSHDR2_SWAN to create OXF_HDR2_SWAN and I made my changes to that.
Remember, configuration good, customisation bad. So I copied PSSTYLEDEF_SWAN to create OXF_STYLEDEF_SWAN. And in OXF_STYLEDEF_SWAN, I replaced PSHDR2_SWAN with OXF_HDR2_SWAN. When you switch to the new swan style, you update Default Stylesheet on PeopleTools Options to PSSTYLEDEF_SWAN. I instead switched it to OXF_STYLEDEF_SWAN.
Images
I had to create 4 image definitions in App Designer. Each of these are referenced in the stylesheet OXF_HDR2_SWAN as background images for 4 different elements.

Bringing it all Together
So here's how it all works together. The PT_BRANDING extended Application Package (with new methods) calls the new HTML Definitions. Updated or newly created bind parameters are passed to the custom HTML Definition to generate the content of the Portal Header. The new stylesheets and images provide the formatting for the Portal Header HTML. What you can come up with is only limited by your imagination.
28/07/2010
Most Recently Used
A new feature of PeopleTools 8.50 is the horizontal navigation menu that runs across the top of the screen below the header. It means the menu down the left hand side is no longer needed. This new horizontal menu has a Favourites menu item, and on this it keeps track of the most recently accessed components you have navigated to. But it is capped at the last 5. Wouldn't it be great to increase this, to 10 maybe. The Most Recently Used items are set using the PT_HNAV_JS HTML Definition. Line 1474 has a CONSTANT called MAX_MRU which is set at 5 as delivered. Increase this to 10 (or more if you want) and voila, your Most Recently Used items increase to 10.
Welcome
Welcome to my PeopleTools blog. I've been a PeopleSoft Developer for over 10 years. I've been regularly following a number of blogs for the last 2 years now and I thought it was about time I gave something back. So expect to find posts about various PeopleTools topics: App Designer, PeopleCode, Portal, PIA, App Servers, Integration Broker, and so on. And tell all of your PeopleSoft friends.
Subscribe to:
Posts (Atom)