Adding Live Search to PeopleSoft Enterprise
In the past week I’ve been playing around with PeopleSoft’s built-in search engine (Verity) to come up with a better search experience for users. Riding on the wave of Google Suggest a lot of people have implemented a “live” search feature on their sites. So, I decided to sprinkle a little AJAX on top of PeopleSoft and build the same feature for Enterprise 8.4 and above. Check it out…
The most unbelievable thing about how I implemented live search on PeopleSoft is that I didn’t customize any delivered code. None. This was possible because of Monkeygrease. Monkeygrease allows me to “inject” JavaScript/CSS/HTML into a page before it’s delivered to the browser. On the back end, I created a simple PeopleSoft iScript to carry out the search and return the results in a <ul> tag… I thought about using JSON, but then that would have added more complexity to the JavaScript.
Here’s the iScript:
[WEBLIB_CSS_LSCR.ISCRIPT1.FieldFormula]
Function FormatPath(&Path As string) Returns string
Local number &i, &begin, &end;
Local string &stringToSearch, &stringToCut;
&stringToSearch = &Path;
&begin = Find(”{”, &stringToSearch);
While &begin > 0
&end = Find(”}”, &stringToSearch);
&stringToCut = Substring(&stringToSearch, &begin, &end - &begin + 1);
&stringToSearch = Substitute(&stringToSearch, &stringToCut, “”);
&begin = Find(”{”, &stringToSearch);
If &i = 1000 Then /* Safety break */
Break;
Else
&i = &i + 1;
End-If;
End-While;
Return Substitute(&stringToSearch, “.”, ” > “);
End-Function;
Function IScript_doSearch()
Local string &q, &node, &partialUrl, &fullUrl, &resultsHtml;
Local number &resCounter;
Local ApiObject &portal, &query, &results, &result, &cref;
Local Request &Request = %Request;
Local Response &Response = %Response;
REM If no query text avail, return nothing;
&q = &Request.GetParameter(”q”);
If &q = “” Then
Return;
End-If;
&portal = %Session.GetPortalRegistry();
&portal.Open(%Portal);
&query = &portal.GetSearchQuery();
&query.Language = %Language;
&query.QueryText = &q | “*”;
&query.RequestedFields = “CONTENT_PROVIDER,URL,SCORE”;
&query.SortSpecifications = “SCORE desc”;
&results = &query.Execute(1, 20);
If &results Null Then
&result = &results.First();
Else
&result = Null;
End-If;
&resCounter = 1;
While &result Null
&node = &result.SearchFields.ItemByName(”CONTENT_PROVIDER”).Value;
&partialUrl = &result.SearchFields.ItemByName(”URL”).Value;
&fullUrl = &portal.GetAbsoluteContentURL(&node, &partialUrl);
&cref = &portal.FindCrefByURL(&fullUrl);
If &cref Null Then
If &cref.Authorized And
&cref.isVisible And
(&cref.URLType = “UPGE” Or
&cref.URLType = “UEXT” Or
&cref.URLType = “USCR” Or
&cref.URLType = “UGEN”) Then
&resultsHtml = &resultsHtml | GetHTMLText(HTML.CSS_LIVE_SEARCH_RESULT, &cref.Label, &cref.AbsolutePortalURL, FormatPath(&cref.Path), &cref.Description);
If &resCounter = 8 Then
Break;
End-If;
&resCounter = &resCounter + 1;
End-If;
End-If;
&result = &results.Next();
End-While;
&portal.close();
If &resultsHtml “” Then
&Response.Write(GetHTMLText(HTML.CSS_LIVE_SEARCH, &resultsHtml));
End-If;
End-Function;
There are two functions in this iScript, FormatPath and IScript_doSearch. FormatPath just formats the path location of the search result item (where it’s stored in the portal registry). The IScript_doSearch is what calls the Verity API to carry out the search. In this function, I filter each result through the portal registry to see if the user has access to the item. This iScript performs amazingly well.
The iScript above references some HTML objects… here they are:
[HTML Object: CSS_LIVE_SEARCH] <ul> %bind(:1) </ul>
[HTML Object: CSS_LIVE_SEARCH_RESULT] <li> <a href="%bind(:2)" title="%bind(:4)" target="_top">%Bind(:1)</a> <div>%bind(:3)</div> </li>
The the only other things I needed to do was code up the JavaScript and CSS to insert into the page. You can view those here: live-search.js and live-search.css. I then “injected” these files via this Monkeygrease rule:
<rule enabled="true" name="Live Search" url-pattern="(/psp/?([^/]*)?/?([^/]*)?/?([^/]*)?/(h/|s/WEBLIB_EO_PE_LN.ISCRIPT1.FieldFormula.IScript_EPPLN_INFRAME)|/psc/?([^/]*)?/?([^/]*)?/?([^/]*)?/s/WEBLIB_PT_NAV.ISCRIPT1.FieldFormula.IScript_PT_NAV_INFRAME_TITLE).*" insert-at="head-end">
<![CDATA[
<script type="text/javascript" src="http://some.server.com/monkeygrease/lib/prototype.js"></script>
<link rel="stylesheet" href="http://some.server.com/monkeygrease/live-search.css" type="text/css" media="screen" />
<script type="text/javascript" language="javascript" src="http://some.server.com/monkeygrease/live-search.js"></script>
]]>
</rule>
As you can see from these Monkeygrease rules, the prototype.js library is required. I used this library to simplify the code… and it did just that.
February 6th, 2006 at 12:43 PM PST
Rich,
Ridiculously great! This is a fantastic demonstration of exactly why MonkeyGrease is such a great tool. Really cool stuff!
Dave
February 8th, 2006 at 7:06 AM PST
Great Work. I’m a PS consultant and I’ve actually implemented some Ajax tricks like this. One of them gave the ability to copy text on a page and asynchronously post that data to the server using a javascript driven contextual menu and the selection object. This posted data was received by an iScript (as you have done) and stored in a table that was used in another component. This basically gave the user an easy way to copy data from one component in the system to another without having customize peoplesoft objects, since it was all driven through a single html definition which included the js and html (as you have done).
I’m currently looking into using ajax to populate rowset data asynchronously behind a tab in a ps grid control to ease user perceived performance of a complex grid.
Cool to see somebody else is looking into this sort of thing with PeopleSoft as well.
February 8th, 2006 at 9:13 AM PST
Will, excellent! You should take a look at Monkeygrease (http://monkeygrease.org). It makes adding Ajax features to PSFT a lot easier.
April 27th, 2006 at 11:50 AM PDT
Rich,
This is awesome.
I was prototyping the resizing textarea along with peoplesoft using monkeygrease. I keep getting this error.
Safari can’t open the page “http://clancy.corp.apple.com:11400/psp/gcrmweb/EMPLOYEE/CRM/s/WEBLIB_PTPP_SC.HOMEPAGE.FieldFormula.IScript_AppHP?pt_fname=CR_SUPPORT&FolderPath=PORTAL_ROOT_OBJECT.CR_SUPPORT&IsFolder=true”. The error was: “bad server response” (NSURLErrorDomain:-1011) Please choose Report Bug to Apple from the Safari menu, note the error number, and describe what you did before you saw this message.
Page hangs on IE.
Any pointers….
May 4th, 2006 at 6:28 AM PDT
Daniel
Tried to get this working on PeopleTools 8.47 without success. I think part of the problem is that iscript record WEBLIB_EO_PE_LN.ISCRIPT1.FieldFormula.IScript_EPPLN_INFRAME does not exist. I wonder if this is because I do not have the Enterprise Portal? I do however have an inout box in the header and verity works. Presumeably I need to track down the iscript that creates that input box and use that in the monkeygreas.xml rule. 8.4x is quite new to me so any help on how to track down this iscript would be very welcome indeed.
Thanks
Graham
May 5th, 2006 at 4:48 AM PDT
Hi Rich,
I am new to Monkeygrease and was wondering if you had to install the servlet filter on the PeopleSoft Web Server? If so, could you post instructions on how to do so?
Great work!!!
Thanks,
Jeff
June 7th, 2006 at 3:03 AM PDT
I am trying to have a text search plugin in peoplesoft for searching applicant resumes. Want to use something other than verity. Have any of you worked on this?
September 11th, 2006 at 11:09 AM PDT
Rich,
I have been using AJAX with PeopleSoft to display database content to users without requiring them to navigate to separate components. This seems to be a very light-weight, user-friendly approach. Posting to an IScript with AJAX and writing the response to an HTML object (div, etc) is a logical approach. As you demonstrate above, this is a very user-friendly way to interact with data outside the current component buffer. But what about data within the current component buffer?
I recently wrote a budget module “bolt-on” for our PeopleSoft Financials system (EPM didn’t meet our user’s needs). Because budgets contain a lot of complex what-if calculations, I had to forego deferred processing in favor of a change-value/see-results real-time processing approach. Our budget users were accustomed to spreadsheet real-time calculation updates. I, therefore, had to emulate this behavior in my PeopleSoft pages. As you know, this makes data entry a bit more painful because users have to wait for the “flicker” associated with a page post-back for every field change (as I said, deferred processing was not an option).
AJAX provides the potential to interact with the component buffer (execute FieldChange PeopleCode, etc) without a full page refresh. Using a JavaScript library like jquery or prototype it would be possible to write a library that transforms the form post into an AJAX post with partial page rendering (PPR). Can you imagine the end-user applause? A generic library could be included in all pages using MonkeyGrease. Please let me know if you have any ideas for making this a reality. I posted a similar question on my September blog at http://jjmpsj.blogspot.com/. Wouldn’t it be great to be able to retrofit the existing PeopleTools 8.4 implementation with web 2.0 PPR using a MonkeyGrease script file?
September 11th, 2006 at 3:04 PM PDT
Hi Jim. Believe me, if it was easily done, this would have been the first thing I would have attempted. The problem is that the PSFT component buffer is not built for AJAX based transactions. At one point PeopleSoft was looking at doing partial-page refreshes on events that waranted it, however, I don’t know where that project ever went.
I’ve looked into do this on my own, but the problem is that a PIA page’s form is built for a full page submit. There’s really nothing that distinguishes a field change event vs. a save on the client side — I think all of that is handled on the appserver. So, because of that, it’s difficult to figure out what event to act on.
With that said, there are lots of other things you can do to improve a PIA page with Monkeygrease. I’ve seen other people improving the prompt drop-downs, adding context sensitive related data (similar to the Context Manager feature of the PSFT portal), replacing the date picker, adding WYSIWYG editting to textareas, etc.
Let me know if you end up building something with Monkeygrease… or Ajax enabling your PSFT app. I’m got a session this year at Oracle Open World on PeopleSoft and Ajax.
September 11th, 2006 at 4:15 PM PDT
Thanks Rich. I have used AJAX to add contextually related data to PeopleSoft pages as well. I’m planning to post some details on my blog. I am also currently working on a modified version of Chris Heller’s grid enhancement that will use jquery and MonkeyGrease. I will post details about this project on my blog when I’m finished.
I’m already signed up for your OpenWorld session! I am looking forward to it. See you in San Francisco!
November 25th, 2006 at 6:05 AM PST
Hi Jim
Excellent article.I like to implement AJAX for all search view in PS.We can get only 300 rows in any search view,so if you click next the user should retrieve faster.
Jim can you please help me on this
March 30th, 2007 at 12:42 PM PDT
[...] Check out his posting on adding live search to a PeopleSoft Enterprise Application -> http://manalang.com/archives/2006/02/01/adding-live-search-to-peoplesoft-enterprise/. His posting is using his server filter Monkey Grease, which enables him to inject the Java-Script [...]
July 28th, 2007 at 10:39 AM PDT
broadbeach holiday gymnasium aids beltone hearing
May 19th, 2008 at 8:44 PM PDT
[...] Guided User Input - AJAX et al One of these days, I will write a post on how we solved a common PeopleSoft user interface issue - lack of mouse over help for field and other UI elements. For now do check out this article by Rich Manalang on Adding Live Search to a PeopleSoft Application. [...]
May 28th, 2008 at 7:06 AM PDT
Zyban is an antidepressant and indicated as an aid to smoking cessation treatment.
http://cialis.buyantibiotics.net/buy-cialis-omline.html
August 15th, 2008 at 2:26 PM PDT
Great work Rich! We probably use your solution to one of our clients!! Thanks for sharing such a cool idea..:)