Sunday, February 10, 2008

What is an IScript?

It has been a few years since I attended my first PeopleSoft|Connect conference. As a new PeopleSoft developer, I was eager to learn all I could about PeopleSoft's Integration Broker, PeopleTools, and PeopleSoft's web UI. I spent hours pestering the experts (ask Robert Taylor, a prior Integration Broker product manager, and Tushar Chury, a former component interface developer). During one of the sessions I attended, someone from the audience asked a question about integration and the presenter replied, "I would probably create an IScript to do that." I don't remember the question. The only thing that stuck with me was the term "IScript." I had so many other questions for the experts that I didn't ask what an IScript was. Nevertheless, I left the event with a big question: "What is an IScript?" Since I had already taken the PeopleTools and PeopleCode classes and had not heard mention of IScripts, I decided they must be some legacy PeopleSoft technology that I didn't need to learn. To satisfy my curiosity, I looked up IScripts in PeopleBooks and received a... well... thorough definition... just like reading a good dictionary (see Enterprise PeopleTools 8.49 PeopleBook: PeopleCode API Reference > Internet Script Classes (iScript)). Yes, after reading the definition in PeopleBooks, I knew what an IScript was, but I just couldn't figure out why I would want to use one. Now, several years later, I find that I can't work without IScripts. Ajax, pagelets, WML, and SVG provide excellent use cases for IScripts. Each of these "technologies" requires marked up text without the overhead of the PIA rendered component HTML.

I like to think of IScripts as the PeopleTools developer's Swiss Army Knife. Besides a "cutting implement" a Swiss Army Knife might have a leather punch, a screw driver, a can opener, etc. Yes, you can do just about anything with a Swiss Army knife, but it might take you a long time to get the job done. Then, when you are done, the job might not be as satisfactory as it would have been if you had used the right tool. Have you ever opened a can with a Swiss Army Knife can opener? I'll bet you worked up an appetite. Likewise an IScript is the right tool for some jobs, but choose wisely. You can probably replicate the postback behavior of a component with an IScript, but it is a lot of unnecessary work. Likewise, you may have to consider multi-lingual translations, etc.

I compare IScripts to JSP or ASP. Basically an IScript is PeopleCode that has access to the Request and Response objects. Just like JSP and ASP, you, the developer, writes code to read parameters from the request and write information, data, etc to the response. Unfortunately, just like ASP, the response object's write methods only render text. Since the response object does not contain any binary write methods, you will have to ignore the dynamic image generation possibilities (I was hoping to use IScripts to render images stored in a user table, but I haven't figured out how to make that work since the write method only accepts plain text).

How do you create an IScript? For more information, you can look it up in PeopleBooks, but just to vaguely satisfy your curiosity, IScripts follow the same design pattern as FUNCLIBS. An IScript is a PeopleCode function stored in a record definition. The record definition name must start with WEBLIB_. The function can be in any field event of the record definition. By convention, we generally use the field ISCRIPT1 and the event FieldFormula. The function name, however, must start with IScript_ and cannot take any parameters or return a value.

How do you call an IScript? IScripts can be called a number of ways. How you call it depends on the purpose of the IScript. If your IScript is a pagelet, then you will create a CREF for your IScript in the portal registry under Portal Objects > Pagelets. If your IScript is called from JavaScript (Ajax, etc), then you call your IScript using a URL like http://server:port/psc/site_name/portal_name/node_name/s/WEBLIB_name.FIELDNAME.FieldFormula.IScript_name. To make it easier, you can generate an IScript URL using the PeopleCode built-in function GenerateScriptContentURL.

Now that you know what an IScript is, you might be interested in looking at some examples. Chris Heller posted a couple of IScripts that can be used as Bookmarklets. These Bookmarklets allow us, the developer, to exend our existing tool set by writing tools that we can use where we work: in the web browser. On Wednesday, April 4th, 2006, Chris posted a bookmarklet/IScript that will drill into a portal registry content reference from a PeopleSoft page. In his 2006 Open World and 2007 Alliance presentations, Chris showed us how to use IScripts and bookmarklets to turn on tracing and display security information. ERP Associates also has some good PeopleSoft Bookmarklet examples.

149 comments:

knan said...

Can you go over weblib and espacially over the createQueryURL and createqueryCrystalURL

shobana_shankar said...

HI Jim

Your post is excellent and i would like to talk more about iScript and i have few requirements to handle and i gues iscript is the solution but not sure how to use it efficiently.

Can i contact you ?...Is there an email or phone number i can reach you at.

Thanks in advance
Shobana

Jim Marion said...

@knan, I put it on the list. I will blog about those topics in the near future.

@shobana, can you post your requirements here? If so, that would be great. Then other readers could benefit from our discussion.

shobana_shankar said...

We are implementing ePay in PS8.9. The view paycheck page does not fit into one page when printed, its also getting cut off towards the right. When we print from the browser print, it goes to about 1.5
pages and it shows the url at the botton and also shows the view other paychecks links that is there on the page.

The users want to have button on the page that converts the page into a printable version (like the option you see on websites). There are two options in our mind.
1) Just convert the page into a neat html without the menu pagelet on the left side, compressing it into 1 page.
2) Compress into one page and then convert it to a PDF so that users can either print or save it.

We are unable to identify an optimal solution that would do one of the above.

I was thinking of creating a HTML definition that would have the paycheck layout in 1 page. Then have a button on the page that would call an iScript, passing the lines to be printed on the paycheck as part of the querystring in the url that is used to call the iscript. This iScript should in turn call the HTML and passing the parameters to it so that it fills out the paycheck with employee's pay data and then writes into a new browser window that will not have the menu pagelet and anyother PS page attributes like New Window link and so on.

This might not be the right solution, but this is the closest i could get to do this. In fact, this does not even adress the PDF conversion possibility.

Any better solution to acheive either of the 2 options would be greatly helpful.

Thanks in advance
Shobana

Jim Marion said...

@shobana, great ideas. I think you are on the right track. Here are a couple more:

CREF with different template: Depending on how the page is accessed, you may be able to create a link to the paycheck component and choose a different template. Templates control what additional content appears on a page, like the menu and header, for example. You can create your own templates as well. This option will remove the enterprise menu and header with the least amount of work. You could then put a "Printable View" link on the paycheck with PeopleCode to open the CREF in a new window... or use PeopleCode to populate an HTML Area that is a link to open the CREF in a new window.

XML/BI Publisher: If you are using PT 8.48 or greater, you can use XML Publisher to create a PDF version of your paycheck and link to it. This will run through the process scheduler. There are other Java based PDF renders and even some that convert HTML to PDF. You can either use an IScript and Java from PeopleCode to generate the PDF or you can use a servlet filter to generate the PDF. You can combine the CREF link/template option with a custom servlet and an HTML to PDF processor to convert the PeopleSoft HTML output to PDF. This would eliminate the header/footer.

IScript: If you use an IScript, then you should only pass the keys into the component as query string parameters, then use HTML objects, PeopleCode, and SQL objects to select the data. If you pass in the keys, you could even use a component interface to read the data from the base component if you don't know all the base tables and calculations, etc. With this option, the browser print function will still add headers and footers.

If you are going to do custom development, rather than write an IScript, you might find it easier to create a custom page/component with a CREF that uses a custom template and link to this from your main paycheck component with the text "Printable View" or something like that. IScripts can do just about anything, but they can be a real pain to maintain.

Jim Marion said...

@shobana, if you just want to view/print the component without the header and menu, then you can use the GenerateComponentContentURL function to create a URL to the component that does not include the portal markup. The GenerateComponentContentURL function creates a URL that matches the CREF's URL but uses the psc servlet rather than the psp servlet. You can see some example code on ChiliJoe's site: Direct access to a Component

Jim Marion said...

@knan, I'm still planning to cover the createQuery functions. Here is a post covering WEBLIB's: What is a WEBLIB. Is this what you were hoping to read? If not, let me know and I'll try to expand upon this.

shobana_shankar said...

Hi Jim

Thank you so much for reviewing my solution.

I have done the i narrated and i dont get header and footer or the menu through iscript. this is because the iscript url passes 'psc'instead of the usual psp portal servlet. This way the new window that opens just has the paycheck content.

http://foxlau05:8600/psc/dev89/EMPLOYEE/HRMS/s/WEBLIB_VMSA.SCRIPT1.FieldFormula.IScript_VMSA

