Friday, May 30, 2014

Using Related Content and jQuery lightbox to turn any PeopleSoft Transaction into a Dashboard.

In my two previous posts I showed how to implement a Colorbox and use Pagelet Wizard in related content to load up to 25,000 rows of related data into an HTML table.  In the Pagelet Wizard posting it will load the first 100 rows and fetch the next 100 rows as the user scrolls the table.  But as I noted in that posting if you define a link in Pagelet Wizard it will overlay the Related Content Area frame and your related data table will be gone.  Since I did not think this was a great UX for the user, I really wanted a way to open this content into a jQuery lightbox, I choose Colorbox based on its flexiblity and its friendly license.

When I examined the HTML that was being generated by Peoplesoft I noticed it was loading the content into three seperate iFrames.


There is a TargetContent Frame, this is the largest area on the page and would be the best location to present the content from the related content.  Then there are two related content frames, the Related Content frame and a child frame called the related content area frame.  The question was how do I load the content from the child frame to the uncle frame?  I call the TargetContent frame an uncle, because it is on the same level as the Related Content frame.  In order to accomplish this I needed a lightbox that could be called from the jQuery Namespace from the child frame.  In my research I found two lightboxes that were suitable for this type of use.  First was the Fancybox2, it is a very good jQuery lightbox, but it also requires a license be purchased for Commercial development.  Now that is only $89 for multi-domains or $19 for one domain, but still it has a cost beyond learning how to use it.  The second option is the Colorbox, this is the option I went with since it is lightweight, flexible and licensed under the MIT License.  

Now if you have already followed the steps of my previous 2 postings, Pagelet Wizard for Related Content and Colorbox. Then all you need to do is modify the iScript in the Pagelet Wizard post to deliver the Colorbox to the transaction.

This is my modified iScript:



import PTPPB_PAGELET:*;
import PTPPB_PAGELET:DataSource:*;
import ZZ_JSON:JSONEncoder;

Local XmlDoc &xmlDoc;

Function IScript_RLC_CSS()
   %Response.SetContentType("text/css");
   %Response.Write(GetHTMLText(HTML.ZZ_RLC_SWAN_CSS));
End-Function;

