Add to git.
[monolith.git] / examples / 06_big_form.c
1 /* Big, complicated form.
2  * - by Richard W.M. Jones <rich@annexia.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  * $Id: 06_big_form.c,v 1.4 2002/11/02 18:53:46 rich Exp $
19  */
20
21 #include <string.h>
22
23 #include <pool.h>
24 #include <pstring.h>
25 #include <pthr_cgi.h>
26
27 #include "monolith.h"
28 #include "ml_window.h"
29 #include "ml_text_label.h"
30 #include "ml_button.h"
31 #include "ml_table_layout.h"
32 #include "ml_flow_layout.h"
33 #include "ml_form.h"
34 #include "ml_form_submit.h"
35 #include "ml_form_text.h"
36 #include "ml_form_textarea.h"
37 #include "ml_form_password.h"
38 #include "ml_form_select.h"
39 #include "ml_form_radio_group.h"
40 #include "ml_form_radio.h"
41 #include "ml_form_checkbox.h"
42 #include "ml_form_textarea.h"
43
44 /*----- The following standard boilerplate code must appear -----*/
45
46 /* Main entry point to the app. */
47 static void app_main (ml_session);
48
49 int
50 handle_request (rws_request rq)
51 {
52   return ml_entry_point (rq, app_main);
53 }
54
55 /*----- End of standard boilerplate code -----*/
56
57 /* Private per-session data. */
58 struct data
59 {
60   ml_window win;
61
62   /* The form input fields themselves. */
63   ml_form_text familyname, givenname;
64   ml_form_password password;
65   ml_form_select dd, mm, yyyy;  /* Date of birth. */
66   ml_form_radio_group gender;
67   ml_form_radio m, f;           /* Gender. */
68   ml_form_checkbox eating, drinking, sleeping; /* Interests */
69   /*ml_form_file photo;            File upload, not yet implemented. */
70   ml_form_select dept;
71   ml_form_textarea comments;
72 };
73
74 static void create_form (ml_session session, void *vp);
75 static void submit_form (ml_session session, void *vp);
76
77 static void
78 app_main (ml_session session)
79 {
80   pool pool = ml_session_pool (session);
81   struct data *data;
82
83   /* Create the private, per-session data area and save it in the
84    * session object.
85    */
86   data = pmalloc (pool, sizeof *data);
87
88   /* Create the top-level window. */
89   data->win = new_ml_window (session, pool);
90
91   create_form (session, data);
92 }
93
94 static void
95 create_form (ml_session session, void *vp)
96 {
97   pool pool = ml_session_pool (session);
98   struct data *data = (struct data *) vp;
99   ml_form form;
100   ml_table_layout tbl;
101   ml_text_label text;
102   ml_form_submit submit;
103   ml_flow_layout flow;
104   int i;
105
106   /* Create the form. */
107   form = new_ml_form (pool);
108   ml_form_set_callback (form, submit_form, session, data);
109
110   /* Create the table. */
111   tbl = new_ml_table_layout (pool, 10, 2);
112
113   /* Create the contents of the form. */
114   text = new_ml_text_label (pool, "Family name / surname");
115   ml_table_layout_pack (tbl, text, 0, 0);
116   data->familyname = new_ml_form_text (pool, form);
117   ml_table_layout_pack (tbl, data->familyname, 0, 1);
118
119   text = new_ml_text_label (pool, "Given name(s) / forename(s)");
120   ml_table_layout_pack (tbl, text, 1, 0);
121   data->givenname = new_ml_form_text (pool, form);
122   ml_table_layout_pack (tbl, data->givenname, 1, 1);
123
124   text = new_ml_text_label (pool, "Password");
125   ml_table_layout_pack (tbl, text, 2, 0);
126   data->password = new_ml_form_password (pool, form);
127   ml_table_layout_pack (tbl, data->password, 2, 1);
128
129   text = new_ml_text_label (pool, "Date of birth");
130   ml_table_layout_pack (tbl, text, 3, 0);
131   flow = new_ml_flow_layout (pool);
132   data->dd = new_ml_form_select (pool, form);
133   for (i = 1; i <= 31; ++i)
134     ml_form_select_push_back (data->dd, psprintf (pool, "%02d", i));
135   data->mm = new_ml_form_select (pool, form);
136   ml_form_select_push_back (data->mm, "Jan");
137   ml_form_select_push_back (data->mm, "Feb");
138   ml_form_select_push_back (data->mm, "Mar");
139   ml_form_select_push_back (data->mm, "Apr");
140   ml_form_select_push_back (data->mm, "May");
141   ml_form_select_push_back (data->mm, "Jun");
142   ml_form_select_push_back (data->mm, "Jul");
143   ml_form_select_push_back (data->mm, "Aug");
144   ml_form_select_push_back (data->mm, "Sep");
145   ml_form_select_push_back (data->mm, "Oct");
146   ml_form_select_push_back (data->mm, "Nov");
147   ml_form_select_push_back (data->mm, "Dec");
148   data->yyyy = new_ml_form_select (pool, form);
149   for (i = 1900; i <= 2002; ++i)
150     ml_form_select_push_back (data->yyyy, psprintf (pool, "%04d", i));
151
152   ml_flow_layout_pack (flow, data->dd);
153   ml_flow_layout_pack (flow, data->mm);
154   ml_flow_layout_pack (flow, data->yyyy);
155
156   ml_table_layout_pack (tbl, flow, 3, 1);
157
158   text = new_ml_text_label (pool, "Gender");
159   ml_table_layout_pack (tbl, text, 4, 0);
160   data->gender = new_ml_form_radio_group (pool, form);
161
162   flow = new_ml_flow_layout (pool);
163   data->m = new_ml_form_radio (pool, data->gender, "m");
164   ml_form_radio_set_checked (data->m, 1);
165   ml_flow_layout_pack (flow, data->m);
166   text = new_ml_text_label (pool, "Male");
167   ml_flow_layout_pack (flow, text);
168   data->f = new_ml_form_radio (pool, data->gender, "f");
169   ml_flow_layout_pack (flow, data->f);
170   text = new_ml_text_label (pool, "Female");
171   ml_flow_layout_pack (flow, text);
172
173   ml_form_radio_group_pack (data->gender, flow);
174   ml_table_layout_pack (tbl, data->gender, 4, 1);
175
176   text = new_ml_text_label (pool, "Interests");
177   ml_table_layout_pack (tbl, text, 5, 0);
178
179   flow = new_ml_flow_layout (pool);
180   data->eating = new_ml_form_checkbox (pool, form);
181   ml_flow_layout_pack (flow, data->eating);
182   text = new_ml_text_label (pool, "Eating");
183   ml_flow_layout_pack (flow, text);
184   data->drinking = new_ml_form_checkbox (pool, form);
185   ml_flow_layout_pack (flow, data->drinking);
186   text = new_ml_text_label (pool, "Drinking");
187   ml_flow_layout_pack (flow, text);
188   data->sleeping = new_ml_form_checkbox (pool, form);
189   ml_flow_layout_pack (flow, data->sleeping);
190   text = new_ml_text_label (pool, "Sleeping");
191   ml_flow_layout_pack (flow, text);
192
193   ml_table_layout_pack (tbl, flow, 5, 1);
194
195   text = new_ml_text_label (pool, "Department");
196   ml_table_layout_pack (tbl, text, 6, 0);
197   data->dept = new_ml_form_select (pool, form);
198   ml_widget_set_property (data->dept, "form.select.size", 4);
199   ml_widget_set_property (data->dept, "form.select.multiple", 1);
200   ml_form_select_push_back (data->dept, "Accounting");
201   ml_form_select_push_back (data->dept, "Development");
202   ml_form_select_push_back (data->dept, "Marketing");
203   ml_form_select_push_back (data->dept, "Personnel");
204   ml_form_select_push_back (data->dept, "Support");
205   ml_form_select_push_back (data->dept, "Systems");
206   ml_table_layout_pack (tbl, data->dept, 6, 1);
207
208   text = new_ml_text_label (pool, "Comments");
209   ml_table_layout_pack (tbl, text, 7, 0);
210   data->comments = new_ml_form_textarea (pool, form, 5, 50);
211   ml_table_layout_pack (tbl, data->comments, 7, 1);
212
213   text = new_ml_text_label (pool, "Photo");
214   ml_table_layout_pack (tbl, text, 8, 0);
215   text = new_ml_text_label (pool, "[not implemented]");
216   ml_table_layout_pack (tbl, text, 8, 1);
217
218   /* Submit button. */
219   submit = new_ml_form_submit (pool, form, "Submit");
220   ml_table_layout_pack (tbl, submit, 9, 1);
221
222   /* Pack it all up. */
223   ml_form_pack (form, tbl);
224   ml_window_pack (data->win, form);
225 }
226
227 static void
228 submit_form (ml_session session, void *vp)
229 {
230   pool pool = ml_session_pool (session);
231   struct data *data = (struct data *) vp;
232   ml_text_label text;
233   ml_table_layout tbl;
234   ml_button button;
235   const char *str;
236
237   str = psprintf
238     (pool,
239      "Form submitted.\n"
240      "\n"
241      "Family name: %s\n"
242      "Given name: %s\n"
243      "Password: %s\n"
244      "Date of birth: dd = %d, mm = %d, yyyy = %d\n"
245      "Gender: %s\n"
246      "   M is checked: %d  F is checked: %d\n"
247      "Interests: Eating = %d, Drinking = %d, Sleeping = %d\n"
248      "Dept fields checked: [ %s ]\n"
249      "Comments:\n"
250      "--start--\n"
251      "%s\n"
252      "--end--\n",
253      ml_form_input_get_value (data->familyname),
254      ml_form_input_get_value (data->givenname),
255      ml_form_input_get_value (data->password),
256      1 + ml_form_select_get_selection (data->dd),
257      1 + ml_form_select_get_selection (data->mm),
258      1900 + ml_form_select_get_selection (data->yyyy),
259      ml_form_input_get_value (data->gender),
260      ml_form_radio_get_checked (data->m),
261      ml_form_radio_get_checked (data->f),
262      ml_form_input_get_value (data->eating) ? 1 : 0,
263      ml_form_input_get_value (data->drinking) ? 1 : 0,
264      ml_form_input_get_value (data->sleeping) ? 1 : 0,
265      pjoin (pool,
266             pvitostr (pool, ml_form_select_get_selections (data->dept)), ", "),
267      ml_form_input_get_value (data->comments));
268
269   tbl = new_ml_table_layout (pool, 2, 1);
270   text = new_ml_text_label (pool, str);
271   ml_table_layout_pack (tbl, text, 0, 0);
272   button = new_ml_button (pool, "Back to form");
273   ml_button_set_callback (button, create_form, session, data);
274   ml_table_layout_pack (tbl, button, 1, 0);
275
276   ml_window_pack (data->win, tbl);
277 }