Agile Tortoise

Greg Pierce’s blog

« Magnetic ribbons      Happy Birthday, Sweetie! »

Servoy: turning global form events into callbacks

Using global methods for form events provides a simple way to build consistent interfaces across your solution while maintaining DRY principals. Servoy's latest 3.5 release includes form event templates, which makes it even easier to apply a set of global events to new forms. There's always cases, however, where you have behaviors that are specific to particular forms and can't be abstracted to globals. This is a perfect opportunity to use callbacks.

So my solution to making a maintainable set of generic global form events is based on turning the events into a set of callbacks on forms that follow a basic naming convention, and if they callbacks are defined, they are called -- if not, the default event behavior is used. For those who just want to cut to the chase, I've included a demo solution for download -- just import into Servoy 3.5:

demo_form_events download

First, you'll need methods to determine if a form exists, and if a method by a particular name is defined on that form. Here are mine:

JavaScript:
  1. // form_exists - returns boolean
  2. eval('forms.'+arguments[0]);
  3. return forms[arguments[0]] ? true : false;

JavaScript:
  1. // form_has_method - returns boolean base on form/method name passed
  2. var frmName = arguments[0];
  3. var methodName = arguments[1];
  4.  
  5. if( !globals.form_exists(frmName) )
  6.    return false;
  7. return utils.stringLeft( typeof(forms[frmName][methodName]), 7 ) == 'functio' ? true : false;

Now you can utilize those methods to check if the callbacks you want to use are defined on a form, and call them in your global form events. Here's an example global form event method for the "onNewRecord" event:

JavaScript:
  1. // form_event_newRecord
  2. // get calling form name...
  3. var frm_name = application.getMethodTriggerFormName();
  4.  
  5. // use new security methods to check if the user can create a record
  6. if( !security.canInsert(currentcontroller.getServerName(), currentcontroller.getTableName() ) )
  7. {
  8.    plugins.dialogs.showErrorDialog( "Error""Permission error""OK" );
  9.    return;
  10. }
  11. // if a 'canInsert' method is defined, call it -- it should return a boolean
  12. if( globals.form_has_method( frm_name, 'canInsert' ) )
  13. {
  14.    if( !forms[frm_name].canInsert() )
  15.       return;
  16. }
  17. // this is optional, depending on your requirements
  18. databaseManager.saveData();
  19.  
  20. // if 'form_event_newRecord' is defined on the form, use it to create the record
  21. // otherwise, use the controller.newRecord default
  22. if( globals.form_has_method( frm_name, 'form_event_newRecord' ) )
  23.    forms[frm_name].form_event_newRecord();
  24. else
  25.    forms[frm_name].controller.newRecord(false,true);
  26. // if 'form_event_initRecord' is defined, call it.  use this callback to set values on the record
  27. if( globals.form_has_method( frm_name, 'form_event_initRecord' ) )
  28.    forms[frm_name].form_event_initRecord();
  29. return;

The demo solution also has examples for 'onDeleteRecord' and 'onRecordSelection' -- the later I use to implement record-level security through callbacks. I have a full set of the methods for all standard events which I utilize in my solutions. Then, I just don't really think about events -- just that I have a callback chain. The callback chain in the above 'onNewRecord' example is: 'canInsert' (return false to prevent creation), 'form_event_newRecord' (override the default controller.newRecord behavior), 'form_event_initRecord' (set default values on the new record).

I'm interested to hear if people are doing similar things, or think this is a valueable technique.

Monday, August 6th, 2007 at 9:38 pm and is filed under Servoy. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

One Response to “Servoy: turning global form events into callbacks”

  1. kazar Says:
    November 10th, 2007 at 12:08 pm

    This is cool. I hope you participate in the Servoy Best Practices wiki begun by Robert Ivens of ROCLASI … to which I have contributed a little bit of writing thus far in a weak attempt to help, but I have little technical expertise to contribute, sadly. See wiki.servoyforge.net — I would be very interested in reading discussion there between the “do not use method-naming conventions to ‘objectivize’ methods” camp, and those who happily go ahead and do just that … and to watch what collaboratively defined best practices result.

Leave a Reply