Validating when using controller.newRecord();

Hi All

I am starting to use error handling and would like in a first attempt to just validate if there was valid data entry for 2 fields: the 1st is a primary key (number), the 2nd field is text and mandatory.

What is the easiest way to accomplish that in version 3.5? I am quite uncertain what is currently a good way as I think error handling has improved much lately.

I am also irritated as there is an on error method hook in the solution settings, but where to set it locally (forms/table) when inserting a new record (for example). Is it the onREcordEditStop event?

Thanks for any help pointing me to some info.

Best regards, Robert

You don’t set any error “handlers” locally. The global method you attach to the solution’s onError property will catch all errors, no matter where they come from. Check out the sample code from the servoyException node to get started…

Hi Patrick

Thanks for the hint. Are you saying I can’t have a local error handler per table for example?
I have to make all the separation of various errors in one and the same global error handler, i. e. for the whole solution? I am irritated, I must say.
Is there no local (encapsulated) way to handle errors?

Best regards, Robert

patrick:
You don’t set any error “handlers” locally. The global method you attach to the solution’s onError property will catch all errors, no matter where they come from. Check out the sample code from the servoyException node to get started…

Robert,

How about looking at the calling exception in the global handler and then consulting a table (of exceptions and actions to take)? With eval(local_method_name_as_string) if needed to perform a callback.

Haven’t tried this (in Servoy but have used this technique elsewhere). Exceptions can be then documented (TEXT field) and can be managed (including recording of error conditions, user and node id etc).

I agree with you though. Encapsulation of errors (especially things like say a field level validation call … things like field_is_mandatory), in my opinion, needs to be pushed back from a global level to a form level (at least as a programming option). I personally don’t like managing things like field level exceptions at a global level. I think this should be done elegantly via a data provider column setting: the forms themselves ought to trap for things like mandatory attributes and provide feedstock to a local exception handler for recovery.

In the same breath, I do like a global handler as well (but not for form-field stuff) … I know these things are often subject to “architectural debates” … :)

Just wondering out loud … not sure if this applies to your situation.

Michael

Have you looked at the table level events on data providers added in 3.5?

You can attach a method to the “onInsert” event for the table which will validate your values. If the method returns false, the insert will not be done.

The advantage of this over form level validation is that it will occur on any form the table is used on.

greg.

Hi Michael

I agree with your thoughts. I really think field level validation IS local, i. e. bound to a table/form as the field(s), i. e. attributes and constraints of them are defined in the data model for exact the corresponding entity, i. e. table.

I don’t mind about a global error handler, it may have it’s purpose but I don’t like to be forced to make something global which is per definitionem local. If only the global option is there, you have to make a big case statement just to filter out your searched local thing.

I played with the newly added table level events as mentioned by Greg but it seems I need to “play” more to understand it ,-) May be that’s a solution to field level validation.

Thanks and best regards, Robert

Michael Mooney:
Robert,

How about looking at the calling exception in the global handler and then consulting a table (of exceptions and actions to take)? With eval(local_method_name_as_string) if needed to perform a callback.

Haven’t tried this (in Servoy but have used this technique elsewhere). Exceptions can be then documented (TEXT field) and can be managed (including recording of error conditions, user and node id etc).

I agree with you though. Encapsulation of errors (especially things like say a field level validation call … things like field_is_mandatory), in my opinion, needs to be pushed back from a global level to a form level (at least as a programming option). I personally don’t like managing things like field level exceptions at a global level. I think this should be done elegantly via a data provider column setting: the forms themselves ought to trap for things like mandatory attributes and provide feedstock to a local exception handler for recovery.

In the same breath, I do like a global handler as well (but not for form-field stuff) … I know these things are often subject to “architectural debates” … :)

Just wondering out loud … not sure if this applies to your situation.

Michael

Thanks for the tip, Greg. I have to “play” more with these options to find out what they are best used for. Do you know what the original intention was to introduce them?

Thanks, Robert

agiletortoise:
Have you looked at the table level events on data providers added in 3.5?

You can attach a method to the “onInsert” event for the table which will validate your values. If the method returns false, the insert will not be done.

The advantage of this over form level validation is that it will occur on any form the table is used on.

greg.

Field level validation has been in Servoy since the beginning (onDataChange, onRecordEditStart/Stop).

We only extended the options you have as a developer to catch errors globally (onError Method under Solution Settings) and on table level (onInsert,onUpdate & onDelete).

The underlying reason of table events is to be able to set your business logic on table level, instead of having to duplicate it per form.

The onError method has been introduced to allow consistent error handling all throughout the solution.

Paul

Paul, thanks for explanation. I will try these possibilities :-)

Best regards, Robert

pbakker:
Field level validation has been in Servoy since the beginning (onDataChange, onRecordEditStart/Stop).

We only extended the options you have as a developer to catch errors globally (onError Method under Solution Settings) and on table level (onInsert,onUpdate & onDelete).

The underlying reason of table events is to be able to set your business logic on table level, instead of having to duplicate it per form.

The onError method has been introduced to allow consistent error handling all throughout the solution.

Paul

Hi Paul,

Do you happen to know offhand if very common validation things (like data for a field being set to Mandatory) will become a property (e.g. - of a form field object or a data provider column) in future releases?

I certainly understand this can be managed via a local method and that these methods have been around for some time now.

At this point I am just “kinda wondering” where this might be headed so I can plan my development.

Michael

Hi All

Has someone to share a little example on onInsert error handling? Would be very welcome :-)

Thanks and regards, Robert

agiletortoise:
Have you looked at the table level events on data providers added in 3.5?

You can attach a method to the “onInsert” event for the table which will validate your values. If the method returns false, the insert will not be done.

