Thursday, July 2, 2015

Invoke PeopleCode Event from Javascript (in a HTMLAREA)

Let us walk through an example on how to invoke a peoplecode event from a javascript in a HTMLAREA.

Here is a test page which contains a push button that display a winmessage on FieldChange.


Let us see what happens behind the scenes when we click on the push button by inspecting the HTML.


We can see that the onclick event on the push button invokes the javascript function (delivered) submitAction_win0(document.win0, this.id, event). In this case, this.id would be equal to CSK_TEST_WRK_TEST. The general format for the id field would be <RECORD_NAME>_<FIELD_NAME>. This would translate to <RECORD_NAME> = CSK_TEST_WRK and <FIELD_NAME> = TEST.

Now let us include a HTMLAREA on the page.


Include the following HTML and javascript in the HTMLAREA properties. Note: I am using a constant HTML value for the purposes of this example.


HTML Code:

<script>
function myFunction() {
   submitAction_win0(document.win0,"CSK_TEST_WRK_TEST", event);
}
</script>

<a href="#" onclick="myFunction()">Push Button in HTMLAREA</a>

Updated HTML Code - 20151105 - Thanks to @Santiago.gmerino's comment below:

<script>
function myFunction() {
   // submitAction_win0(document.win0,"CSK_TEST_WRK_TEST", event);
   // Use %formname to resolve _win# dynamically.
   submitAction_%formname(document.%formname,"CSK_TEST_WRK_TEST",event);
}
</script>

<a href="#" onclick="myFunction()">Push Button in HTMLAREA</a>

Now let us test the javascript in the HTMLAREA.


We can see the hyperlink that we added in the HTMLAREA appear on the page. Let us click the hyperlink 'Push Button in HTMLAREA'. This should trigger the FieldChange event on the push button CSK_TEST_WRK.TEST.


Note: At the time of writing this post, I am using HCM 9.2 PUM Image 12 - PeopleTools 8.54.08.

