1CGI::Application::PlugiUns:e:rFoCromnSttraitbeu(t3e)d PeCrGlI:D:oAcpupmleinctaattiioonn::Plugin::FormState(3)
2
3
4

NAME

6       CGI::Application::Plugin::FormState - Store Form State without Hidden
7       Fields
8

VERSION

10       Version 0.12
11

SYNOPSIS

13       FormState is just a temporary stash that you can use for storing and
14       retrieving private parameters in your multi-page form.
15
16           use CGI::Application::Plugin::FormState;
17
18           my $form = <<EOF;
19              <form action="app.cgi">
20              <input type="hidden" name="run_mode" value="form_process_runmode">
21              <input type="hidden" name="cap_form_state" value="<tmpl_var cap_form_state>">
22              ...
23              </form>
24           EOF
25
26           sub form_display_runmode {
27               my $self = shift;
28
29               # Store some parameters
30               $self->form_state->param('name'       => 'Road Runner');
31               $self->form_state->param('occupation' => 'Having Fun');
32
33               my $t = $self->load_tmpl(scalarref => \$form);
34               return $t->output;
35
36           }
37
38           sub form_process_runmode {
39               my $self = shift;
40
41               # Retrieve some parameters
42               print $self->form_state->param('name');       # 'Road Runner'
43               print $self->form_state->param('occupation'); # 'Having Fun'
44           }
45

EXAMPLE

47       This is a more complete example, using
48       CGI::Application::Plugin::ValidateRM.
49
50           use CGI::Application::Plugin::Session;
51           use CGI::Application::Plugin::FormState;
52           use CGI::Application::Plugin::ValidateRM;
53
54           my $form = <<EOF;
55              <form action="app.cgi">
56              <input type="hidden" name="run_mode" value="my_form_process">
57              <input type="hidden" name="cap_form_state" value="<tmpl_var cap_form_state>">
58              ...
59              </form>
60           EOF
61
62           sub my_form_display {
63               my $self     = shift;
64               my $errs     = shift;
65               my $t        = $self->load_tmpl(scalarref => \$form);
66
67               # Stash some data into it
68               $self->form_state->param('name'       => 'Wile E. Coyote');
69               $self->form_state->param('occupation' => 'Mining Engineer');
70
71               # Normal ValidateRM error handling
72               $t->param($errs) if $errs;
73               return $t->output;
74           }
75
76           sub my_form_process {
77               my $self;
78
79               # Normal ValidateRM validation
80               my ($results, $err_page) = $self->check_rm('my_form_display','_my_form_profile');
81               return $err_page if $err_page;
82
83               # The data from the submitted form
84               my $params = $self->dfv_results;
85
86               $params->{'name'}       = $self->form_state->param('name');       # 'Wile E. Coyote'
87               $params->{'occupation'} = $self->form_state->param('occupation'); # 'Mining Engineer'
88
89
90               # Now do something interesting with $params
91               # ...
92
93
94               my $t = $self->load_tmpl('success.html');
95               return $t->output;
96           }
97
98           # Standard ValiateRM profile
99           sub _my_form_profile {
100               return {
101                   required => 'email',
102                   msgs => {
103                           any_errors => 'some_errors',
104                           prefix => 'err_',
105                   },
106               };
107           }
108

DESCRIPTION

110       "CGI::Application::Plugin::FormState" provides a temporary storage area
111       within the user's session for storing form-related data.
112
113       The main use of this is for multi-page forms.  Instead of using hidden
114       fields to store data related to the form, you store and retrieve values
115       from the form state.
116
117       In the first instance of your app:
118
119           $self->form_state->param('some_name' => 'some_value');
120           $self->form_state->param('some_other_name' => 'some_other_value');
121
122       And later, in a different instance of your app:
123
124           $val1 = $self->form_state->param('some_name');
125           $val2 = $self->form_state->param('some_other_name');
126
127       To connect the first instance and the second, you put a single hidden
128       field in your template:
129
130           <input type="hidden" name="cap_form_state" value="<tmpl_var my_storage_name>">
131
132       You don't have to worry about creating the template param
133       "cap_form_state"; it is added automatically to your template parameters
134       via the "load_tmpl" hook.
135
136       If you want to use a parameter other than "cap_form_state" you can do
137       so via the "name" parameter to "form_state-"config>.
138
139       If you're skeptical about whether all this abstraction is a good idea,
140       see "MOTIVATION", below.
141

PRESERVING FORM STATE ACROSS REDIRECTS

143       You can include the form_state hash in a link:
144
145           my $link = '/app.cgi?rm=list&cap_form_state=' . $self->form_state->id;
146
147       If you use CGI::Application::Plugin::Redirect, you can easily create
148       redirect this way:
149
150           $self->redirect('/app.cgi?rm=list&cap_form_state=' . $self->form_state->id);
151
152       If you also use CGI::Application::Plugin::LinkIntegrity it is as simple
153       as:
154
155           $self->redirect($self->link('/app.cgi', 'rm' => 'list', 'cap_form_state' => $self->form_state->id));
156
157       Or, in the case of a link to the currently running app:
158
159           $self->redirect($self->self_link('rm' => 'list', 'cap_form_state' => $self->form_state->id));
160

IMPLEMENTATION