About the pdf, do you think using java code in iscript wil help me do that ? Our tools version is 8.47.

Thanks much
shobana

Jim Marion said...

@shobana, If you want to output in PDF without using XML/BI Publisher, then you will need to use Java. You can find lots of Java PDF rendering engines. FOP is a PDF rendering project that takes XML and converts it to PDF using XSL-FO. Another option is to look into HTML to PDF converters. This would take your HTML page as generated by PeopleSoft and convert it to PDF. This could be wired up with a ServletFilter to transform a response prior to sending it to the browser.

David Vandiver said...

iScript is truly a great tool. I did a HEUG presentation on this in 2006. I also wrote an open source project that uses PeopleTool's iScript to format and open an Excel document from within the PS PIA.

The code is free at: http://sourceforge.net/projects/sqr2xml

Look for the package "peoplecode2xml" on the project "sqr2xml". Also, you'll find code here to send SQR output to Excel XML.

Laura said...

Hello Jim,

Thanks for your comments about iscript. A couple of weeks ago I went to my first Oracle training (Enterprise Portal), and I had the same experience as you had several years ago.
I am eager to learn more about this scripting language. But I don't know where to start. I searched PeopleBooks library, but there is no specific book for iscript. The same situation happened when I tried to find classes related to this topic. I searched the Oracle University courses, but I couldn't find any that teaches iscript.
Can you please help/guide me on this?

Thanks in advance,

Laura

Jim Marion said...

@Laura, I assume you already looked at the IScript labels on this blog. PeopleBooks has very good IScript documentation in the PeopleBook Enterprise PeopleTools 8.49 PeopleBook: PeopleCode API Reference > Internet Script Classes (iScript). IScripts are just PeopleCode functions that can be called from a URL. Therefore, it is possible to write any valid PeopleCode. The only differences between an IScript function and a FUNCLIB function is that an IScript has to follow certain naming conventions, an IScript doesn't take any parameters, and an IScript doesn't return a value. Instead, IScripts read parameters from the %Request object and write a response to %Response.

I primarily use IScripts as data sources for Ajax request handlers. I don't recommend creating user interfaces strictly with IScripts because IScripts don't have a component buffer or any of the other design features of a component. IScripts are great for non-interactive request handlers. For example, serving JSON to an Ajax request, creating a CSV, or even creating an HTML pagelet.

Laura said...

Hi Jim,
Thank you very much for your prompt respond. I have already downloaded the poeplebook you recommended.
But if I want to go deeper with this topic, is there any other source? Do you know if Oracle offers iscript courses? I looked at it, but there is no course with this name. Do you know if there is a course with a different name that covers this topic?
Thanks again,
Laura

Srinivas said...

Hi Jim,

Can I use an iScript to redirect a user from a PeopleSoft page to an external website when he clicks on a hyperlink? I also need to pass some information fields to the external website. And once the transaction is complete, the external website has to redirect the user back into PeopleSoft. Can this be done?

Thanks in advance
Srini

Jim Marion said...

@Srinivas, absolutely. If the data that you need to send comes from the component buffer, then just send the user to the external site directly from the page. No need for an IScript to do that. If you need to get additional data from the database, etc, then an IScript makes sense.

As far as getting back to PeopleSoft, send the external system a callback URL or configure it to have a callback URL that points back to the page you want to view. From an IScript, you can use the HTTP referrer header to get the source page, or you can use the strCurrURL JavaScript variable as the callback URL. The benefit of strCurrUrl is that it contains the level 0 search keys.

In your IScript, make sure you don't pass any parameters that can be derived on the server. For example, don't pass in OPRID because that can come from %OperatorID. Likewise, don't accept EMPLID unless you have a way of checking the EMPLID's and related information against the information available to %OperatorID. Failure to do so can open you up to Insecure Direct Object Reference.

BRIANH said...

I am using iscript to call the ESS folder navigation into a pagelet which we use on the Poeplsoft homepage. Now everything works fine except some of the folder links then use psc instead of psp (like Payroll and Compensation) and thus use the content servlet. The causes us to lose the left hand menu navigation when that is clicked. Any thoughts?

Jim Marion said...

@Brian, I've been thinking about this since you posted the question last week. I'm not too familiar with the application specific Employee Self Service folders. These are Navigation Collections, right? Whether they are or not, I think the easiest thing for you to do is create your own navigation collection and publish it as a homepage pagelet. For more options, create the navigation collection and then use the Pagelet Wizard to create a homepage pagelet from the Navigation Collection.

Let me know if this seems appropriate or if I missed the point. Thanks Brian!

BRIANH said...

Hi Jim,
What you stated is exactly what I had to do. I am still not sure why calling the iscript directly does not work poperly but I gave up trying to find out.

Thanks for your response.
Brian

Jim Marion said...

@Brian, cool. Thanks for the update. You stated the problem, "some of the folder links then use psc instead of psp." I'm not sure why the application developer created the folder navigation collection that way. By creating your own navigation collection, you were able to ignore their decisions.

Vignesh said...

Hi Jim
When a user clicks on the url of the Job posting in the third party system(JOB PORTAL), it takes me to the login page of our portal, is it possible to take the user to specific JOB details page without loging in.

Jim Marion said...

@Vignesh, yes, if you enable anonymous login in your web profile and grant access to the component to your anonymous user. To generate a URL to a specific component, use the URL in the address bar and add the search record's keys as query string key=value pairs. The easiest way to acquire a URL for a specific transaction is to view a page's source and search for strCurrUrl in the JavaScript.

Srinivas said...

Hi Jim,

This is a follow-up to my previous post - I'm proceeding to development from due diligence. Currently in our PeopleSoft system, customers have the ability to pay off items using credit cards. With the strict PCI data security requirements, we want to outsource the credit card processing piece to a vendor. So on the payment page, on clicking the 'Pay by credit card' URL, we need to do a http post to the vendor's hosted order page, while passing the first name, last name and the order amount info. I also need to include a signature using function which is contained in an include-jsp file that is provided by the vendor. The customer will fill all the credit card info on vendor's website and complete the transaction. I can configure the return URL for PeopleSoft on vendor site's config page to get the control back.

I tried putting a HTML area with a 'Buy now' button on the item page and tried a post to the vendor's site, but PeopleSoft generates a relative URL and control remains on the same page. I don't know how I can use iScript in this case as I just need to transfer control over to external site and am not responsible for their content.

Thanks in advance,
Srini

Jim Marion said...

@Srinivas, interesting dilemma. Without knowing the contents of the jsp, I think you need to post to the JSP, and then have the JSP post to the credit card processor? There are a handful of ways to accomplish this. The most obvious is to put an HTML area on a page and insert a form into that HTML area with hidden input elements and a submit button. The action for the form would either be the jsp or the credit card processor. PeopleSoft will not generate a URL when you insert one into an HTML Area. If you are seeing a relative URL, then it is because you are not correctly specifying a URL and your browser is deriving one for you.

It seems like I remember PeopleSoft having trouble with nested forms (the main page has a form), so this HTML Area/form option may not work. As you appropriate mentioned, an IScript is another alternative. The purpose of the IScript in this instance is to "break out" of the PeopleSoft form and component processor. In this instance, your button or link would point to the IScript. The IScript would return an HTML document containing a form. The form would have the action set to the target jsp or credit card site. The form's method would be set to POST. The form would contain hidden input elements for each of the items you need to send. The HTML document's body element would contain an onload element containing JavaScript to submit a form. You can find lots of examples of this online.

Srinivas said...

Hi Jim,

Thanks for your prompt response as always. I had tried out the HTML area knowing the one-form limitations. Then, per your suggestion, I tried the IScript. So the hyperlink on the PeopleSoft page calls the IScipt which gets the html text from a HTML definition and I tried to paste the contents of it below, but could not. I found some onload code examples on the internet and tried using them, but clicking the link is just refreshing the page rather than forwarding to the target URL. While refreshing, the status bar on the browser briefly shows the URL for the PS page with the presentation servlet(psc) in it. Can you please help me?
Also note the include for HOP.jsp, I'm not sure where on the web server to place this jsp.

-include file="HOP.jsp"
form -action="https://orderpagetest.ic3.com/hop/orderform.jsp" method="POST"