The advantage of this over form level validation is that it will occur on any form the table is used on.

greg.

Hello Paul et al.

I hooked the sample error script to the solution on error event (as described in the sample script).

sample error script:
//this sample script should be attached to onError method handler in the solution settings
var e = arguments[0];
application.output("Exception Object: " + e)
application.output("MSG: " + e.getMessage())
if (e.isServoyException)
{
application.output(“is a ServoyException”)
application.output("Errorcode: " + e.getErrorCode())
if (e.getErrorCode() == ServoyException.SAVE_FAILED)
{
plugins.dialogs.showErrorDialog( “Error”, “It seems you did not fill in a required field”, ‘OK’);

//Get the failed records after a save
var array = databaseManager.getFailedRecords()
for( var i = 0 ; i < array.length ; i++ )
{
var record = array*;*

  • application.output(record.exception);*
  • if (record.exception.isDataException)*
  • {*
  • application.output("SQL: " + record.exception.getSQL())*
  • application.output("SQLState: " + record.exception.getSQLState())*
  • application.output("VendorErrorCode: " + record.exception.getVendorErrorCode())*
  • }*
  • }*
    }
    }[/quote]
    Now what I find very strange and in this form useless:
    If I produce an error, e. g. not entering a mandatory defined (in the db) field, I get an error (as expected), but when clicking the OK button and click to some other record (form is in table list view), so an auto save is done, then the not valid row is still visible!!
    If I switch in Developer to design mode and back to display mode, the row is gone (as it should be). Hmmm :-(
    Best regards, Robert
    PS: This method seems to work only when attached to the solution error handler. I attached it to the table event error handler onInsert but I get errors saying the functions used within the script are unknown.
    > pbakker:
    > Field level validation has been in Servoy since the beginning (onDataChange, onRecordEditStart/Stop).
    >
    > We only extended the options you have as a developer to catch errors globally (onError Method under Solution Settings) and on table level (onInsert,onUpdate & onDelete).
    >
    > The underlying reason of table events is to be able to set your business logic on table level, instead of having to duplicate it per form.
    >
    > The onError method has been introduced to allow consistent error handling all throughout the solution.
    >
    > Paul

The onRecord* event methods get passed a single argument, which is the record being handled. In this example, I use onRecordInsert to set default values for a field – only if the user has not choosen a value. This is a common problem I’ve run into where I don’t want to auto-enter the info, but I do want a default value if the user has not set one.

var rec = arguments[0]; // this holds the recorded being processed

if( rec.note_type == null )
   rec.note_type = 'default';
return true;

You could also return false, and the insert would not occur, so that would be how you would force the user to enter the value.

greg.

Hi Greg

The table events are (at the moment) a mystery for me:

Code:
application.output(“onRecordInsertsubjects”);
application.output("Code = " + forms.ScoSubjectsL.code);
application.output("Fach = " + forms.ScoSubjectsL.name);

if (forms.ScoSubjectsL.code == null)
{
plugins.dialogs.showErrorDialog( “Error”, “Please enter a code”, ‘OK’);
}
else
{
plugins.dialogs.showErrorDialog( “Error”, “Hmmm?”, ‘OK’);
}

I am using the autosave mode.
forms.ScoSubjectsL.code and forms.ScoSubjectsL.name are mandatory columns.
What happens is that if the user clicks on any record, subject code and name contain the values of the clicked record. So I am asking myself how can I check for filled columns on the record to be inserted?

Also the question remains when exactly is onRecordInsert fired? I assume it’s fired post inserted?

It would be extremly helpful if anyone could shed some light to this mechanism.

Best regards, Robert

agiletortoise:
Have you looked at the table level events on data providers added in 3.5?

You can attach a method to the “onInsert” event for the table which will validate your values. If the method returns false, the insert will not be done.

The advantage of this over form level validation is that it will occur on any form the table is used on.

greg.

Think of the table events as database triggers, if you are familiar with those.

THey are fired when the action is done towards the database, so after a saveData(), but prior to the actual action towards the database, because you have the ability to return false and cancel the action.

So, to give you an example of an onInsert method:

var _rec = arguments[0]
if (!_rec.column1Name)
{
}
return true;

This basically checks if the inserted record has a value assigned to the column with name column1Name. If not, false is returned and the action is canceled, otherwise the record is actually inserted into the database.

Paul

Thanks Paul, just posted the previous post.

The desired solution is one likes to give the user the chance to complete the data entering (make it a valid record) if (s)he misses to enter a mandatory column. How to do that?

Best regards, Robert

pbakker:
Think of the table events as database triggers, if you are familiar with those.

THey are fired when the action is done towards the database, so after a saveData(), but prior to the actual action towards the database, because you have the ability to return false and cancel the action.

So, to give you an example of an onInsert method:

var _rec = arguments[0]

if (!_rec.column1Name)
{
}
return true;




This basically checks if the inserted record has a value assigned to the column with name column1Name. If not, false is returned and the action is canceled, otherwise the record is actually inserted into the database.

Paul

I see I missed a piece of code in my example, returning false if a column is not filled properly.

This is the correct code:

var _rec = arguments[0] 
if (!_rec.column1Name) 
{ 
return false;
} 
return true;

If you return false, the record will not be inserted, so the user can continue.

Paul

I would like to test for null values in required fields without using the
on-error method for the solution.
(Autosave is off)

If you use the the code from Paul with a required text field it works fine.

If you do this with a required number field you get an exception from Servoy and the code is not executed at all.

If there is a required text field in a form you can empty it and go to the next field and there is no exception thrown, if you do the same with a number field an exception is thrown.

Any way to get around this ?

I have logged a case for this.