34 comments:

  1. Sasank, win0 works only on an initial session. If you were navigating in Psoft with a browser session opened with the 'new window' link. your session's objects will have win1 or win2, etc. The url in peoplesoft will also show you the session appended to the db instance as _1, _2, etc. The script is still referencing win0 which does not exists, the actions wont work.

    ReplyDelete
    Replies
    1. @[Sara -kiki- Llewellyn] Thanks for pointing that out! I certainly took a short cut with that function call.

      I will try to write some dynamic javascript to make the code independent of the window counter. I will update this post when I get a chance!

      Thanks again for point that out! :)

      Delete
  2. No need to create a function to replace win0 but only use the variable %Formname ;)

    ReplyDelete
    Replies
    1. @Santiago.gmerino - Thank you! You saved me some time because I never got a chance to get back to this post.

      %formname meta-html is a great way to resolve the _win# subsitution dynamically!

      Delete
    2. Also, updated the post with the latest javascript so that it helps the other bloggers/readers!

      Delete
  3. Thanks Sasank. I was looking for something like this to implement will try this out.
    One question I had. How does App server know that "CSK_TEST_WRK" is the Record and TEST" is the field. Wouldnt it mistake it for "CSK_TEST" to be the record and "WRK_TEST" as field?

    ReplyDelete
    Replies
    1. Hi Jithin - Good question.

      I think id attribute that is generated by PeopleTools (either by default:record+field or the one we assign at the page field level) will be unique (in the context of the component buffer).

      In the context of the actual HTML, the uniqueness of the id is important (concat of record+field name) and it really does not matter what is the record/field portion. I guess the component processor should then be able to simply co-relate the id attribute with the page field.

      Also, if you try to use the same page field name in two different fields on the same page, then you will get this error in App Designer:
      https://snag.gy/hQklEv.jpg

      Hope that makes sense.

      Delete
    2. That definitely makes sense. Thanks for your quick response.

      Delete
  4. Hi Sasank,
    I've somewhat similar requirement.
    I want to call a FieldChange event on click on header of collapsible groupbox.

    How can I achieve it?


    ReplyDelete
    Replies
    1. If this is a Fluid page, then you could use the JavaScriptEvents property on the group box field. Then do whatever you need to do in the JavaScript code.

      Here is a sample of what you can do in Fluid and JavaScript:
      https://pe0ples0ft.blogspot.com/2016/07/fluid-ui-custom-development-invoke.html

      Delete
  5. Hi Sasank,
    Is that possible to send any additional parameters in submitactionform(buttonid,event,?) other than button id and event.

    Rashmi

    ReplyDelete
    Replies
    1. Hi Rashmi - Good question. If I do a 'Find In...' searching all HTML objects for 'submitAction_', I see a few variants of the use of this function, so there may very well be other parameters that you could pass. But I am not sure if there is documentation. Could not find the actual function definition either, so really not sure.

      That said, what are you trying to pass? If you want to pass back data to the PeopleCode event, it is best to pass it as part of the component buffer that way you will be able to access it via PeopleCode.

      In some cases, I have placed a hidden, 'modifiable by javascript' field on the page and use that to pass back data. That is, before calling the submitAction_%formname, I would use some javascript to place my data in the hidden field.

      Hope this gives you some ideas! Let us know what you are trying to achieve and we may be able to provide more options.

      Delete
  6. This works great for me in IE, but it doesn't work in Firefox or Safari. Any suggestions?

    ReplyDelete
    Replies
    1. I realized this problem recently as well (on Firefox). I was able to workaround this by omitting the event parameter as follows:
      submitAction_%formname(document.%formname,"CSK_TEST_WRK_TEST");

      Let us know if that resolves your issue.

      Delete
  7. Hi Sasank !
    It is a nice post. I tried it and works for me.
    However, if I call DoSave() function in FieldChange event, then I get the following error, although the data is saved successfully.





    Home



    Global Search












    Search



































































    NavBar









    Close









    "This page is no longer available.
    To continue, return to your most recent active page or select one of the navigation icons in the header above."

    Any thoughts on this?

    ReplyDelete
    Replies
    1. I have not seen this error before. I found these documents on My Oracle Support:
      E-WL: Intermittent Issues after Configuring Coherence*Web in PeopleSoft Environment: Users may receive "Page is no longer available" Messages and/or Users are Sometimes Kicked Back to Search Page (Doc ID 1585569.1)

      EGL: General Ledger Online Journal Edit Times Out With Error "Failed To Publish Initial Request Status" (Doc ID 2163214.1)

      The second document seems to suggest there may be some conflict with the Push Notifications?

      Delete
  8. We are trying to implement text counter in PeopleSoft Edit Box we are on V9.1; the below code works perfect in IE but not working in Chrome

    function CharCounter()
    {
    if (document.win0.EP_APPR_SECTION_EP_RESULTS2.value.length > 3000)
    document.win0.EP_APPR_SECTION_EP_RESULTS2.value = document.win0.EP_APPR_SECTION_EP_RESULTS2.value.substring(0, 3000);
    else
    document.win0.EP_BTN_LINK_WRK_COUNTER2.value = 3000 - document.win0.EP_APPR_SECTION_EP_RESULTS2.value.length;
    }
    function AddEvent(obj, evType, fn, useCapture){
    if (obj.AddEventListener){
    obj.AddEventListener(evType, fn, useCapture);
    return true;
    } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
    } else {
    }
    }
    AddEvent(document.win0.EP_APPR_SECTION_EP_RESULTS2, "keydown", CharCounter, false);


    In Chrome the AddEventListener is not working;any suggestion how we can alter the code so that it works for both IE and Chrome

    Mahesh

    ReplyDelete
    Replies
    1. Hi Mahesh,

      Sorry for the late response. I think you have a typo with the AddEventListener method call. It should start with a lower case 'a' as addEventListener. Otherwise, your script seems to work in all browsers.

      I tried this jsfiddle based on your script:
      https://jsfiddle.net/SasankVemana/jt4rehwh/

      Let me know how it goes.
      Thanks,
      Sasank

      Delete
  9. Thanks a lot;)
    I am really thankful to you it helped me it resolved by issue; thanks a lot you made my day.

    Mahesh

    ReplyDelete
  10. hello Sasank,

    Once I am in page, instead of clicking the Push Button in HTML Area, when i come to the page it has to populate the Hello World with out clicking.

    Can you let me know how it can be achievable.

    ReplyDelete
    Replies
    1. Hi Ajay - If you are looking at triggering code in a fieldchange event, why not just replicate the code in the Page Activate event?

      Just trying to understand the requirement better.

      Delete
    2. There is a delivered page, When the User opens the page, instead of clicking the View All button (to view all rows), the User want it to populate all the rows with out clicking the View All button. There is setting in App designer for scroll "Unlimited Occurs Count" but we are getting performance issue (it is working fine for less than 100 rows, if it more than 100 rows it just spins and timesout). So we decided to populate first 100 rows when the user opens the page.For scroll we cannot give 100 rows in the page field properties. So i am trying your code. Inserted HTML object on the page and below is the code. (this is working when i click the Push Button, but i dont want to click it manually, it should click automatically when the User opens the page).


      For some reason i am not able to place the code, the code is same as your 4th screenshot instead of submitAction_win0(document.win0,"CSK_TEST_WRK_TEST", event); i updated to submitAction_win0(document.win0,"$ICField1$hviewall$0").click();

      This is an urgent requirement, if you can send me the updated code, it will be very helpful.

      Thanks in advance.

      Delete
    3. Couple of suggestions:

      - If you want to fire the function right away, try the following line write before the end of the script tag.
      window.onload = myFunction;
      Screenshot
      - Also, replace win0 with %formname (see updated code in the post). Otherwise you will run into issues with this code executing in new windows.

      Hope this helps.

      Delete
    4. Also, avoid the event parameter. I don't think it is required and know to cause issues with FireFox.

      Delete
    5. Hello Sasank,

      script
      function myFunction() {
      submitAction_%formname(document.%formname,"$ICField1$hviewall$0").click();
      }
      window.onload = myFunction;
      /script


      removed <> for script

      I updated the code but the function is not firing right away..

      Delete
    6. Not sure what the problem is in your case. The suggestions that I gave works for me (in the example provided in this blog).
      Video: https://media.giphy.com/media/3og0IP61Om7YrnjgfC/giphy.gif

      You might have to debug your script (write messages to the browser console) and see if you are getting any errors (look in the browser console).

      Delete
    7. Hello Sasank,

      Can you copy and paste your code here please...

      Delete
    8. You can find the script here. It is just one line of code added for you requirement (rest is the same as in this blog):
      https://jsfiddle.net/SasankVemana/j9pa04b1/3/

      Delete
    9. The code is working if you dont have a search record, or if you just have one row in a record. Can you add the search record and let me know if it is working...

      Delete
    10. ajay - JavaScript will only fire one per component load. So if you have multiple rows and you are navigating back and forth to the search page you may have to write additional code to account for those events.

      This is post is just a proof of concept on how to invoke PeopleCode from JavaScript.

      Delete
  11. HI Sasank ..can you send me the code please. I tried but it did not work ...

    ReplyDelete
    Replies
    1. Hi Ajay - I don't have code for that scenario. If I find anything that might help. I will post back on this thread. Thanks!

      Delete
  12. Hi Sasank,
    Thanks for this nice article.
    Can this approach be used for uploading files attached to a form into PeopleSoft using javascript? Is there a way to get the file attachment content and save it to a PS table?

    Thanks

    ReplyDelete
    Replies
    1. I have not tried but it should be possible. You may need to use javascript and potentially javascript events via peoplecode and figure out a way to initiate the attachment upload. Once the request reaches the server side (peoplecode), you would be able to use code that is similar to delivered attachment functionality to load it into a PS table.

      Delete