-body onLoad="javascript:firstrun()"

Vignesh said...

Hi Jim,
After publishing the message how do i clear the existing instance of a node?.

Now what's happening is a message goes to Node A with one XML, the same message with different XML to node B now it goes to both node A & Node B.It should go separately to Node B but it also goes to node A

Jim Marion said...

@Vignesh, depending on your tools version, it sounds like you either have a routing for both nodes A and B or a relationship for both nodes A and B.

I recommend posting your question on PeopleSoft OTN forum. Several talented PeopleSoft experts monitor the OTN forums.

ap said...

Jim,

Is it possible to set HTTP response codes on an Iscript %Response object?. We need to use Iscript to throw error messages in certain use cases of the Iscript. Currently by default these erros can go back to client with status code 200. We need to make it a 500. (Just like how SOAP faults are thrown to client). BTW im not using any webservice...

Jim Marion said...

@ap, good question. Did you try throwing an uncaught exception (CreateException)? I don't see any Response methods or properties for setting a return code. You might also try opening a support case. If we don't provide a method, then perhaps we can get this as a future enhancement.

ap said...

I remember using CreateException and I think I still got the exception with a HTTP 200..Let me retry it just to confirm... BTW opening a support case will back to us...I work for the PeopleTools team :)

Jim Marion said...

@ap, Another option is to use a ServletFilter. You could add a custom header to your %Response, and then use a ServletFilter to set the HTTP response based on the custom header. In your web.xml, you will want to map the ServletFilter to the IScript's URL pattern. I would recommend using this ServletFilter for all IScripts for flexibility. If the custom header doesn't exist on a particular IScript response, then the ServletFilter would ignore the response, passing it through untouched.

ap said...

Jim,

Interesting idead of using a servlet filter. I understand that we can override the status in the response object in the filter, but how do I read the header from the iScript response. I can read the headers in the client request but i cant read the header in the reponse set by the iscript. Is it possible to read response headers in filter..I know we can set and then get it HttpServletResponseWrapper but how to read the reponse header with it?. Help me with a snippet..

Jim Marion said...

@ap, I don't actually have an example. You IScript's %Response.SetHeader(...) will add a header to the http response returned by the psp/psc servlet. Your ServletFilter will be in the "chain" to receive the response from the psp/psc servlet after the call to chain.doFilter returns. At that point you can modify the HTTP response by either modifying it directly or wrapping it with the HttpServletResponseWrapper.

Vignesh said...

Hi Jim,
I'm Working on Peoplesoft Portal, currently we have tabs in our portal , we need to have subtabs( like sub menus).
Say when i click on any one of the main tabs it should display the subtabs with its menu folder opened. Can i know the place(like App package or HTML) to create the my sub tabs.Is it possible to customize of that kind

Thanks in advance...

Vignesh

Jim Marion said...

@Vignesh, yes you can make that type of customization. It isn't very easy, but certainly possible. In your branding you can add a custom element and then insert that into your header HTML template. I would use an App Class to implement the PeopleCode multi-level tabs. You could even use the portal registry to store the second level of tabs. Again, it isn't easy, so I won't explain exactly how to do it here, but it is certainly possible.

kayal said...

Hi Jim,
My name is Kayal and this is exactly what i am trying to achieve.

1. I sign in to my portal, i see a pagelet that has a url, when i click on the url it takes to a third party system. this third party system has to get the encrypted user id from my portal for it to sign in as that particular user id.

2. In my portal i have a encrypt.js file that the third party provided me to use it to encrypt and the value in post url.

These are the steps i followed:

1. I have a encrypt.js file in my web server
2. I want to create a pagelet that sources this javascript (pagelet wizard with html data source)
3. Now i want to use a function within the js file which encrypts the user id that it will get from the database
4. in order to get the user id that is currently signed in, i created an iscript like this:

Function IScript_RoomManagementSystem()
Local string &UVID;
&UVID = %UserId;
End-Function;

5. Now, i edited the content reference of that html pagelet that i created earlier to call another column that points to the iscript within a record field formula.

But, i am unable to get the user id from the iscript.

Please advise.

Here is my HTML that i have within the pagelet wizard. I have removed the tags with the brackets.

html
head
meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
titleLoyola University Chicago: Room Management Systemtitle

meta name="keywords" content="RMS"
meta name="description" content="RMS"

script type="text/javascript" src="https://webserver2.luc.edu:1234/environment/encrypt.js" script
head
body
script
function encryptValues(){
alert(document.rms.RMSPassword.value);
document.rms.RMSUserName.value=EncodeKey(document.rms.RMSUserName.value);
document.rms.RMSPassword.value=EncodeKey(document.rms.RMSPassword.value);
document.rms.submit();
alert(document.rms.RMSUserName.value);
alert(document.rms.RMSPassword.value);
}

script
form action="http://web1.is-svr.luc.edu/PortalProcess.asp" method="post" name="rms"
a href="javascript:encryptValues();">Access the Online Campus Housing Program a
input type="hidden" name="RMSUserName" value=&UVID
input type="hidden" name="RMSPassword" value=&UVID>
form

body
html

Jim Marion said...

@kayal, you are 99% of the way there. You are correct in creating HTML and putting a script tag in there to reference the external encrypt.js file. I think the problem, however, is with your PeopleCode. You can't directly execute PeopleCode from the Pagelet Wizard. There are ways through IScripts and source IScripts, that you can call PeopleCode functions, but here is what I think you really want to do:

1.Place your HTML in an App Designer HTML definition and put %Bind(:1) where you currently have value=&UVID so that it reads value="%Bind(:1)".

2. Instead of using Pagelet Wizard, create an IScript that serves the HTML definition. Your PeopleCode will look similar to the PeopleCode you already have, but it will pass &UVID to GetHTMLText(...) and you will write the result to %Response.

3. Create a CREF in Portal Objects > Pagelets > whatever category.

4. Add the new pagelet to a homepage in portal objects > homepage > tabs.

Pagelets are just CREF's, so you don't need to use the pagelet wizard. One of the steps of the pagelet wizard is actually to create CREF's.

Vignesh said...

Hi Jim,
I want to save a Peoplesoft page as PDF, for that i had added an html area in the page
and added the code in that

SCRIPT LANGUAGE='javascript'
function test()
{
document.execCommand('SaveAs',null,'Filename.HTML');
}

// reset onclick evnet for print button

if(document.forms(0).PA_BTN3)
{
document.forms(0).PA_BTN3.onclick = test;
}

SCRIPT

When i give file name extension as HTML its working when i give it as PDF its not producing the PDF, please provide me solution is there any other way to save my file as PDF.

Jim Marion said...

@Vignesh, I am not familiar with browser support for saving files as PDF. I know you can print to PDF, but I am not familiar with browser JavaScript print API's (if any). It is my understanding that developers usually use XMLPublisher to create PDF versions of PeopleSoft pages. These developers then add links to PeopleSoft pages to run those XMLPublisher reports. Using the ProcessRequest API and Run to window (RENS), you can launch the XMLPublisher report in a new window and have it open when the process completes.

James said...

How do you pass an argument/parameter from a CREF to an IScript function? For example, let's say you have a Function IScript_Some_Name(&isValid As boolean), and your CREF points to this function. How would I set the value to be boolean true from the CREF page? Note: The Additional Parameters section does not appear to work...the error I receive is "Wrong number of parameters for function IScript...

Jim Marion said...

@James, I think I see the problem. iScripts do not have traditional function parameters. They can accept input, it is just done in a different way. Redefine your function like this:

Function IScript_Some_Name()
   Local boolean &isValid = All(%Request.GetParameter("is_valid"));
...
End-Function;

This code sample assumes that the additional parameters in the CREF contains is_valid=true. It also assumes that &isValid should have a value of True if the is_valid parameter exists on the query string. You will require additional logic if you want to test for an actual true/false value. You can place any type of value in a parameter or query string.

You access the CREF's additional parameters through %Request.GetParameter(). Unfortunately, %Request.GetParameter will always treat additional parameters as strings. This makes sense because URL's are always strings and the HTTP protocol is a text based protocol.

hops said...

Jim,

