Tuesday, November 2, 2010

Using jQuery in PeopleSoft: Validating, Formatting and Totaling

In my last entry, I introduced using JavaScript and, specifically, the jQuery library to enhance your PeopleSoft pages. Now we'll take a look at how to apply this to browser-side data validation, formatting and totaling. This is the application that inspired me to look into using JavaScript with PeopleSoft in the first place.

Experienced PeopleSoft developers (and why would you be reading this if you're not one?) know that in order to force data validation and page update as soon as a user leaves a field, we must deactivate "deferred processing" so that the page will be submitted when the data changes. On pages with many fields, it can be very disruptive to efficient data entry to submit the page on each change. This also increases the load on the server. On the other hand, real-time data validation and page updates provide the user valuable feedback.

The solution is to do basic data validation, formatting and totaling on the browser-side with JavaScript.
One caveat, never rely solely on browser-side data validation. You cannot control what happens on the user's computer. It is not that hard to hack a web page and subvert the validation. Always do server-side validation also to insure that data you receive is safe and valid.
jQuery makes it easy to detect changes and take action on them. The basic code looks like this.

$(document).ready(function(){
  $('#MY_INPUT').change(function () {
    //do something here
  });
});

The .change() method causes the enclosed function to be called whenever the selected object value is changed and the object loses "focus." An object losses focus when the user "tabs out" or otherwise selects another object on the page. A similar method, .blur(), can also be used. The blur event occurs when the object losses focus, whether or not the value has changed.

Let's say we have a simple time entry page where the user will record her time for the week. Each day has an hours text input element, HOURS1, HOURS2 ... HOURS7. We can watch all seven inputs with one line of code and do some validation and totaling.

$(document).ready(function(){
 $('input:text[id^=HOURS]').change(function () {
  try{
   var hours = parseNumber($(this).val());
   if (hours < 0 || hours > 24){
    alert('Daily hours must be between 0 and 24.');
   }else{
    $(this).val(formatNumber(hours));
   }   
  }catch(er){
   alert ($(this).val() + ' is "' + er.toString() + '"');
  }
 });
 
 // parse text to number.
 function parseNumber(n) {
  var out;
  if (n == ''){
   out = 0;
  } else{
   var out = parseFloat(n);
  }
  if (isNaN(out)) {
   throw 'Not a number';
  }
  return out;
 }

 // format number to text with 2 decimal point. If 0 return ''
 function formatNumber(n) {
  var out;
  if (n == 0) {
   out = '';
  } else {
   out = n.toFixed(2);
  }
  return out;
 }
});


Each time one of the HOURS inputs is changed, this code is called. First we parse the value of the input ($(this).val()) to a number. If it's not a number, the user gets an alert. Same if the value is not between 0 and 24. Finally, the number is formatted with 2 decimal places and we update the input element value.

All this takes place on the browser without submitting the page to the server. Let's take one more step and provide a total. I'll add a totalHours method:

function totalHours() {
  var total = 0;
  $('input:text[id^=HOURS]').each(function () {
   total += parseNumber($(this).val());
  });
  $('#TOTAL_HOURS').val(total.toFixed(2));
 }

and call it from my original code:
...
   }else{
    $(this).val(formatNumber(hours));
    totalHours();
   }   
...

Note how easily I can loop through each of the HOURS inputs and total them up using the each() method.

Now, a couple PeopleSoft-specific tips.

By default, PeopleTools gives each input an id attribute equal to the concatenated record and field names. This can be awkward and sometimes not very descriptive. You can override this behavior by setting the "Page Field Name" in the "General" tab of the Edit Box Page Field properties. The value you set here will be used as the id and name of the element in the html. Just be sure the value you set is unique for the page.

The Edit Box "Display-Only Appearance" should be set to "Disabled Edit Control" in the "Use" tab of Edit Box Page Field properties. This causes the Edit Box to become an "addressable" text <input> element rather than <span> element with no id. This does cause some formatting issues depending on the browser. I'll describe my solution to this in a later post.

So now you can validate, format and total data on the browser side without having to submit your page to the server.

In my next post, I'll show you how to intercept the delivered PeopleSoft submit process so you can do validations and verifications on submit.