Function json()
   Local array of XmlNode &rows = &xmlDoc.DocumentElement.FindNodes("/root/table/tbody/tr/td/table/tbody/tr");
   Local array of XmlNode &td;
   Local ZZ_JSON:JSONEncoder &utility = create ZZ_JSON:JSONEncoder();
   Local boolean &isFirstRow = True;
   
   %Response.Write("[");
   rem start on row two to avoid the table headers;
   For &x = 2 To &rows.Len
      If (&isFirstRow) Then
         &isFirstRow = False;
      Else
         %Response.Write(", ");
      End-If;
      %Response.Write("{""trClass"": """ | &utility.encode(&rows [&x].GetAttributeValue("class")) | """, ""valign"": """ | &utility.encode(&rows [&x].GetAttributeValue("valign")) | """,  ""td"": [");
      &td = &rows [&x].FindNodes("td");
      &isFirstData = True;
      For &y = 1 To &td.Len
         If (&isFirstData) Then
            &isFirstData = False;
         Else
            %Response.Write(", ");
         End-If;
         &Anchor = &td [&y].FindNode("A");
         If &Anchor.isnull Then
            %Response.Write("""" | &utility.encode(&td [&y].NodeValue) | """");
         Else
            %Response.Write("{""href"": """ | &utility.encode(&Anchor.GetAttributeValue("href")) | """, ""title"": """ | &utility.encode(&Anchor.GetAttributeValue("title")) | """,  ""value"": """ | &Anchor.nodevalue | """}");
         End-If;
      End-For;
      %Response.Write("]}");
   End-For;
   %Response.Write("]");
End-Function;




Function iScript_Request()
   Local array of string &bindArray = CreateArray(%Request.GetParameter("BIND1"), %Request.GetParameter("BIND2"), %Request.GetParameter("BIND3"), %Request.GetParameter("BIND4"), %Request.GetParameter("BIND5"), %Request.GetParameter("BIND6"), %Request.GetParameter("BIND7"), %Request.GetParameter("BIND8"), %Request.GetParameter("BIND9"), %Request.GetParameter("BIND10"));
   Local array &dsParms = CreateArray();
   
   Local string &START = %Request.GetParameter("START");
   Local string &AJAX = %Request.GetParameter("AJAX");
   Local string &PAGELETID = %Request.GetParameter("PAGELETID");
   Local number &chunk = 100;
   
   Local PTPPB_PAGELET:PageletWizard &PWAPI = create PTPPB_PAGELET:PageletWizard();
   
   Local PTPPB_PAGELET:Pagelet &thisPagelet = &PWAPI.getPageletByID(&PAGELETID, True);
   
   
   SQLExec("select PTPPB_VALUE from ps_PTPPB_PGLT_PRMS where PTPPB_PAGELET_ID = :1 and PTPPB_FIELDNAME = 'QueryName'", &PAGELETID, &QryName);
   
   &ajaxQS = "?AJAX=Y&PAGELETID=" | &PAGELETID;
   For &x = 1 To &bindArray.Len
      If All(&bindArray [&x]) Then
         Local string &thisBind = "BIND" | String(&x);
         
         SQLExec("SELECT FIELDNAME||'.'||BNDNUM FROM PSQRYBIND WHERE OPRID = ' ' AND QRYNAME = :1 AND BNDNAME=:2", &QryName, &thisBind, &qryBind);
         REM MAP BIND VARIABLES TO THE RLC QUERY DATASOURCE PARAMETERS;
         Local PTPPB_PAGELET:DataSource:DataSourceParameter &Temp = &thisPagelet.DataSource.addParameter(&qryBind, &bindArray [&x]);;
         &dsParms.Push(&Temp);
         &ajaxQS = &ajaxQS | "&" | &thisBind | "=" | &bindArray [&x];
      End-If;
   End-For;
   
   
   &loadURL = GenerateScriptContentURL(%Portal, Node.HRMS, Record.WEBLIB_ZZ_RLC, Field.ISCRIPT1, "FieldFormula", "iScript_Request") | &ajaxQS | "&START=";
   &cssURL = GenerateScriptContentURL(%Portal, Node.HRMS, Record.WEBLIB_ZZ_RLC, Field.ISCRIPT1, "FieldFormula", "IScript_RLC_CSS");
   &jQueryURL = GenerateScriptContentURL(%Portal, Node.HRMS, Record.WEBLIB_APT_JSL, Field.ISCRIPT1, "FieldFormula", "IScript_jQuery_1_7_1");
 rem  &FANCYBOX_CSS_URL = GenerateScriptContentURL(%Portal, Node.HRMS, Record.WEBLIB_ZZ_FBOX2, Field.ISCRIPT1, "FieldFormula", "IScript_FancyboxCss2");
 rem  &FANCYBOX_PACK_URL = GenerateScriptContentURL(%Portal, Node.HRMS, Record.WEBLIB_ZZ_FBOX2, Field.ISCRIPT1, "FieldFormula", "IScript_FANCYBOX_2_1_5_PACK");
   &COLORBOX_CSS_URL = GenerateScriptContentURL(%Portal, Node.HRMS, Record.WEBLIB_ZZ_CB, Field.ISCRIPT1, "FieldFormula", "IScript_colorbox_css");
   &COLORBOX_JS_URL = GenerateScriptContentURL(%Portal, Node.HRMS, Record.WEBLIB_ZZ_CB, Field.ISCRIPT1, "FieldFormula", "IScript_ColorBoxJs");
   
   
   If &AJAX <> "Y" Then
      &AJAX = "N";
      Local PTPPB_PAGELET:DataSource:DataSourceParameter &dsStart = &thisPagelet.DataSource.addParameter("START", "1");
   Else
      Local PTPPB_PAGELET:DataSource:DataSourceParameter &dsStartAJAX = &thisPagelet.DataSource.addParameter("START", &START);
      %Response.SetContentType("application/json");
   End-If;
   
   Local PTPPB_PAGELET:DataSource:DataSourceParameter &dsParmq = &thisPagelet.DataSource.addParameter("QueryName", &QryName);
   Local PTPPB_PAGELET:DataSource:DataSourceParameter &dsParmR = &thisPagelet.DataSource.addParameter(".MAXROWS", String(&chunk));
   Local PTPPB_PAGELET:DataSource:DataSourceParameter &dsParmR1 = &thisPagelet.DataSource.addParameter("AJAX", &AJAX);
   
   &string = &thisPagelet.Execute();
   
   
   REM &html = GetHTMLText(HTML.ZZ_RLC_REQUEST, &loadURL, &string, &chunk, &cssURL, &jQueryURL, &FANCYBOX_CSS_URL, &FANCYBOX_PACK_URL);
   &html = GetHTMLText(HTML.ZZ_RLC_REQUEST, &loadURL, &string, &chunk, &cssURL, &jQueryURL, &COLORBOX_CSS_URL, &COLORBOX_JS_URL);
   
   If &AJAX = "N" Then
      
      %Response.Write(&html);
      
   Else
      REM DO JSON PROCESSING;
      &xmlDoc = CreateXmlDoc("" | &string | "");
      
      json();
      
   End-If;
   
End-Function;


Then modify the HTML.ZZ_RLC_REQUEST JavaScript to load jQuery in the TargetContent Frame and then load the Colorbox.js if the user request the content.

<script type="text/javascript"  src="%BIND(:5)"></script>
<script type="text/javascript"  src="%BIND(:7)"></script>

<script type="text/javascript">

function setcolorbox() {
    $('a').click(function() {
       if (typeof tgtFrame.contentWindow.$.colorbox ==='undefined') {
        var thisHref = this.href;
        tgtFrame.contentWindow.$.getScript(colorbox,function() {
        var pscUrl = thisHref.replace("/psp/", "/psc/");
        tgtFrame.contentWindow.$.colorbox({href : pscUrl,  iframe: true,  height: '90%', width: '95%'})});
        return false;
       }
       else
       {
       var pscUrl = this.href.replace("/psp/", "/psc/");
       tgtFrame.contentWindow.$.colorbox({href : pscUrl,   iframe: true,  height: '90%', width: '95%'});
       return false; 
       } 
    });
};

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

 
var processing;
var chunk = %bind(:3);
var StartRow = chunk + 1;
var iScriptURL = "%bind(:1)";
var colorboxCss = "%bind(:6)";
var colorbox = "%bind(:7)";



var tgtFrame = window.top.document.getElementById('ptifrmtgtframe');
var tgtHead = tgtFrame.contentWindow.document.getElementsByTagName('Head');

var fbCss = document.createElement("link");
fbCss.rel = "stylesheet";
fbCss.href = colorboxCss;
fbCss.type = "text/css";
 
var scriptJQ = document.createElement('script');
scriptJQ.type='text/javascript';
scriptJQ.src = "%bind(:5)";


tgtHead[0].appendChild(scriptJQ);
tgtHead[0].appendChild(fbCss);

$(document).ready(function(){
 
    setcolorbox();    
      
    $(window).scroll(function(e){
         
        if (processing)
            return false;

        if ($(window).scrollTop() >= ($(document).height() - $(window).height())*0.7){
          processing = true;
           iScriptURL2 = iScriptURL+StartRow;
            
            $.get(iScriptURL2, function(loaded){
var htmlRows = '';
StartRow = StartRow + chunk;
for (var i=0;i<loaded.length;i++)
{ 
  //debugger;
  htmlRows = htmlRows + "<tr class='"  + loaded[i].trClass + "' valign='" + loaded[i].valign + "'>";
   for (var d=0;d<loaded[i].td.length;d++)
   {
     if ( typeof loaded[i].td[d].href != 'undefined')
        {       
          htmlRows = htmlRows + "<td><a href='" + loaded[i].td[d].href +  "'>" + loaded[i].td[d].value +"</a></td>";          
        }
     else
        {
          htmlRows = htmlRows + "<td>" + loaded[i].td[d] + "</td>";
        }
   }
}
$('.PSLEVEL1GRID tr:last').after(htmlRows);
 //rem setup new rows to open in colorbox;
 setcolorbox();

if (loaded.length>0){
processing = false;
};
});
        };
    });
});
</script>

 
%bind(:2)
The results are just stunning!



No comments:

Post a Comment