Trying to create a page in my local Peoplesoft database that exists in another Peoplesoft database and have it look like it is part of the original component. Can't use dblinks or IBQueue's. Started by going direct to the other database and copying the URL into an HTMLArea which worked but had double menu/header, etc. Tried GenerateComponentContentURL with ViewContentURL/or ViewURL which also worked but instantiates the component from the foreign database effectively replacing the original local component requiring the user to go "Back" in IE to get to the original component. Now, on to an IScript called from a derived field(pushbutton) into an HTMLArea on the page. I have the WEBLIB record and function, and suspect I need to build the HTML by capturing JavaScript(from the Source of the foreign page?). Really only want the page but don't know how to strip out the page from the component so that it instantiates into the local component. Don't know much about IScripts. Don't know much about JavaScripts either. Any help u can give, including code, would be great. Initial efforts with storing JS file in an HTML object and calling it with
%Response.setcontenttype("text/html");
%Response.Writeline("<$cript src= "| %Response.GetJavaScriptURL(HTML.HELLOWORLD_JS) ">");
(example from Peoplebooks) failed with "not available in the context". (had to replace the S above with $ sign to allow posting to your blog) Is an IScript the only way to do this and if so, any help would be great. many thanks.

Jim Marion said...

@hops, I don't think iScripts are the best answer. Integration Broker messaging (synchronous or replicated/asynchronous) is the appropriate answer and db links is also a good answer. If you can't use dblinks or ib (as you stated), then you could use Ajax and iScripts to load this data. You will write your iScript in the source system, not the system with the page you are designing. If your other PeopleSoft application uses a different host name, then you will have to use a script tag to source the external data (to avoid cross site scripting) and will have to build the external content entirely on the client using JavaScript. This is a fine approach that can be done asynchronously and can look quite elegant, but is also very complex for the average PeopleSoft developer because it requires JavaScript, HTML, and PeopleCode knowledge. I suggest you start by writing a basic "Hello World" iScript, which is just a PeopleCode function written in the FieldFormula event of a record that is prefixed with "WEBLIB_". I have several chapters describing how to create iScripts and use JavaScript in my new book PeopleSoft PeopleTools Tips & Techniques. You can view and/or download the marketing flyer from my post: Marketing Flyer for PeopleTools Tips Book.

If your second PeopleSoft system is on the same server or is reverse proxied into the same URL, you can have your iScript return HTML and can use something like jQuery to load the external content. Then loading the external content is as simple as adding an HTML Area to your page with HTML that looks like:

<script type="text/javascript">
$(document).ready(function() {
  $("#JJM_ExternalContent").load("http://the.external.system/psc/iscript/url")
});
</script>

<div id="JJM_ExternalContent">&lt-- comment to keep tidy from stripping this empty div -->

If the external system is in a different URL, then your iScript will return JavaScript to insert/inject the information you want to add to the page. This is the same type of approach google gadgets use to build the gadgets in a page. In this case, your HTML area will contain HTML like this:


<script type="text/javascript" src="http://the.external.system/psc/iscript/url">
</script>

Dennis said...

Jim,

Thanks so much for all the great code. I have purchased 2 copies of your new book and was looking to download the source code from www.OraclePressBooks.com but did not find any code available.

Thanks,
Dennis

Jim Marion said...

I apologize Dennis. That is my fault. I am in the process of exporting the code for Oracle Press. I hope to have it finished this weekend.

Dennis said...

Jim,

Thanks for the quick response. Will the book be available in any ebook formats in the future ?

Thanks,
Dennis

Jim Marion said...

@Dennis, I don't know if the publisher will publish in electronic formats for sure, but judging from feedback and prior books, I suspect they will publish in a few electronic formats including kindle

Dennis said...

Jim,

GM: did not see the code on the Oracle website so I just figured that you got busy over the weekend. Can you just email me when the code is there ? dmissel@gmail.com

Thanks as always,
Dennis

Jim Marion said...

@Dennis, the code is taking longer to export than I thought. After writing the book, the code in my database matches the final chapter. I'm having to go back and re-apply each change chapter by chapter, and then export.

Srinivas said...

Hi Jim,
Congratulations on the success of your book on PeopleSoft Tips and Tricks. Your friend Steve Wills from Oracle preented a few tips from your book at a recent PeopleSoft RUG meeting. We are planning on ordering a copy for our team.
Coming to my issue, I had posted earlier regarding the integration of PeopleSoft with external website for credit card processing. I had trouble with the right location for the java server pages(jsp) so that the PS HTML definition can read it. With the PT8.47 version, it worked when I placed the file on the web server at PS_HOME\webserv\sitename\applications\peoplesoft\ PSIGW. We are now upgrading to PT8.50 and FSCM9.1. Placing the jsps in the similar location with PT8.50 is not working. Any thoughts?

Jim Marion said...

@Srinivas I work with Steve. He is a very bright consultant. I hope you enjoy the book.

From the back slashes, I'm assuming you are on Windows? I've deployed PT 8.50 on Linux, but not Windows. Either way, it is very similar. On Linux, I know that PSIGW is now PSIGW.war. Basically, it is the same though.

Put your JSP in any sub directory of "peoplesoft." I usually put them in PORTAL.war because that is the default web app, so you can reference files in that directory as http://yourserver.com/yourfile.jsp.If you put it in PSIGW, then you have to access it as http://yourserver.com/PSIGW/yourfile.jsp.

After placing the file in that directory, restart Weblogic (if you are using Weblogic). Whether or not the file is immediately available depends on your server mode (development, production, etc). J2EE servers in production mode don't run from those sub directories directly. Instead, they copy files off to a working directory and cache them (compile JSP's to class files, etc), so restarting your webserver usually causes it to reload that working cache.

Srinivas said...

Hi Jim,

You were right about the cache. I touched the application.xml on the web server and then bounced the PIA. The JSPs got compiled and I started seeing them. On the way back, the external site posts the response to an IScript and in it I read the parameters and show an HTML confirmation page. But I'm getting a message saying Warning: This page was reached in error. And I could see my IScript URL all fine in the browser. Again, this works perfectly fine in PT8.47 but I'm having issues with PT8.50. Any help is appreciated.

Jim Marion said...

@Srinivas, is this a psp or psc URL? I ask because this makes a difference in regards to the URL you see in the browser. If it is psp, then what you are seeing is the URL to your iScript plus the portal information. In this case, the actual URL to the content is in an iframe. If you use the psc URL, then you bypass the portal frameset and go direct to the content.

I recommend using Fiddler to see if your web browser is making any HTTP requests (redirects, etc) that you are not aware of.

byff said...

Jim, et al: I'm working on a rush project that utilizes some of the techniques you've discussed here. I'm nearly done, but am having trouble with the Keys parameter to the GenerateScriptContentURL function. I receive the error "Invalid parameter 7 for function GenerateScriptContentURL. (2,116) "

How should I format the keys? I've concatenated a list of values together using ampersands, and have tried key / value pairs associated with the equal sign and separated by ampersands. I would expect the string to have to resemble an ordinary querystring, but that's evidently not the case.

byff said...

Jim, et al: I'm working on a rush project that utilizes some of the techniques you've discussed here. I'm nearly done, but am having trouble with the Keys parameter to the GenerateScriptContentURL function. I receive the error "Invalid parameter 7 for function GenerateScriptContentURL. (2,116) "

How should I format the keys? I've concatenated a list of values together using ampersands, and have tried key / value pairs associated with the equal sign and separated by ampersands. I would expect the string to have to resemble an ordinary querystring, but that's evidently not the case.

Jim Marion said...

@byff, I don't have a reference right in front of me, but I believe it takes a record... at least that is how the GenerateComponentxxx functions work. What I usually do is create the string and just concatenate it at the end. I let the GenerateScriptContentURL function generate the URL, then I add:

| "?" | &parms

Where &parms is the key/value query string parameters

byff said...

Jim, according to PeopleBooks, it *does* take a record, but it didn't work for me. Maybe that's because I was using a derived record; the documentation doesn't specify. I also tried with a "created" record (using CreateRecord against a SQL Table record definition), but that didn't work either.

The solution I stumbled across was to simply omit the Keys parameter and append a well-formed querystring to the URL produced by the function. It works fine, and I'm kicking myself for not having tried it earlier (but I assumed there was some arcane reason why it had to be done as per the documentation...)

Thanks for responding.

Jim Marion said...