162       When you call "$self->form_state" for the first time, a top-level key
163       is created in the user's session.  This key contains a random, hard-to-
164       guess element.  It might look something like:
165
166          form_state_cap_form_state_84eb13cfed01764d9c401219faa56d53
167
168       All data you place in the form state with "param" is stored in the
169       user's session under this key.
170
171       You pass the name of this key on to the next instance of your
172       application by means of a hidden field in your form:
173
174           <input type="hidden" name="cap_form_state" value="<tmpl_var cap_form_state>">
175
176       You manually put this hidden field in your template.  The template
177       parameter "cap_form_state" is automatically added to your template
178       parameters via the "load_tmpl" hook.  It contains the random, hard-to-
179       guess portion (e.g. "84eb13cfed01764d9c401219faa56d53").  When the
180       template is filled, the hidden field will look something like this:
181
182           <input type="hidden" name="cap_form_state" value="84eb13cfed01764d9c401219faa56d53">
183
184       Since all values are stored on the server in the user's session, the
185       user can't tamper with any of them.
186
187       To keep old form_data from cluttering up the user's session, the system
188       uses CGI::Session's "expire" feature to expire old form state keys
189       after a reasonable amount of time has passed (2 days by default).
190
191       You can manually delete a form state storage by calling:
192
193           $self->form_state->delete;
194

METHODS

196       config(%options)
197           Sets defaults for the plugin.
198
199           Calling config is purely optional, since the defaults should be
200           fine most purposes.
201
202               $self->form_state->config('name' => 'storage_names', 'expires' => '3d')
203
204           The following options are allowed:
205
206           name
207               Sets the name of the default form state storage.  This name is
208               used for the key in the user's session, for the name of hidden
209               form field, and the template parameter used to fill the hidden
210               form field.  So if you set the "name" to "foo":
211
212                   $self->form_state_config('name' => 'foo');
213
214               then the hidden field in your template should look like this:
215
216                   <input type="hidden" name="foo" value="<tmpl_var foo>">
217
218               and the key in the user's session would look something like
219               this:
220
221                  form_state_foo_84eb13cfed01764d9c401219faa56d53
222
223           expires
224               Indicates when form state storage keys should expire and
225               disappear from the user's session.  Uses the same format as
226               CGI::Session's "expire".  Defaults to 2 days ('2d').  To cancel
227               expiration and make the form state last as long as the user's
228               session does, use:
229
230                   $self->form_state_config('expires' => 0);
231
232       param
233           Read and set values in the form state storage.  It acts like the
234           "param" method typically does in modules such as CGI,
235           CGI::Application, CGI::Session, "HTML::Template" etc.
236
237               # set a value
238               $self->form_state->param('some_name' => 'some_value');
239
240               # retrieve a value
241               my $val = $self->form_state->param('some_name');
242
243               # set multiple values
244               $self->form_state->param(
245                   'some_name'       => 'some_value',
246                   'some_other_name' => 'some_other_value',
247               );
248
249               # retrive the names of all the keys
250               my @keys = $self->form_state->param;
251
252       clear_params
253           Clear all of the values in the form state storage:
254
255              $self->form_state->param('name' => 'Road Runner');
256              $self->form_state->clear_params;
257              print $self->form_state->param('name'); # undef
258
259       delete
260           Deletes the form_state storage from the user's session.
261
262       id  Returns the current value of the storage param - the "hard to
263           guess" portion of the session key.
264
265               my $id = $self->form_state->id;
266
267       name
268           Returns the current name being used for storage.  Defaults to
269           "cap_form_state".
270
271               my $name = $self->form_state->name;
272
273       session_key
274           Returns the full key used for storage in the user's session.
275
276               my $key = $self->form_state->session_key;
277
278               # Get the full form state hash
279               my $data = $self->session->param($key);
280
281           The following can be used to debug the form_state data:
282
283               use Data::Dumper;
284               print STDERR Dumper $self->session->param($self->form_state->session_key);
285

MOTIVATION

287   Why not just use hidden fields?
288       Hidden fields are not secure.  The end user could save a local copy of
289       your form, change the hidden fields and tamper with your app's form
290       state.
291
292   Why not just use the user's session?
293       With "CGI::Application::Plugin::FormState" the data is associated with
294       a particular instance of a form, not with the user.  If the user gives
295       up halfway through your multi-page form, you don't want their session
296       to be cluttered up with the incomplete form state data.
297
298       If a user opens up your application in two browser windows (both
299       sharing the same user session), each window should have it's own
300       independent form state.
301
302       For instance, in an email application the user might have one window
303       open for the inbox and another open for the outbox.  If you store the
304       value of "current_mailbox" in the user's session, then one of these
305       windows will go to the wrong mailbox.
306
307       Finally, the user's session probably sticks around longer than the form
308       state should.
309

AUTHOR

311       Michael Graham, "<mag-perl@occamstoothbrush.com>"
312

BUGS

314       Please report any bugs or feature requests to
315       "bug-cgi-application-plugin-formstate@rt.cpan.org", or through the web
316       interface at <http://rt.cpan.org>.  I will be notified, and then you'll
317       automatically be notified of progress on your bug as I make changes.
318

ACKNOWLEDGEMENTS

320       Thanks to Richard Dice and Cees Hek for helping me sort out the issues
321       with this approach.
322
323       The informative error message text used for when this module is loaded
324       before your app actually @ISA "CGI::Application" object was stolen from
325       Cees's CGI::Application::Plugin::TT module.
326
328       Copyright 2005 Michael Graham, All Rights Reserved.
329
330       This program is free software; you can redistribute it and/or modify it
331       under the same terms as Perl itself.
332
333
334
335perl v5.34.0                      2021-07C-G2I2::Application::Plugin::FormState(3)
Impressum