Difference between revisions of "Dialog/Form Validation"
(Move from WEB) |
(source files) |
||
(9 intermediate revisions by 2 users not shown) | |||
Line 3: | Line 3: | ||
In this tutorial, we will show you how to validate controls in a dialog or in a form. First we will describe the validation concept. We will show how integerControl and realControl use the validation concept. Then we consider the validation in a container control. And finally we will add the validation for several usual controls: editControl, listBox and a newly created custom control. | In this tutorial, we will show you how to validate controls in a dialog or in a form. First we will describe the validation concept. We will show how integerControl and realControl use the validation concept. Then we consider the validation in a container control. And finally we will add the validation for several usual controls: editControl, listBox and a newly created custom control. | ||
Source files corresponding to this tutorial is available in the examples '''Help -> Install Examples...''' | |||
==Validation Concept== | ==Validation Concept== | ||
Line 19: | Line 19: | ||
==Validation in integerControl and realControl== | ==Validation in integerControl and realControl== | ||
Let us create a form and add two '''custom controls''' in it with the classes integerControl and realControl. You can see the result in the supplied example project in the form integerControlAndRealControl. | Let us create a form and add two '''custom controls''' in it with the classes integerControl and realControl. You can see the result in the supplied example project in the form <vp>integerControlAndRealControl</vp>. | ||
The generated code will look like: | The generated code will look like: | ||
Line 30: | Line 30: | ||
realControl_ctl:setSize(60,12),</vip> | realControl_ctl:setSize(60,12),</vip> | ||
Also we need to add invocation of integerControlAndRealControl | Also we need to add invocation of <vp>integerControlAndRealControl</vp> form: | ||
<vip>predicates | <vip>predicates | ||
Line 41: | Line 41: | ||
When we run the project and input non-integral values, we will see a dialog box with an explanation about the mistake. | When we run the project and input non-integral values, we will see a dialog box with an explanation about the mistake. | ||
We can add also | We can add also <vp>onOK</vp> responder to retrieve values of the validated controls: | ||
<vip>predicates | <vip>predicates | ||
Line 52: | Line 52: | ||
stdIO::write("Real value = ",Real, "\n").</vip> | stdIO::write("Real value = ",Real, "\n").</vip> | ||
It is important to notice | It is important to notice <vp>onOK</vp> responder is '''not''' invoked if the dialog validation is not successful. And of course, <vp>onOK</vp> responder is invoked '''after''' all validation predicates. | ||
Let us look in file \pfc\gui\controls\integerControl.pro to inspect how the validation is implemented. We can see: | Let us look in file '''\pfc\gui\controls\integerControl.pro''' to inspect how the validation is implemented. We can see: | ||
<vip>clauses | <vip>clauses | ||
Line 69: | Line 69: | ||
onIntValidate(_) = contentsOk.</vip> | onIntValidate(_) = contentsOk.</vip> | ||
I.e. if the local predicate checkContent considers the text as an integer, then the validation is successful. | I.e. if the local predicate checkContent considers the text as an <vp>integer</vp>, then the validation is successful. | ||
As it is mentioned above we can also force validation programmatically. We will add button TryValidation and code: | As it is mentioned above we can also force validation programmatically. We will add button TryValidation and code: | ||
Line 84: | Line 84: | ||
==Validation in Container Controls== | ==Validation in Container Controls== | ||
For considering the validation in a container control, we should create such control first. Let us create a new control | For considering the validation in a container control, we should create such control first. Let us create a new control <vp>fromTo</vp> in our project and add two controls integerControl in it. | ||
We will consider that | We will consider that <vp>fromTo</vp> control is valid if <vp>From</vp> value is less than <vp>To</vp> value, therefore we will add a validation responder to <vp>fromTo</vp> control: | ||
<vip>predicates | <vip>predicates | ||
validateFromTo : control::validateResponder. | validateFromTo : control::validateResponder. | ||
clauses | clauses | ||
validateFromTo (Source) = control::contentsInvalid(Source,from_ctl, | |||
"From value must be less than To value") :- | "From value must be less than To value") :- | ||
from_ctl:getInteger() >= to_ctl:getInteger(), | from_ctl:getInteger() >= to_ctl:getInteger(), | ||
!. | !. | ||
validateFromTo (_) = control::contentsOk.</vip> | |||
Please notice that control from_ctl | Please notice that control <vp>from_ctl</vp> will receive the focus if the validation is not successful. | ||
==Validation in Usual Controls== | ==Validation in Usual Controls== | ||
Let us create a new control myControl | Let us create a new control <vp>myControl</vp> in our project, and then create a form and add three controls in it: | ||
*edit control; | *edit control; | ||
Line 107: | Line 107: | ||
*listbox control; | *listbox control; | ||
*custom control of myControl | *custom control of <vp>myControl</vp> class. | ||
You can see the result in the supplied example project in the form ''usualControls''. | You can see the result in the supplied example project in the form ''usualControls''. | ||
Line 157: | Line 157: | ||
That is, you can see that it is possible to validate a control in really different ways. | That is, you can see that it is possible to validate a control in really different ways. | ||
[[Category:GUI]] | |||
[[Category: |
Latest revision as of 10:55, 4 March 2016
When a user presses OK in a dialog, it means that something should happen. But this can only happen if the data in the dialog are valid. The dialog/form must be validated. This tutorial describes the validation mechanism supported by PFC GUI. It also shows how to use the validating controls integerControl and realControl, and how to validate other controls in a dialog/form.
In this tutorial, we will show you how to validate controls in a dialog or in a form. First we will describe the validation concept. We will show how integerControl and realControl use the validation concept. Then we consider the validation in a container control. And finally we will add the validation for several usual controls: editControl, listBox and a newly created custom control.
Source files corresponding to this tutorial is available in the examples Help -> Install Examples...
Validation Concept
The validation concept is based on the idea: "control values should be valid". The validation check happens on pressing OK button in a dialog or a form, but the validation check can be forced programmatically also.
It is the responsibility of a control to state that its contents is valid, therefore a validation responder can be set to a control.
When a dialog or a form makes the validation check, the controls are tested sequentially, but if one of the tests results in
contentsInvalid(Source, FocusControl, ErrorMessage)
then the validation check is terminated.
Validation in integerControl and realControl
Let us create a form and add two custom controls in it with the classes integerControl and realControl. You can see the result in the supplied example project in the form integerControlAndRealControl.
The generated code will look like:
integerControl_ctl := integercontrol::new(This), integerControl_ctl:setPosition(92, 4), integerControl_ctl:setSize(60,12), realControl_ctl := realcontrol::new(This), realControl_ctl:setPosition(92, 20), realControl_ctl:setSize(60,12),
Also we need to add invocation of integerControlAndRealControl form:
predicates onFileIntegercontrolRealcontrol : window::menuItemListener. clauses onFileIntegercontrolRealcontrol(Source, _MenuTag) :- Form = integerControlAndRealControl::new(Source), Form:show().
When we run the project and input non-integral values, we will see a dialog box with an explanation about the mistake.
We can add also onOK responder to retrieve values of the validated controls:
predicates onOk : button::clickResponder. clauses onOk(_) = button::defaultAction() :- Integer = integerControl_ctl:getInteger(), Real = realControl_ctl:getReal(), stdIO::write("Integer value = ",Integer, "\n"), stdIO::write("Real value = ",Real, "\n").
It is important to notice onOK responder is not invoked if the dialog validation is not successful. And of course, onOK responder is invoked after all validation predicates.
Let us look in file \pfc\gui\controls\integerControl.pro to inspect how the validation is implemented. We can see:
clauses new() :- editControl::new(), addValidateResponder(onIntValidate). predicates onIntValidate : validateResponder. clauses onIntValidate(_) = contentsInvalid(This,This, ErrorMessage) :- string(ErrorMessage) = checkContent(getText()), !. onIntValidate(_) = contentsOk.
I.e. if the local predicate checkContent considers the text as an integer, then the validation is successful.
As it is mentioned above we can also force validation programmatically. We will add button TryValidation and code:
predicates onTryValidation : button::clickResponder. clauses onTryValidation(_Source) = button::defaultAction() :- tryValidateWithErrorDialog(), !, stdIO::write("All controls are valid\n"). onTryValidation(_Source) = button::defaultAction().
Validation in Container Controls
For considering the validation in a container control, we should create such control first. Let us create a new control fromTo in our project and add two controls integerControl in it.
We will consider that fromTo control is valid if From value is less than To value, therefore we will add a validation responder to fromTo control:
predicates validateFromTo : control::validateResponder. clauses validateFromTo (Source) = control::contentsInvalid(Source,from_ctl, "From value must be less than To value") :- from_ctl:getInteger() >= to_ctl:getInteger(), !. validateFromTo (_) = control::contentsOk.
Please notice that control from_ctl will receive the focus if the validation is not successful.
Validation in Usual Controls
Let us create a new control myControl in our project, and then create a form and add three controls in it:
- edit control;
- listbox control;
- custom control of myControl class.
You can see the result in the supplied example project in the form usualControls.
Initialization code will contain the setting of responders and initialization for these three controls:
clauses new(Parent) :- formWindow::new(Parent), generatedInitialize(), edit_ctl:addValidateResponder(validateEditCtl), listbox_ctl:addList(["First","Second","Third"]), listbox_ctl:addValidateResponder(validateListBox).
And validation responders will look like:
predicates validateEditCtl : control::validateResponder. clauses validateEditCtl(_) = control::contentsOk :- "OK" = edit_ctl:getText(), !. validateEditCtl(Source) = control::contentsInvalid( Source, Source, "Edit control expects to have the text 'OK'"). predicates validateListBox : control::validateResponder. clauses validateListBox(Source) = control::contentsInvalid( Source,Source, "Selection of the first row is not allowed") :- 0 = listbox_ctl:tryGetSelectedIndex(), !. validateListBox(_) = control::contentsOk(). predicates validateMyControl : control::validateResponder. clauses validateMyControl(Source) = control::contentsInvalid( Source,Source, string::concat("A marker in the ",Missed, " part is mandatory")) :- Missed = toString(isMandatoryMarkNotActive( mandatoryMark, activatedMark)), !. validateMyControl(_) = control::contentsOk().
That is, you can see that it is possible to validate a control in really different ways.