@byff, I usually use the same approach because I rarely have a record definition that matches the querystring structure. When I have used a record though, I've used CreateRecord, populated the record's keys, and then used SelectByKey to populate the record.

Neeraj Kholiya said...

Jim

You just rock , I was working with Iscript and third party application as posting data back to it . Every time I was receving "warning page error " I just changed it to psc and worked like charm . Thanks a lot SIr

Jim Marion said...

@Neeraj, thank you. I appreciate your encouragement.

Greetings To All said...

Hi Jim,

I am a PS Developer and i am new to IScript, I wish to learn more about IScript and working it within in peoplesoft, can you send me some materials, stuffs related to Writing IScript programs in PS?

Thanks,
DK

Jim Marion said...

@DK, My book has a full chapter devoted to iScripts. You can also look at Internet Script Classes in the PeopleCode API reference.

There are quite a few delivered examples as well. In App Designer, open any record named WEBLIB% and look for PeopleCode functions that begin with IScript.

BShreyas said...

Hi Jim

I am working on invoking the iscript in PT_COPYURL for generic cusomization.
I will be grateful if the following quesion is answered:
How do I get the name of the menu, component,page of the final page that gets formed, in iScript. %Menu, %Component do not wrk in this case. The problem will be solved even if I get the final url of the page that gets generated after incorporation of PT_COPYURL.

Thanks

Jim Marion said...

@BShreyas, see JavaScript complement of PeopleCode Global Vars and Injecting JavaScript Libraries into PeopleSoft Pages. My book also has a document.createElement option for inserting/injecting JavaScript as well.

Ankit said...

Hi Jim,
Could you please let me know the working of 'finfolderbyname'? I am on peopletools 8.18 and my code is using an Iscript function to call an external URL on the homepage of EPM 8.3. I need to change the external URL but I am not able to find how.Where can I find the folder collection on the server?

Jim Marion said...

@Ankit, you may want to ask this question on the ITToolbox and OTN forums.

Roger Martin said...

Hi Jim,

I need to integrate Outlook with Peoplesoft 9. Do you think it's possible to use iScripts in order to send emails thru outlook?

thanks for your great blog!

Jim Marion said...

@Roger, you can send e-mails from any PeopleCode event. iScripts may be appropriate for this. It depends on what you are doing.

Roger Martin said...

Thanks for your answer.

Do you mean with the sendmail function? My problem is that the smtp server available has a compatibility issue with Peoplesoft.

After some research I thought I could find a workaround using some embedded script that could call the Outlook app or an Office macro that could do the job. Do you think it's a good strategy?

Jim Marion said...

@Roger, Outlook automation would not work client side because your web browser doesn't have access to do those types of things. Server side MS Office automation usually doesn't work that well either.

I have always used the app server SMTP settings. You should file a case with oracle support if you found a compatibility issue.

Here are some server side alternatives to the PeopleCode SendMail function: #1 Java, #2 Shell scripting.

Srini said...

Hi Jim,
Thanks for the great blog.
I posted earlier also and this is related to my previous posts. I ran into a issue due to URL limitation when using the Iscript. I'm using the credit card worksheet in Accounts Receivable to gather all the items and send it to third-party for finishing the credit card transaction. So when there are over a 100 items in the worksheet and invoking the Iscript, I'm getting an error message. I think this is because Iscript strings out all the parameters into the URL and the length is going over the maximum. How can I get around this limitation?

Thanks,
Srini

Jim Marion said...

@Srini, are you posting content to an iScript and running into the URL query string parameter limitation? The query string method uses the HTTP GET method. The alternative is to use an HTTP POST. You can either use a form or Ajax to perform a post (jQuery $.post is probably the easiest). Does this answer your question?

Srini said...

Yes, but I was able to get around the URL length limitation by using Mozilla Firefox instead of IE (100,000 versus 2083 characters). So from the iScript, I'm using a HTML form to post to a jsp on the web server which instead posts a form to the third-party website. But when the the jsp loads I could still see all my form post parameters in the URL which in turn are getting passed to the third-party and it's issuing an error messsage saying URL is too long. How can I suppress the form input parameters to not show in the URL?

Jim Marion said...

@Srini, just to confirm. Your form uses the POST method instead of the get method. It posts to a JSP and the URL for the JSP has the query string parameters in the URL or the JSP is sending to an external target and after the JSP you see the parameters in the URL? It sounds like one of those two is using a GET instead of a POST. A way to know for sure is to install and launch Fiddler. I find it extremely valuable for this type of thing.

Abhishek said...

Jim... I wanted to know if we can call peoplecode from a HTML button.. I mean in our page we have a button created by HMTL button and one click of that button its opening a new popup window using showPopWin('html.html',false,false,null); ...

I need to do some Peoplecode Validation before opening the window... Is there a way we can Peoplecode from HTML or Call HTML showPopWin in Peoplecode...

Please suggest,

Jim Marion said...

@Abishek, PeopleCode runs on the server, not on the browser. There are two ways to run PeopleCode from a user interface:

1. Design your page as a PeopleSoft page/component instead of an iScript, and use FieldChange PeopleCode

2. Use Ajax to call an iScript prior to opening the new window.

robert said...

Hi Jim,
Do you have an iScript example of how to pass user ID and password to auto login to external website. (User clicks on a hyperlink on PeopleSoft page and it will take them to the external website without have to enter ID and password)

Thanks much for your help

Robert

Jim Marion said...

@Robert, whether or not you need an iscript for this depends on how you authenticate. If you want some PeopleCode to run that will communicate with the target system to generate an auth token that you send back to the browser as a cookie prior to a redirect, then you would likely use an iScript. Likewise, if the authentication information is stored in PeopleSoft and you want to create a redirect iScript that retrieves that information and formats an HTTP GET/POST, then you might use an iScript. Otherwise, you can put everything you requested directly in the HTML with the link to take you to the target system.

Unfortunately, I don't have examples of this type of iScript.

Abhishek said...

Hi Jim,

Is there a way we can open a new window using Iscript? I used %response.redirecturl but it opens in the same window... What my requried is on protal we have nav collection and one of the link(content ref) need to open a url basically enrollment handbook which will be dynamic url...

I created iscript and used in content reference.. When user click on the link it should open handbook in new window and should not lose the TAB from where the link is being clicked.

Can you please suggest.

Jim Marion said...

@Abhishek, generally speaking, you wouldn't use a CREF to open something in a new window. From a nav collection, yes, there is a checkbox for opening in a new window. The other way to open in a new window is to use the ViewContentURL function. There is also a CREF attribute named NAVNEWWIN. You can read more about that here: Portal External URL

imran's thoughts said...

Hi Jim, Hope this finds you in good health.

I am just a beginner in Peoplesoft. I have this Iscript confusion.
There is a component 'A' accessed by two groups of users with different role say role R1 and R2.
when user with role R1 Acesses component A an iscript is running calling an application class that checks whether a training record is available (as a business rule its required for the user to take an online training every year to access this component) if the training is expired(one year crossed)an online message is being displayed giving training expiry information. This check is working fine for users with role R1 as iscript is running fine. I am trying to implement the same training check for users with role R2 when they access same component. But im not able to invoke the iscript. Please suggest how can put this provision for users with role R2.

Thanks,
Imran

Jim Marion said...

@Imran, if it is an iScript that is invoked prior to the component, then the iScript is doing a redirect to the component and it is likely that a user could get the component URL and call it directly. I don't think an iScript is appropriate here. I think one of the early Component events would be more appropriate. Then you would use the IsUserInRole PeopleCode function to determine if the user is in one of the roles... but only if there are certain people that are allowed access all the time.

Sudheer said...

Hi Jim,

I want to read the data from active directory into peoplesoft. Could you please suggest me how can I approach to achieve this.

Thanks
Sudheer

Jim Marion said...

@Sudheer, I have little experience with Active Directory. PeopleSoft delivers directory code though. I suggest you review the signon PeopleCode that communicates with a directory server.

Dolphin Energy said...

The requirement is to apply css to certain pages. The Menu.Component name is in a table. I have an application package which returns "True" or "False", based on whether the passed string has one of the values in the table or not. The code in PT_SAVEWARNINGSCRIPT applies css. I also have a iscript that calls this Application package, which determines if css should be applied or not. How can I use this iscript in html, to determine if css should be applied or not.

Jim Marion said...

