making_forms.anubis
11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
*Project* The Anubis Project
*Title* Making Web Forms.
*Copyright* Copyright (c) Alain Prouté 2005.
*Author* Alain Prouté
read web/making_a_web_site.anubis
*Overview*
This file contains tools for helping making forms for a web site, using
'making_a_web_site.anubis'.
*** (1) General principles.
A form allows a client to send a lot of informations within a web page. These
informations are entered by the client in so-called 'input fields'. The server must:
- check the content of the form, and eventually return the form to the client (with
already entered values) for modifications with a warning message. This is 'phase 1'.
- when the form is OK, save the informations (maybe after some transformations) into
a data base, and send a confirmation page to the client. This is 'phase 2'.
Below is the flowchart of the behavior of the form:
:
phase 1 : phase 2
:
+-------------+ : +-------------------+
| form |<------+ : | confirmation page |
+-------------+ | : +-------------------+
submit| | : ^
| | : client side |
......................................:..........................................
| | : server side |
| | : |
| |no : |
| --------- : |
| / \ : |
| / is form \ yes: +-------------+ |
+------->| correctly |------------>| save or |----+
\ filled / : | update data |
\ in ? / : +-------------+
--------- : |
: |
: V
: +-----------+
: | data base |
: +-----------+
Actually, the confirmation page may be an infirmation page if some problem arose with
the data base.
This file contains tools for automating most of this process.
Recall that pages are actually computed from 'states' as explained in
'web/making_a_web_site.anubis', so that we are mainly concerned by states instead of
pages. The type of states is represented below by the parameter $State.
You must distinguish two kinds of data:
- intermediary data which are those needed in phase 1. These data are made of the
current values of the fields of the form. They are needed, because if the form is not
correctly filled in, the form must be sent back to the client with most fields already
filled in with previous values so that the client does not have to enter correct values
again. Intermediary data have an initial value. This initial value may be a general
default value if the form is for getting new informations from the client. It may also
be the case that the client just wants to update already existing data. In this case
the initial intermediary data are computed from the informations already stored into
the data base.
- definitive data, which may be constructed from intermediary data when the form has
been correctly filled in. These definitive data are saved into the data base in some
new record, or an existing record is updated.
So, we also have to distinguish between two sorts of forms:
- forms for getting new data,
- forms for updating existing data.
Actually, the above flowchart is not complete, because in the case of updating data,
the data may have changed between the moment the old data are sent to the client
(within the initial form) and the moment updating must take place. In this case, you
have to decide is you update the data or sent the form back to the client with an
appropriate message.
*** (2) Carrying on.
For each form, you have to define the following types:
- the type of messages (represented below by the parameter $Msg),
- the type of definitive data (represented below by the parameter $Row, as used by
'tools/sdbms.anubis')
The tools defined below perform all the stuff which is possible without knowing the
actual types represented by our parameters.
Now, the main tool 'make_form' (a schema of definition using the parameters), produces
a result of the following type:
public type MakeFormResult($State):
result($State -> HTML_Off_Form the_form, // to be used in the 'compute_page' function
Web_Action($State) the_action). // action of submitting the form
The form, as filled up by the client, may be either incorrect or correct. Hence, the
following type:
public type CheckFormResult($Msg):
incorrect ($Msg),
correct.
The form must be described. Actually, the form is made of the following components:
- a title,
- an text for explaining what the form is used for,
- all fields of the form, each field contains:
- a explanation,
- a tag for the input field,
- the input field itself,
- a submit button.
We have selected the following sorts of inputs for our forms. All the components are
functions which will be applied to the current state when the form is generated.
public type FieldCheck($Msg):
failure($Msg),
ok.
public type FormInput($State,$Msg):
text ($State -> String initial_value,
$State -> FieldCheck($Msg) check_field),
password,
check_box,
selector ($State -> List(String) items,
$State -> Maybe(String) selected),
upload.
public type FormField($State,$Msg):
field(String name, // symbolic name of field
$State -> String explanation,
$State -> String tag,
FormInput($State,$Msg) input).
public type FormDescription($State,$Msg):
form(String form_name,
$State -> String title,
$State -> String explain,
List(FormField($State,$Msg)) fields,
$State -> String submit_button_text).
Now, for making a form, you must provide the content of the form, a function for
checking the form and a function for saving or updating the informations.
Choose how to transmit the form:
public type FormTransmission:
http, // HTTP only
https, // HTTPS only
http_https. // both
public define MakeFormResult($State)
make_form
(
FormTransmission form_transmission,
FormDescription($State,$Msg) form_description,
$State -> $IData initial_values,
$State -> CheckFormResult($Msg) check_form,
$IData -> $State save_or_update
).
The above function is executed only once for each form when the server starts. The
result is used to feed up the arguments for the function 'make_web_site_description'
defined in 'web/making_a_web_site.anubis'.
--- That's all form the public part ! -------------------------------------------------
public define MakeFormResult($State)
make_form
(
FormDescription($Sate,$Msg) form_description,
$State -> $IData initial_idata,
($IData intermediate_data,
$State previous_state) ->
CheckFormResult($Msg,$IData) check_form,
($IData) -> $State save_or_update,
FormTransmission ftrans
) =
if form_description is form(form_name,title,explain,fields,button_text) then
with action_name = form_name+"_submit",
result(
($State s) |-> form(form_name,
table([nude],flat[
row(cell([h_center,columns(3)],text([size(16)],title(s)))),
row(cell([left,columns(3),width(400)],paragraph([justified,size(10)],explain(s)))),
map((FormField($State,$Msg) f) |-> if f is field(name,expl,tag,input) then
[
row(cell([h_center,columns(3)],paragraph([justified,size(10)],expl(s)))),
row[cell([right],text([size(10)],tag(s))),
cell([width(10)],text([],"")),
cell([left],if input is
{
text(init) then text_input (name,init,55)
password then password_input (name,55)
check_box(c) then check_box (name,c)
selector(i,s) then if s is
{
failure then selector(name,1,i(s))
success(k) then selector(name,1,i(s),k)
}
upload then file_upload (name,55)
})]
]
,fields),
row(cell([h_center,columns(3)],
actioner(if ftrans is
{
http then http,
https then https,
http_https then same
},
same,
link([size(14)],button_text(s)),
action_name,
[])))])),
(if ftrans is
{
http then http_action
https then https_action
http_https then http_https_action
})(action_name,
allow,
(List(Web_arg) lwa,
$State s) |-> if check_form(s) is
{
incorrect(msg,idata) then
correct then
}
)
).