PeopleSoft/SQR technical development PeopleSoft/SQR technical development PeopleSoft/SQR technical development
• Mail/phone
  Search
  Keyword:
  Tools
SQR Debugger
 
 
 
TECH TALK
Lightly technical observations on PeopleSoft and related topics
 

May 23, 2007

Component-Changed State

The component represents the fundamental unit of work in PeopleSoft. Pages are the most visible object to the user, but they are just views into a component. The component is where all the action is.

PeopleSoft keeps track of whether a component is "changed." This occurs when the user or any PeopleCode changes the value of one of the fields on one of the physical tables in the component. You may have seen cases in which your code in an event such as SavePostChange never runs, even though the user has clicked the Save button. This happens because the component's state was never set to "changed" and so the event never fires.

One way to force the Save events to fire is to fake a change by writing code to move a value into a field and then change it back. This kludge is no longer necessary, though, because there is a built-in function—SetComponentChanged()—that tells the component processor that some data has changed (even if it hasn't).

I'm currently in the process of developing some self-service pages and I've run into a little problem along these lines. A page contains a Submit button. Code in RowInit sets the initial values of many fields, so now the component is considered to have been changed. The user can make changes to the data on the page and click Submit, at which time workflow sends it off to the HR Department for approval. Now, if there weren't actually any user-entered changes, I don't want to send it off and I want to let the user know that nothing was changed. How to do this?

Unfortunately, there is no function that is the opposite of SetComponentChanged(). I came up with several solutions, none of which are all that good. One way would be to assemble the page using only derived record fields and then shuttle the data back and forth to the real tables. That's unappealing. DoSaveNow() could be used to save the component after the various initial values are set, but that is wasteful and raises other difficulties—for example, the code in the various Save events would need to know whether this is the user's save or the initial DoSaveNow(). Also, DoSave() and DoSaveNow() are restricted to the FieldChanged and SaveEdit events, whereas I want to do this in RowInit. A kludge would be possible, but... It would be nice to be able to start the Submit button out in a disabled state and then enable it after any field change. But that means turning off Deferred Processing for every field—another unappealing prospect. Another way would be to maintain a component-level boolean "dirty" flag. This would be set in the FieldChanged event for every field (after being initialized at the end of RowInit). That's a possibility, although there are a lot of fields involved.

I tried a real kludge and it works. In RowInit, I concatenate all of the starting values of the fields using a loop to go through all of the fields (using GetRecord().FieldCount) and save this in a component-level string. (That could be changed to a hash value using the Hash() function instead.) Then when the Submit button is clicked, the same concatenation is done again and the values are compared. It works, but it's one of those things where you sort of feel compelled to explain and apologize in a comment. I'll probably go back to setting a flag in all of the FieldChanged events...

Until next time...







 

  HOME  |  ABOUT US  |  PRODUCTS  |  SERVICES  |  TECH TALK  |  LINKS  |  SQR  |  CONTACT
© 2003-2010 SparkPath Technologies, Inc. & its licensors. All rights reserved. Trademarks used are property of their respective owners. | Terms of Use