@Dolphin Energy, it sounds like you either need to call the iScript using Ajax and then inject your CSS accordingly, or use RowInit (or some other component event) to execute the same logic as the iScript (and skip the iScript).

Jim Marion said...

@Dolphin Energy, I saw your same question on the it toolbox and suspect that you want a generic solution that applies to all pages, not to a specific page. If that is the case, then I suggest you look at the "custom scripts" solution in the second section of my book. It shows you how to add a few lines of JavaScript to a delivered HTML definition to call iscripts on load. For post 8.50, you will want to follow the search page "monkey patching" example.

For CSS, this approach doesn't offer the most elegant solution because the CSS loads after the page so your users first see the content without your styles, and then they see the content change. You could modify the book's solution to NOT wait for the page to load, which would help. Give it a try and see what happens.

mymithraa said...

JIm,

How to maintain HTTP session? I tried to consume 3rd party web service and they ask me to main HTTP session to do other operation in their WSDL. In Java and other things we have some option to maintain http session. Please help.

Thanks,

Ap said...

@mymithraa - HTTP seesion I believe is maintained by cookies in http header. In this case you should be using integration broker. Add a HTTP target connector property - "header" with name-value pair for the header corresponding to maintaining the session. This connector property can be also filled programatically in request peoplecode.
-Balaji

Jim Marion said...

@mymithraa, I read the same question on the OTN forum. Hakan's recommendation is reasonable. Other options include storing the session ID in a table keyed by operator ID.

Gangaram said...

Hi Jim,
I have a query on the Calling Iscript from signon peoplecode. My requirement is creating a cookie when the uesr logging in thru Sign on peoplecode. to do that I am using An ISCRIPT which will create the cookie but. I am able to redirect with Hardcoded(psc/HRPSPDMO/EMPLOYEE/EMPL/s/WEBLIB_G.BUTTON1.FieldFormula.IScript_HelloWorld) value but not dynamically by using the delivered function with in peoplecode. When I using the GenerateScriptRelativeURL and %Node,%PORTAL variables are returning null string. am I doing some thing wrong here? kindly share your comment.

Jim Marion said...

@Gangaram, unfortunately, you can't use %Response in Signon PeopleCode, which means you can't use it to set cookies, redirect, etc.

Debu Guin said...

Jim, as %response is not working from signon peoplecode, how I can conditionaly redirect to a peoplesoft page designated through an available URL on sign-on?

Jim Marion said...

@Debu, unfortunately you can't choose the target from signon PeopleCode. Signon PeopleCode has no access to the response object and no way to interact with the browser.

The target is determined by the incoming URL. If no destination is specified, then PeopleSoft will send the user to his/her homepage.

Rohit Keskar said...

Hi Jim,

Please provide me with your valuable inputs on my below querry.

I want to change the color of the HEADER example-"Find the existing value" and "Add a value" of any search page which gets displayed on clicking left side Component link.

Abhishek said...

Hi Jim,

Can you please suggest if we can hav a web service or API to UPload files on Peoplesoft Portal from Share Point, We want to sync Share Point and Portal... ??

Thanks!

Jim Marion said...

@Abhishek, are you trying to import managed content from SharePoint? I'm not aware of an API for this. There are a lot of portal consultants on the IT Toolbox PeopleSoft Portal forum. That might be a good place to ask a question like this. Some of the consultants might have custom solutions for this.

Jim Marion said...

@Rohit, those colors come from images defined by PSTAB and PSTABNBO classes.

kvr said...

i am using generatecomponentcontenturl function which will take menu, comp, page etc as params and generates the url, to this url i am concatenating the var=val. usinge %response.redirect i am transferring to a new component.

And then i am using %request.getparameter("var") supposed to retrieve the val, which is not doing..what might be the reason.

If it is not correct.. please suggest me the correct way of sending some var, value combination to new component.
I am in PeopleTools 8.52 , App 9.1.. please help me in this regards.
Thanking you
KVRao

Jim Marion said...

@kvr, what you are doing is correct. Take a look at the returned URL to make sure it has a ? and the appropriate key value pairs. I use fiddler for this type of thing.

kvr said...

hi jim,

please explain your method.

Thank you
KVRao

Jim Marion said...

@kvr, Fiddler is a web debugging proxy. Install and launch it. That will configure your browser to run all traffic through Fiddler. From fiddler, you will be able to see the URL redirect along with all parameters, etc. This will allow you to see what is missing in your URL.

Pavan kumar Daninkula said...

Hi Jim,

Yout post is so helpful. please tell me how to call iscript from portal.
we have called from portal and inside iscript we used window.parent.closemodal() but it gives an error like object expected

Thanks.

Jim Marion said...

@Pavan, I assume you are using a /psp/ URL for the iScript. Since it works in your application, your application obviously has the closeModal JavaScript function defined within the page template. Since you get an "object expected" error when you try to call closeModal in Portal on window.parent, it either means you are attempting cross site/cross domain scripting and your browser is not allowing access to the portal site or the portal's page template doesn't have a closeModal method. Another possibility is that you aren't using a (i)frames based template for the iScript CREF in portal. If it is a cross domain issue, make sure your auth token domain is set in your web profile and that both sites are on the same domain. If it is a JavaScript error, then make sure the JavaScript is defined the same in both places.

Pavan kumar Daninkula said...

@jim

I have checked both cross site and i frames. we are using (i)frames based template for iscript CREF's and we have set auth token domain in out web profile but still have the same issue like "OBJECT EXPECTE" COMPONENT NAME
Please assist me any possible issues

Jim Marion said...

@Pavan, I have no other recommendation. I suggest you create a support case and post your question on the OTN forum.

Pavan kumar Daninkula said...

Hi Jim,

Can you please let me know how to find is portal page template having
closemodal method or not?

Jim Marion said...

@Pavan, I think you are looking for an HTML definition, not a CREF or portal template. The way to find it is to use the Edit | Find In menu command and search for CloseModal in HTML definitions.

PSbroker said...

Hi Jim ,

Excellent post!!
I have a requirement wherein , we require a popup window where user would enter/select multiple check boxes and then hit "OK". After that this data needs to be used in PeopleCode for some more manipulation.
Can I do this using Javascripts or HTML or even iScripts?

Jim Marion said...

@PSBroker, it will require all 3: HTML and JavaScript to open the popup window and display the form and then an iScript to process the results (PeopleCode).

Raj said...

Jim

In our QA environment, the modal window (message box or pop-up window) is coming normal , where as in Prod, the message box comes with maximized page. there is no custom code for this behavior , we are unable to trace the exact cause of this issue.

any ideas, what is causing this issue?

Jim Marion said...

@Raj, no idea. You might want to post on the OTN Forum and/or create a case with MyOracle Support.

Raj said...

Jim

The issue was related to AJAX property that is set in Web Profile. I believe In 8.52, the property is set to TRUE by default; IN 8.51.x, if you use this property and set it as FALSE, you will get this issue.
Once you remove it, it will work fine

Jim Marion said...

@Raj, good to know. Thank you for the response.

Hari said...

Hi Jim,

We are trying to resize an IScript based pagelet dynamically, based on the content.I mean pagelet content URL is being fed from the iScript.

We had this logic working in our PT8.49.23 version. Currently we are in the Tools upgrade phase and upgrading to PT8.52.12

After this upgrade we started facing issue with this resize. Given below is the iframe resize code.

&script = GetHTMLText(HTML.S_IFRAME_GENERIC, &url, "myworklist");
%Response.WriteLine(&script);

IFRAME code

html
script
function resize(){
myFrame = document.getElementsById("%Bind(:2)");
setInterval(function(){myFrame.height = myFrame.contentWindow.document.body.scrollHeight},1);
}
/script
iframe id="%Bind(:2)" src="%Bind(:1)" onload="resize()" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" vspace="0" hspace="0" style="overflow:visible; width:100%; height:100%; display:block" /iframe
/html


We are not getting the object for myFrame variable. Not sure why this is happening? Could you please help us on this?

Also this code is not work if we the pagelet page loads more data based on the field value selection. For ex: If I select a dropdown field value in the pagelet page then it will show a grid in the page. This time pagelet should resize automatically to accommodate the grid space too.

Please help us to achieve this and if there is a better approach to accomplish this please let us know

PS Note: I have removed the <> since html is not accepted.
Thanks,
Hari.A

