Page 1 of 1

Complex form validation

Posted: Wed Jan 04, 2012 3:00 pm
by StephenTaylor
My application manages sets of parameters, called 'bases'. A basis comprises hundreds of parameters. There are many dependencies between them. Certain parameter values make others irrelevant, or constrain their values.

The behaviour of the GUI should reflect as much of this as possible. For example, where the value for one parameter makes others moot, those others should be disabled.

The obvious place to code this behaviour is in the GUI code, triggered by callbacks.

However, I also want to refer to these dependencies when comparing bases. Where the value of parameter X has made values of Y and Z moot, the comparison must ignore Y and Z.

While these parameter sets may be unusually complex, it is perhaps not the first time someone has looked to avoid replicating the dependencies in the GUI code and elsewhere in an app.

Have you any experience with representing such dependencies?

SJT

Re: Complex form validation

Posted: Fri Jan 06, 2012 1:04 pm
by crishog
I did something similar some years back. Probably not an entirely "GUI" styled solutions, as it was based on a DOS APL system, which used an assembler package to imitate GUI functionality.

It was to enter currency trading deals, each form had between one and 4 sub-forms (probably the best way to describe them, in the Windows version I used tabs) and dozens (not hundreds as in your case) of fields which switched on and off according to the type of deal, the customer, the currencies involved, trading position, the type of trader entering the deal. Entering some values not only enabled or disabled subsequent fields (well, subsequent in DOS as e largely ignored the mouse), but restricted the possible values in sub-ordinate fields.

When generating a GUI form the parameters set for each field could "register an interest" in certain keys (arbitrary strings really), so, for example a currency field could signal that it had been set & this could switch off a set of fields if it was one of a particular set and also restrict the input values of other currency fields - not much point selling US Dollars and trying to use US Dollar to buy them with.

That is probably as clear as mud, because I've skimmed over at a very high level. Perhaps you want to have a chat at the next BAA London meeting? Phil, Jake & I all worked on this project, although I did all of the deal entry systems for both the DOS and Windows versions.

Re: Complex form validation

Posted: Fri Jan 06, 2012 4:47 pm
by StephenTaylor
Chris, we seem to be having the right sort of conversation and I look forward to pursuing it at the next BAA London meeting, possibly with my colleague from Australia.

What we are chiefly interested in here is a structure for representing the constraints, that can be used to generate both the GUI code-behind and that can be read by other processes, eg a validator and a diff tool for comparing parameter sets.

Re: Complex form validation

Posted: Mon Jan 09, 2012 9:22 pm
by PhilGray
Not sure what you're after , but FWIW :

I use one central function for handling my GUIs : "#.capture".

