Skip to content

Validation

Forums Forums SIMPOL Programming Validation

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #312
    JD Kromkowski
    Participant

    At the risk of probably being the only one, stumped: I am having some trouble translating the concept of “validation” and “calculated fields” to simpol. I think my trouble is more mechanical than conceptual, because I have function to serve as “lookup”, it is just that I’m not sure the best place to put it. Using onlostfocus and ongotfocus tend to create a stupid endless loop if I use a dialog as part of the process of validation. (I have an awkward work around which involves testing for empty and then setting to ” ” prior to the validation dialog.) The same goes with calculated fields. It is really not clear to me where the functions should be put. It would make sense on one hand, to have them there before the save (as part of a “check for change”, the old IF MOD(“”) THEN …) But I can’t really see how I’d do that. But, on the other hand, you really also want this stuff to happen right in the beginning when you have a blank record and are adding to it for the first time (which is technically (I think) occurring before the “saving”).

    #1935
    Michael
    Keymaster

    On 11/05/2012 22:55, John D Kromkowski wrote:
    > At the risk of probably being the only one, stumped:
    >
    > I am having some trouble translating the concept of "validation" and "calculated fields" to simpol. I think my trouble is more
    > mechanical than conceptual, because I have function to serve as "lookup", it is just that I'm not sure the best place to put
    > it.
    >
    > Using onlostfocus and ongotfocus tend to create a stupid endless loop if I use a dialog as part of the process of validation.
    > (I have an awkward work around which involves testing for empty and then setting to " " prior to the validation dialog.)
    >
    > The same goes with calculated fields. It is really not clear to me where the functions should be put. It would make sense on
    > one hand, to have them there before the save (as part of a "check for change", the old IF MOD("") THEN …) But I can't really
    > see how I'd do that. But, on the other hand, you really also want this stuff to happen right in the beginning when you have a
    > blank record and are adding to it for the first time (which is technically (I think) occurring before the "saving").

    Hi John,

    The right place to add calculation and validation code is in the dataform1.onsave event handler. So you define a function to be
    called when the record is saved and assign it to the onsave event when you open the form (where you also add references to
    whatever else needs them). Prior to saving it will be called and if the routine returns .false, then it won't be saved (allowing
    you to fail the save if the validation fails, so you can put focus on the right control and let them try again).

    As for the constants at record creation, assign a function to the onnewrecord event of the dataform1 object and it will be called
    when the record is created so that you can assign values to the new record prior to it being shown in the form.

    Regarding inline calculations and validation, if you want to define those, put them in the onlostfocus event of the control, but
    don't just pop something up always, only pop up something if the validation fails. If they then select a proper response in the
    validation dialog, put focus on the next appropriate control. For calculations, don't forget that if you are assigning them to a
    field that is associated with an edit control, calling the settext() method of the control will also assign the value to the
    underlying field. If you are assigning to a field not shown, just make the assignment to the dataform1.masterrecord.record object.

    Ciao, Neil

    #1939
    JD Kromkowski
    Participant

    As I try to wrap my head around this. Am I correct that since I am
    going to have to make changes to either application.sma or
    appframework.sma, I can't really use the appframework.sml "as is" but
    rather I have to include all of the components of sma that make up
    appframework.sml in my application. (Or make changes and then recompile
    the appframework.sml)?

    If that is the case then, I really do need all of the sma s (timepicker,
    datepicker, etc.)

    #1942
    Michael
    Keymaster

    On 18/05/2012 16:29, John D Kromkowski wrote:
    > As I try to wrap my head around this. Am I correct that since I am going to have to make changes to either application.sma or
    > appframework.sma, I can't really use the appframework.sml "as is" but rather I have to include all of the components of sma
    > that make up appframework.sml in my application. (Or make changes and then recompile the appframework.sml)?
    >
    > If that is the case then, I really do need all of the sma s (timepicker, datepicker, etc.)
    >

    You shouldn't be making changes to either of them. You would do what is done in the Address Book project and embed the application
    object in your own type definition, like this:

    type myapplication (application)
    reference
    application app resolve

    end type

    function myapplication.new(myapplication me, …)
    me.app =@ application.new(…)

    end function me

    This allows you to define extensions to the application type without changing it. I am pretty sure this is discussed to some
    extent in the chapter that covers the Address Book example in the Quick Start Guide.

    The key function for constants, calculations and validations is completely independent of all of this though. Your onnewrecord
    handler is a function that takes a dataform1 object as its first parameter and probably something like the myapplication object
    above as its second parameter.

    The same is true for handling the onsave event but the function will be a different one.

    Ciao, Neil

    #1944
    JD Kromkowski
    Participant

    On 5/23/2012 7:42 AM, Neil Robinson wrote:
    > On 18/05/2012 16:29, John D Kromkowski wrote:
    >> As I try to wrap my head around this. Am I correct that since I am going to have to make changes to either application.sma or
    >> appframework.sma, I can't really use the appframework.sml "as is" but rather I have to include all of the components of sma
    >> that make up appframework.sml in my application. (Or make changes and then recompile the appframework.sml)?
    >>
    >> If that is the case then, I really do need all of the sma s (timepicker, datepicker, etc.)
    >>
    > You shouldn't be making changes to either of them. You would do what is done in the Address Book project and embed the application
    > object in your own type definition, like this:
    >
    > type myapplication (application)
    > reference
    > application app resolve
    > …
    > end type

    Yeah, I get that part, so this is what I have (works fine

    type payrollapplication (application)
    reference
    application __app resolve
    type(db1table) EMPLOYEE
    type(db1table) WAGES
    end type

    > function myapplication.new(myapplication me, …)
    > me.app =@ application.new(…)
    > …
    > end function me
    >
    > This allows you to define extensions to the application type without changing it. I am pretty sure this is discussed to some
    > extent in the chapter that covers the Address Book example in the Quick Start Guide.
    Yeah, I get this part, too. Again I have an tiny sample payroll
    application working pretty well.

    > The key function for constants, calculations and validations is completely independent of all of this though. Your onnewrecord
    > handler is a function that takes a dataform1 object as its first parameter and probably something like the myapplication object
    > above as its second parameter.

    I still don't understand, sorry I'm slow, where I'd handle constants,
    calculation and validations.

    The newrecord function is handled by "appframework.sml"

    Wouldn't I want to change that to account for constants, calculations
    and validations.

    The address book example doesn't use any validations, calculations,
    constants – so I really can't see how it is supposed to be done (except
    via my work around using ongotfocus() which is really not ideal.

    Same with "saverecord function" that is in the "appframework.sml".

    Right now I'm "handling" validations, etc. by a GotFocus function.

    >
    > The same is true for handling the onsave event but the function will be a different one.
    >
    > Ciao, Neil

    #1945
    JD Kromkowski
    Participant

    Following up on my last one

    Are you talking about handling validations, etc. in this function?

    function ab_onnewrecord(dataform1 me, appwindow appw)
    …..
    end function

    I have never been able to get that function to fire, but I'm thinking I
    know why:

    I am using 2 forms, when I load the 2nd form, I need to call the preform
    function, don't I?

    And I suppose I need to call the preform every time I switch forms,
    too? Is that where I missed what was going on?

    JDK

    #1946
    JD Kromkowski
    Participant

    So if I am understanding this correctly, here is what I've done:

    function preform(appwindow appw)
    dataform1 form
    form =@ appw.form
    if form.name == "Employee"
    form.onnewrecord.function =@ Emp_onnewrecord
    form.onnewrecord.reference =@ appw
    // I'd also do something like
    form.saverecord.function =@ Emp_saverecord
    form.saverecord.function =@ appw
    else if form.name == "Wages"
    form.onnewrecord.function =@ Wages_onnewrecord
    form.onnewrecord.reference =@ appw
    // same here
    end if
    end function

    And then instead of ab_onnewrecord function (by the way, to what does
    the "ab" refer?), I'd have

    function Emp_onnewrecord(dataform1 me, appwindow appw)
    integer e
    e = 0
    //do the validations, constants, and the calculations, including
    serial number if necessary
    end function

    function Emp_onsaverecord(dataform1 me, appwindow appw)
    integer e
    e = 0
    //check for correct validations, constants, and make calculations
    end function

    Is this the right idea? This though does put a lot work on the
    non-professional programmer, making this a little less RAD.

    #1947
    Michael
    Keymaster

    On 24/05/2012 15:44, John D Kromkowski wrote:
    > So if I am understanding this correctly, here is what I've done:
    >
    > function preform(appwindow appw)
    > dataform1 form
    > form =@ appw.form
    > if form.name == "Employee"
    > form.onnewrecord.function =@ Emp_onnewrecord
    > form.onnewrecord.reference =@ appw
    > // I'd also do something like
    > form.saverecord.function =@ Emp_saverecord
    > form.saverecord.function =@ appw
    > else if form.name == "Wages"
    > form.onnewrecord.function =@ Wages_onnewrecord
    > form.onnewrecord.reference =@ appw
    > // same here
    > end if
    > end function

    Not quite. You are replacing the form.saverecord function itself. You should be using the onsave event, like this:

    ….
    form.onsave.function =@ Emp_saverecord
    form.onsave.reference =@ appw
    ….

    > And then instead of ab_onnewrecord function (by the way, to what does the "ab" refer?), I'd have

    ab_ is for AddressBook_. I would use a different starting set of characters for other forms to help differentiate them if they use
    a different master table.

    > function Emp_onnewrecord(dataform1 me, appwindow appw)
    > integer e
    > e = 0
    > //do the validations, constants, and the calculations, including serial number if necessary
    > end function
    >
    > function Emp_onsaverecord(dataform1 me, appwindow appw)
    > integer e
    > e = 0
    > //check for correct validations, constants, and make calculations
    > end function

    Pretty much, but you need to return a .true or .false from the Emp_onsaverecord. The .false will prevent the save (if a validation
    failed and you want to place focus somewhere). If it returns .nul, I am pretty sure the test is against .true, so it will consider
    it to be .false and won't save.

    > Is this the right idea? This though does put a lot work on the non-professional programmer, making this a little less RAD.

    That is true. However as we move forward there will be more and more tools that help create a lot of this as source code for the
    end-user developer.

    Ciao, Neil

    #1948
    JD Kromkowski
    Participant

    On 5/28/2012 4:51 AM, Neil Robinson wrote:
    > On 24/05/2012 15:44, John D Kromkowski wrote:
    >> So if I am understanding this correctly, here is what I've done:
    >>
    >> function preform(appwindow appw)
    >> dataform1 form
    >> form =@ appw.form
    >> if form.name == "Employee"
    >> form.onnewrecord.function =@ Emp_onnewrecord
    >> form.onnewrecord.reference =@ appw
    >> // I'd also do something like
    >> form.saverecord.function =@ Emp_saverecord
    >> form.saverecord.function =@ appw
    >> else if form.name == "Wages"
    >> form.onnewrecord.function =@ Wages_onnewrecord
    >> form.onnewrecord.reference =@ appw
    >> // same here
    >> end if
    >> end function
    > Not quite. You are replacing the form.saverecord function itself. You should be using the onsave event, like this:
    >
    > …
    > form.onsave.function =@ Emp_saverecord
    > form.onsave.reference =@ appw
    > …

    OK. I see the error. onsave vs. saverecord
    >
    >> And then instead of ab_onnewrecord function (by the way, to what does the "ab" refer?), I'd have
    > ab_ is for AddressBook_. I would use a different starting set of characters for other forms to help differentiate them if they use
    > a different master table.

    So, that is basically what I did for the Employee form, I used Emp_yada
    and for the Wage Form I used Wages_yada

    >> function Emp_onnewrecord(dataform1 me, appwindow appw)
    >> integer e
    >> e = 0
    >> //do the validations, constants, and the calculations, including serial number if necessary
    >> end function
    >>
    >> function Emp_onsaverecord(dataform1 me, appwindow appw)
    >> integer e
    >> e = 0
    >> //check for correct validations, constants, and make calculations
    >> end function
    > Pretty much, but you need to return a .true or .false from the Emp_onsaverecord. The .false will prevent the save (if a validation failed and you want to place focus somewhere). If it returns .nul, I am pretty sure the test is against .true, so it will consider
    > it to be .false and won't save.
    This I don't understand – the mechanics not the theory. Forms have
    newrecord and saverecord METHODS, they have onchangerecord (is this like
    the old "mod"), ondelete, ondiscard, onkey, onkeylostfocus, onnewrecord,
    onsave, and onselect EVENTS. Doesn't the onsave event always throw
    saverecord method?

    I suppose it would be helpful for lesser mortals like me if the
    addressbook example had a validation and/or calculated field in it, so
    that I could see it more clearly at work.

    #1949
    Michael
    Keymaster

    On 01/06/2012 17:11, John D Kromkowski wrote:
    > This I don't understand – the mechanics not the theory. Forms have newrecord and saverecord METHODS, they have
    > onchangerecord (is this like the old "mod"), ondelete, ondiscard, onkey, onkeylostfocus, onnewrecord, onsave, and onselect
    > EVENTS. Doesn't the onsave event always throw saverecord method?

    Other way around. A call to the dataform1.saverecord() method will cause a call to the handler for the onsave event if it has been
    defined. If it has been defined and does not return .true, then the saving of the record will not be completed. The logic is this:
    the saverecord() call will always save the record (unless a real error occurs), but during that process, if you want to insert
    some logic for calculating field values or validating them, you can do so by defining and handling the onsave event.

    > I suppose it would be helpful for lesser mortals like me if the addressbook example had a validation and/or calculated field
    > in it, so that I could see it more clearly at work.

    I will think about enhancing the addressbook example in a future release.

    Ciao, Neil

Viewing 10 posts - 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.