Jim Marion said...

@Hari, I don't see anything from the code. I suggest you use firebug and add a few console.log statements to your PeopleCode to print out the value of %Bind(:2), myFrame, and setInterval. Once you know the value of %Bind(:2), run this in the JavaScript console and see what you get: document.getElementsById(Bind2Value).

By the way, nice use of closures with myFrame and setInterval. Just FYI, some browsers (used to or still do? not sure) leak memory when using DOM elements as variables in closures. The garbage collection process isn't able to clean them up. An alternative is to store %Bind(:2) as a string variable, and then call getElementById in your setInterval anonymous function.

Hari said...

Hi Jim,

We have changed the code like assigning bind variable to a local variable and then passing local variable to getelementbyid tag.

We tried to debug this logic by loading the page in Firefox. In the firebug console we are seeing respective iframe ids are getting passed one by one.

But if I have alert in the resize function it always displays only one iframe id multiple times (=number of iframe pagelets in a site). Not sure how to solve this auto resize issue.

Please help us to find a breakthrough for this issue.

Thanks,
Hari.A

I know everyone in my town said...

Hello Jim

I am fairly new to PeopleSoft. I was looking for some help on IScript and I came across your blog. It is really excellent piece of article.
I was wondering if you could help me with a little problem that I am having with IScript. I have a page on which a push Button is attached to an IScript code. When the pushbutton is clicked, it calls the ISCript function. The function itself get some server details etc, and then calls a HTML object. On HTML page, we allow users to upload files. These files get stored on another server. Now my upload functionality works. However, I am having trouble redirecting the upload page back to the previous page( where the pushbutton exists). I have used the
&Referer = %Request.GetHeader("Referer");
in the IScript function. This doesn't help. Could you please tell me what am I doing wrong?

Jim Marion said...

@I know everyone... I suggest instead of performing the redirect, you print the value of the Referer header so you can see what value is used in the redirect. I suggest printing the value when you first hit the iscript, and then also after the upload, but before the redirect.

You can use %Response.WriteLine(%Request.GetHeader("Referer"));

brian livingston said...

Jim, this all very helpful. I have a similar issue I am trying to work through. I have several HTML files that make a website and I am trying to find a way to put the files on my web server and then open the website in an HTML area in a PeopleSoft page. Where would I put the files at on the web server? Can this be done with Java scripts or APEX somehow. Any advice would be greatly appreciated.

Jim Marion said...

@Brian, if I understood what you said, you already have files on a web server. If that is the case, you do not need to copy those files to the PeopleSoft web server. I discourage adding files to the PeopleSoft web server for two reasons:

#1 They present an upgrade concern if you regenerate PIA during an upgrade

#2 They may trigger a requirement for a Weblogic license by violating the restricted use license granted by Oracle for PeopleSoft applications.

Your browser doesn't care where the files reside. It just needs them on some web server somewhere. The easiest way to display external content in PeopleSoft is to use an iframe. You can either use the Pagelet Wizard's URL data source to display external content, or add an HTML Area to a page with an iframe tag to add external content to a transaction page.

David said...

Jim, great article!

I'm thinking I need to use an IScript to read in some variables supplied by a third party vendor that is sending an applicant back to our site, but I'm not sure how to go aobut it. Could you please advise?

Also, is there a way to log out a user and then send them to another site?

Thanks!

Jim Marion said...

@David, both are interesting questions. For the first, if the applicant originated in PeopleSoft, then went to the third party site, and is now coming back, that applicant will still have a session token (if it didn't time out) and an iScript would be a reasonable approach to read query string parameters. I assume you would then redirect the user to a real component? An alternative would be to modify the target component's PeopleCode. You can access %Request items from component PeopleCode as well. The benefit of the iScript approach is that it wouldn't require modifying a delivered component.

For #2, yes, but it is a little bit odd. Signout clears everything including certain cookies. You can create your own cookies that will persist, however. There is also an HTTP, browser, or web server (can't remember which) limitation on the number of cookies, so you have to be careful using them. LocalStorage is another option. Anyway... what you do is set a cookie or LocalStorage value so that the signout template can read the value and navigate to the new target. You will have to update the signout template to make this happen. If the target is consistent, meaning all users go to the same place, then you can skip the cookie/local storage stuff and just use JavaScript to navigate from the signout template.

Akhilesh Kumar Singh said...

Hi Jim,

I am trying to implement captcha in PeopleSoft Portal 9.1 environment on signin.html page.
i have created JSP code to genearte captcha images. i have complied the code through online compiler and that is working fine.
I have created file with following detail's.
File Name : Generatecaptcha.jsp
File Location : PS_HOME\webserv\portal\applications\peoplesoft\PORTAL.war\ps\Generatecaptcha.jsp

i have done changes in signin.html file
<img src="<%=psCtxPath%><%=psHome%>/Generatecaptcha.jsp"

After restart webserver i am not able to see the image which need to be dispaly as per JSP program ouput. I am only able to see that is broken(Crossed) image on sigin.html page and when i am trying to save taht that save as filename.jsp.

Requesting you to please correct me in if i am missing any step.

Thanks.

Jim Marion said...

@Akhilesh, look at the URL generated for the captcha image to confirm it is correct. Also open the image URL directly to see if there are errors.

Allen Kuruvilla said...

Hi Jim,

I have written the following code in a Iscript function which will call an html page(a pop up page precisely)
&HTML = GetHTMLText(HTML.HP_AP_COMMENTS,&Comments);
%Response.Write(&HTML);

now within the html page, there's an input tag whose value, i need to capture in peopleocode.
I will be clicking on the ok button to close the pop up page.

Any hints??

Jim Marion said...

@Allen, when you say, "capture in PeopleCode" do you mean process on SavePostChange or some other PeopleCode event or do you mean just any old PeopleCode? If any old PeopleCode, then you can use an iScript and Ajax to send the value to PeopleCode.

If you need to get this value into the component processor, then add a Derived/Work field to the page and use JavaScript to update the value of that derived/work field. Once you have that working, try hiding the field, but click the "interact with JavaScript" checkbox.

Julio Alvarez Pinedo said...

Hello Jim

I want "disabled close browser web" in PeopleSoft. I can to use IScript? Where I should be the code?

Thanks in advance.
Mr. Juliusss...

Jim Marion said...

@Julio, you can't exactly disable close, but you can add a warning message to one of the JavaScript definitions like, PT_PAGESCRIPT. The close button is controlled by the web browser (and operating system).

SK said...

Hi Jim

Can we read data that was posted using HTTP POST using http listening connector through IB. I am using %request.getparameter but it is returning a null.

Thanks

Jim Marion said...

@SK %Request and %Response do not work with Integration Broker. Instead you have to read the full document posted and parse out what you need. This blog post tells you how to extract query string parameters from a GET request sent to Integration Broker. I don't have any POST examples.

SK said...

I was able to successfully read the query strings but was not able to read the document to get the post data. I do see that GetURIDocument is supported in 8.53 tools but no earlier versions. Can you point me in the right direction in reading the post data.

Jim Marion said...

@SK, GetURIDocument uses the REST service's URL map/pattern to populate a Document object from the URL. It is primarily for GET, not POST. It has been available since PT 8.52. I don't remember exactly which method to use to get unstructured, non XML, but try GetContentString and a few other methods. You can loop through the segments using Message. SegmentCount.

SK said...

This is non-xml data..The Http body content looks like:

NEW_ITEM-EXT_PRODUCT_ID[1]:
NEW_ITEM-VENDOR[1]:
HARB410000
NEW_ITEM-CONTRACT[1]:
NEW_ITEM-CONTRACT_ITEM[1]:
NEW_ITEM-CUST_FIELD1[1]:

Getcontentstring did not help.

Thanks for your responses I appreciate the feedback.

Jim Marion said...

@SK, try all of the get methods and loop through the segments. That is usually how I figure out which one to use.

RAMESH said...

Thanks for the post, Jim! Awesome you are!

Need to understand - whether we can access component buffer data such as rowset via Iscript (i guess not).

Can I use some variables/arrays that can store my temporarily values in Iscripts and get saved after i successful complete the transaction. I need to make my UI interactive and so I am using Iscipt for this.

Thanks!

Jim Marion said...

@Ramesh, iScripts are a great tool for making the user experience more interactive. Unfortunately, they can't access the component buffer. You can send them data (such as key values, etc) through query string parameters and POST data, which allows you to query the database for additional data.

iScripts are completely stateless with no state block on the web server, so there is no place to store variables between iScript calls. If you need to store values, you can generate a guid and use that throughout your component transaction as a pointer to a row in a table, and have your iScript look up values based on the guid you pass it in the query string. I like this method when passing lots of values. It is also a great way to satisfy the OWASP Top 10 Insecure Direct Object References issue.

RAMESH said...

Jim - Thanks! You are the savior!

Jim - Can you put more light on usage of guid. What I am doing right now is I have created a sql table/record with key1 , key2 and value (something like lookup table).And I am storing data in it while I am doing online transaction using iscripts.

It shall be helpful if you could point me to sample/example of usage of guid.

Thanks!

Kind Regards,
Ramesh H Singh

Jim Marion said...

@Ramesh, I have an example of the GUID scenario in chapter 5 of my book PeopleSoft PeopleTools Tips and Techniques. I have a couple of examples of generating a GUID in my blog post HOWTO: Generate GUID from PeopleCode.

Thank you for the "savior" compliment. I will accept the honor of assisting you, but for fear of being struck by lightning, I must deny being "the savior" ;). To loosely quote Steve Rogers in the Avengers, "There's only one God, [sir], and I'm pretty sure he doesn't dress like [me]."