It stores all GUI fields "that I require" into a central table ( called #.Capture ) such as to make searching, sorting, reading GUIs , writing GUIs & validating during callbacks extremely simple.

It maintains a second ( less important ) global called : #.CaptureOR
... which stores the complete GUI Quad-OR object if I reuqire it later.

The function "#.capture" uses the first element of the RH-Arg to point to a multitude of sub-functionality within the function.

I'd have thought this was the obvious way to handle GUIs, and might , from what I've understood, suggest a basis for solving your problem.


Here's an example of what #.Capture might look like :

      ...

ArbitraryTag Field-name Attribute Value Default
--------------------------------------------------------------------------
∆PDF F1.SF1.AHELL Caption
∆PDF F1.SF1.AHELL State
∆LANGUAGE F1.SF1.TC.B1 Caption
∆LANGUAGE F1.SF1.TC.B2 Caption
∆LANGUAGE F1.SF1.TC.B3 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B4 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B4 Tip
∆LANGUAGE F1.SF1.TC.F1.TC.B1 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B1 Tip
∆LANGUAGE F1.SF1.TC.F1.TC.B2 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B2 Tip
∆LANGUAGE F1.SF1.TC.F1.TC.B3 Caption
∆LANGUAGE F1.SF1.TC.F1.TC.B3 Tip
∆DATA F1.SF1.TC.F1.TC.F4.ED1 Text
∆DATA F1.SF1.TC.F1.TC.F1.ED1 Text
∆DATA F1.SF1.TC.F1.TC.F2.ED1 Text


Here's an example of using the function in the GUI-Create stage :

      (∆∆3 #.capture FORM,'.ED2')⎕WC'Edit' ''('Posn'...



Basically , the #.capture function is easily expanded to handle all new functionalities that one needs.
Typically, a result is always returned, and the simple case of writing / reading ...

GUI --> #.Capture
#.Capture --> GUI

.. for single fields, whole groups of fields, or over the all GUIs that are currently "open" is a simple operation.

The "ArbitraryTag" is just a way of grouping items for convenience.
e.g. Using the "∆LANGUAGE" Tag enables me to change the User-Language in real-time with one function call, and changes all GUIs that are currently "open".

Here's a sample of some Callback code :

      :Else
:If ∧/' '=OBJ ⎕WG'Caption' ⍝ then add default
Choice←,''makeInputBOX 1 '' 'Name'
:If 0≠⍴Choice
OBJ ⎕WS'Caption'Choice

DATA←capture 0 '∆DATA'
DATA←duplicate∆DATA∆files DATA ⍝ duplicate files

∆∆PAGEDEFS[CNR]←⊂Choice
DATA DB∆PAGEDEF CNR ⍝ update
:EndIf
:Else ⍝ activate default
DATA←DB∆PAGEDEF CNR
X←capture 1 DATA



Here's a few lines of the "in function" documentation for #.capture :

( view full screen width , to see all whole lines )

      ...

⍝⍝ : READ-from WRITE-to RETURN
⍝⍝ -------------- -------------- ------------------------
⍝⍝ monadic, eg: R←capture 0 'INIBASE' '∆NEW1' '∆NEW2' ... : GUI Capture → field-names,ATTs,values from GUI
⍝⍝ monadic, eg: R←capture 0 : Capture-DATA defaults → Capture

⍝⍝ monadic, eg: R←capture 1 (1 SYSREAD 1) : DATA by name GUI + Capture → field-names,ATTs,values from GUI
⍝⍝ R←capture 1 'INIBASE' : Capture by Name GUI → field-names,ATTs,values from GUI
⍝⍝ R←capture ¯1 'INIBASE' '∆DATA' ... : Capture defaults GUI → ⍳0


Bottom line :
By having all the GUI fields needed in one central table, one would just add a few more "code subsections" to the #.capture function to include various cross-field validations that one requires, as the application develops ( that would be used within the Callbacks).

Re: Complex form validation

Posted: Wed Jan 11, 2012 11:25 am
by StephenTaylor
Phil

Thanks for your generous and extensive reply. Your #.capture function looks very useful. I’m not clear it answers my question, which I had perhaps better clarify.

Consider relationships such as these:

1. If X has value 3, controls A and B are irrelevant
2. If X has value 2, B’s value must be in the range 10 11 12.

If I’m following you, such relationships would be encoded in #.capture. When X has value 3, #.capture disables controls A and B. When X has value 2, #.capture sets the options for B.

I’m looking for a structure (grammar?) within to record such relationships. It would replace a 3,000-line validation function in our app, that replicates equivalent rules in the GUI code-behind. Instead, our GUI would refer to this structure to (eg) disable controls and set combo options. The validator would refer to it to produce a validation report. Display and diff programs would refer to it to suppress irrelevant detail.

Did I miss something in what you wrote?

Best
Stephen

Re: Complex form validation

Posted: Fri Jan 13, 2012 3:51 pm
by paulmansour
Hi Stephen!

This is an interesting problem.

I don't have an answer, but a couple of questions and observations.

First, when the value of parameter A in a basis makes, say, the values of param B and C irrelevant, can the values of B and C be set to a special value like []NULL? Or do you need to keep the irrelevant values because at some point the value of a may be set back to something that makes the values of B and C relevant, and you want to have their previous values still there?

I'm thinking the logic could all be in the getters and setters of a class. I have cases where a class has a bunch of properties, and setting some of them makes others relevant or irrelevant. The setters and getters. If property A being assigned 5 means that property B and C are moot, then the property A setter can reset them as well. Actually, better yet, the property A setter wouldn't do it, but the property B and C getters could. Ah, that makes my first question pointless. You can actually keep the values of B and C in case A makes them active again.

So, if you had everything in a class, testing for equality would be easy, as the actual values of the underlying fields are passed though the getters which contain the logic - you just compare all the property values.

From this is it possible to set up the GUI? I think it should be. You can tell what controls are active by looking at the value of the corresponding property. If it is null or void or whatever special value you use, the control should be inactive. Any change to a control refreshes the whole thing, so other controls go active or inactive accordingly.

For the cases where you have a parameter the range of which depends on the value of another parameter you could use read-only properties. For example if A<-1 means that B may be 'London', 'New York' or "Oslo", then the property AllowedValuesForB could return that list, which could be used as the Items property of a combo box....

I've rambled too long. You have probably already thought of this and rejected it for good reasons.

Re: Complex form validation

Posted: Wed Jan 18, 2012 5:46 am
by neeraj
This would be easy to setup in causeway. Change in value of one control would holler to everything else that depends upon it. This raises an important point - There doesn't seem to be an easy way to create these kind of relationships easily if you choose to use WPF.

Re: Complex form validation

Posted: Wed Jan 18, 2012 6:29 am
by MikeHughes
There are several ways of doing this with WPF - the best method is to use DataValidation with DataBinding. I can't go into detail yet but it is the project I am currently working on. I have got as far as getting the principle to work now with the knowledge I have gained I am trying to convert this into an APL friendlier version. I'm hoping some of my work will act as a model for some additions to Dyalog in 2012 but these meetings are due later this Spring. For more info see Morten.

All I can say at the moment is "Watch this space"

Re: Complex form validation

Posted: Wed Jan 18, 2012 12:23 pm
by Peter Merritt
Interesting news about WPF. But I'd be happier if some of the more intelligent end of the controls were in APL, to avoid being deafened by the 'echoes'... For example, if you just set ;shout' events, you'll need something to stop the loop:-
Item-A shouts 'XXX'
which is picked-up by Item-B,
which shouts 'YYY' 'ZZZ',
which is picked-up by Item-C,
which shouts '123',
which is picked-up by Item-A.......

It is impolite to break into conversations (even between collections of objects) - but not if the house is on fire. And you've been introduced, naturally!

I think you need an object comms 'post office' which can sort-out an original call from an echo.

Re: Complex form validation

Posted: Thu Jan 19, 2012 1:28 pm
by MikeHughes
I believe there is a Sender and OrignalSender property in most event args so you know where the event started and who was the last to pass it on.