RAMESH said...

This is awesome!

Explored loads, so far!

Jim - I got how we use GUID in Iscript. However, the ical example that you specified has one level of data stored. I need to store multiple data with same GUID (say something like we have level1, level 2 data).

Basicaaly, my requirement was - User may select one or more than one roles via UI and I need to store that in cache record using same GUID mutiple times(at different instance while the same session). So, with GUID as key, I could store the temparary cache guid record data into peoplesoft tables at the end of transaction.

Can you suggest me on this. Your guidance really works for me!

Thanks!

Jim Marion said...

@Ramesh you are correct, I was just using one row of data. I assume you have a header row and detail rows? Can you use the guid as your header key and use a composite key for your detail rows? The guid is used to uniquely identify the user's visit, but the composite key of GUID, OPRID, and ROLE (or just GUID, ROLE) makes the rows unique?

RAMESH said...

Jim - Need your suggestion.

Following is the .js. It triggers when I click on Submit button -

$("#submit_ar").click(function () {

var url_0 = apt.files.generateScriptContentUrl({
record: "WEBLIB_AZ_JSL",
field: "ISCRIPT1",
event: "FieldFormula",
script: "IScript_DeleteData"
});
//alert(url_0);
$("#temp_storage").load(url_0);


$("#box1View option.copiedOption").each(function () {
//alert(this.text + ' ' + this.value);
var url_1 = apt.files.generateScriptContentUrl({
record: "WEBLIB_AZ_JSL",
field: "ISCRIPT1",
event: "FieldFormula",
script: "IScript_AddRoleName"
});
var url_par1 = url_1.concat("?role=", this.value)
//alert(url_par1);
$("#temp_storage").load(url_par1);

});

$("#templatepopulation option:selected").each(function () {
//alert(this.text + ' ' + this.value);


var url_2 = apt.files.generateScriptContentUrl({
record: "WEBLIB_AZ_JSL",
field: "ISCRIPT1",
event: "FieldFormula",
script: "IScript_AddRowsecName"
});
var url_par2 = url_2.concat("?rowsec=", this.value)
//alert(url_par2);
$("#temp_storage").load(url_par2);

});

var url_3 = apt.files.generateScriptContentUrl({
record: "WEBLIB_AZ_JSL",
field: "ISCRIPT1",
event: "FieldFormula",
script: "IScript_AddEmplid"
});
var url_par3 = url_3.concat("?emplid=", EMPLID)
//alert(url_par3);
$("#temp_storage").load(url_par3);


var url = apt.files.generateScriptContentUrl({
record: "WEBLIB_AZ_JSL",
field: "ISCRIPT1",
event: "FieldFormula",
script: "IScript_SubmitAccessRequest"
});
//var url_par = url.concat("?url=", url)
alert(url);
$("#temp_storage").load(url);
});


RAMESH said...

and following are the Iscripts:

Function IScript_AddRoleName
Local string &input = %Request.GetParameter("role");
SQLExec("insert into PS_AZ_PASS_STAGING values (:1,:2,:3)", %UserId, "ROLE", &input);
%Response.Write("Inserted");
End-Function;

Function IScript_AddRowsecName
Local string &input = %Request.GetParameter("rowsec");
SQLExec("insert into PS_AZ_PASS_STAGING values (:1,:2,:3)", %UserId, "ROWSEC", &input);
%Response.Write("Inserted");
End-Function;

Function IScript_AddEmplid
Local string &input = %Request.GetParameter("emplid");
SQLExec("insert into PS_AZ_PASS_STAGING values (:1,:2,:3)", %UserId, "EMPLID", &input);
%Response.Write("Inserted");
End-Function;

Function IScript_DeleteData
SQLExec("Delete from PS_AZ_PASS_STAGING where KEY1 = :1", %UserId);
%Response.Write("Deleted");
End-Function;

Function IScript_SubmitAccessRequest
&targetUrl = GenerateComponentContentURL(%Portal, %Node, MenuName.AZ_PASS, "GBL", Component.AZ_PASS_DASHBOARD, Page.AZ_PASS_AR_SUMMARY, "U");
%Response.Write(GetHTMLText(HTML.AZ_PASS_NAVIGATE_PAGE, &targetUrl));
End-Function;


Basically, I am trying to insert all my UI transaction values in the table - Which I could you in page using page activate of AZ_PASS_AR_SUMMARY.

Please suggest If this could be better.

Also, the issue is, by the time last IScript_SubmitAccessRequest is called and page appears, all of the above database updates deletion/insertion are not completed. So, I don't get all the values in page as page activation fires before the database updates.
I want all the operations to be synchronous - one after another.

Thanks!

Kind Regards,
Ramesh H Singh
PARTS, HRIS.

Jim Marion said...

@Ramesh, let me answer the synchronous/asynchronous part. Let me know if you have other questions besides that one. jQuery's .load method is asynchronous. For sychronous (blocking) processing, use jQuery.ajax with the async parameter set to false.

Tarun Sharma said...

Hi Jim,

I am trying to integrate Outlook Calendar with PS ELM. Is there any option other than using iScript? Also please let me know what needs to be done if we intend to use iScript?

Thanks,
Tarun

Jim Marion said...

@Tarun, an iScript is the easiest method. You can find a quick example in my blog post PeopleSoft/Calendar Integration. Chapter 5 of my PeopleTools Tips and Techniques book has a more lengthy example. What makes these examples simple is they use an iScript to create an iCalendar file. I find this easier than dealing with proprietary back end protocols.

RAMESH said...

Jim - I need to identify %Menu or say anything %ROLENAME or permission list in ISCRIPT Function. IS that possible if not could you suggest any alternative.

Thanks!


Function IScript_GetAutosearch1()
Local string &input = %Request.GetParameter("input");
Local SQL &GetDistinctCategories;
Local SQL &GetEmployeeDetails;
Local number &counter = 0;
&GetDistinctCategories = CreateSQL("select distinct az_sprvsr_name , supervisor_id from ps_az_emp_dtl_vw where (upper(name) like '" | Upper(&input) | "%' OR az_uid like '" | Upper(&input) | "%') ");

%Response.Write("");
While &GetDistinctCategories.Fetch(&az_sprvsr_name, &supervisor_id)\...............................................


So the create sql needs to be changed based on the menu. Or can I change view that used in create sql in prebuild code?

Jim Marion said...

@Ramesh, you can definitely use system variables and security functions, such as IsUserInRole. You can't, however, use %Component, %Menu, etc, because these don't exist for iScripts. iScripts are not attached to menus or components.

smile said...

I need to store the images in data base and I should retrive the images through PeopleSoft online pages. If any one had done dat please let me know how to process?? I am new to peoplesoft and your help is much appreciated. Thanks in advance for your help.
Thanks

Jim Marion said...

@smile, there are a handful of ways to accomplish what you require. Some of them are standard and built into the tools. Others require a few tricks. I suggest you post this question on the PeopleSoft General Discussion forum.