-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwizard.example
More file actions
196 lines (178 loc) · 6.84 KB
/
Copy pathwizard.example
File metadata and controls
196 lines (178 loc) · 6.84 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
<?php
// These three defines set the words written in the wizard buttons.
// We use defines because these values get passed to and fro, and
// we have to compare against them when processing the form.
define('WIZARD_NEXT', 'Next');
define('WIZARD_PREVIOUS', 'Back');
define('WIZARD_CANCEL', 'Cancel');
// Set how many steps in this wizard.
define('WIZARD_FINAL_STEP', 3);
// When finishing the wizard (or cancelling it), this defines where
// the browser ends up going.
define('WIZARD_FINISH_REDIRECT', 'node');
function _my_module_wizard($form_values=NULL) {
// Get the "step" in the wizard we're on. If it's not yet set, then
// we must be on step one. We usually increment the step, but if
// the user last pressed the 'back' button, then we decrement it instead.
if (!isset($form_values)) {
$step = 1;
} else {
if(isset($form_values['op']) && $form_values['op'] == t(WIZARD_PREVIOUS)) {
// Back button pressed...
$step = $form_values['step'] - 1;
} else {
$step = $form_values['step'] + 1;
}
}
// Put a hidden value in the form that says which step we're on.
// This gets posted back to us, and used (above) next time around.
$form['step'] = array(
'#type' => 'hidden',
'#value' => $step,
);
// This is purely cosmetic. We just say which page we're on. This
// probably wants removing (or at least pretty-ing up!)
$form['display'] = array(
'#type' => 'markup',
'#value' => "Page $step",
);
// These are *very* important. 'multistep' tells Drupal to store
// extra information between form steps. 'tree' tells drupal to
// preserve the multi-dimensional form information we're using.
// 'tree' isn't completely necessary in this example, but for
// big/complex forms, it's pretty obligatory!
$form['#multistep'] = TRUE;
$form['#tree'] = TRUE;
// This is where we actually produce the form on each step of the
// wizard. Naturally, it's possible to have as many steps as needed
// here. It's not obligatory, but useful to separate each page in
// a separate key in for $form.
switch($step) {
case 1:
$form['pageone']['itemone'] = array(
'#type' => 'textfield',
'#default_value' => 'page 1 item',
);
break;
case 2:
$form['pagetwo']['itemtwo'] = array(
'#type' => 'textfield',
'#default_value' => 'page 2 item',
);
break;
case 3:
$form['pagethree']['itemthree'] = array(
'#type' => 'textfield',
'#default_value' => 'page 3 item',
);
break;
}
// This is important. If we're on the final step,
// we tell drupal to use the normal redirect functionality.
// That means the browser goes to whatever page after the
// final submit. All previous steps don't redirect, so just
// post back to this form.
if($step == WIZARD_FINAL_STEP) {
$form['#redirect'] = NULL;
} else {
$form['#redirect'] = FALSE;
}
// Now insert any previous form values... We need to remember
// what has gone on previously. It's possible this could go into
// $_SESSION instead, which is probably a good idea if there's
// a lot of data captured in the wizard. This code only re-inserts
// multi-dimensional form values (which are used in the switch/case
// above). This leaves all non multi-dimensional out of the
// post/repost cycle (saving a bit of mess in the form)
if(!is_null($form_values)) {
foreach (array_keys($form_values) as $pagenum) {
if(is_array($form_values[$pagenum])) {
foreach ($form_values[$pagenum] as $key => $value) {
// Don't overwrite any form elements that are set above.
// This could happen if the user presses "back"; it basically
// makes elements disappear, which we don't want!
if(!isset($form[$pagenum][$key])) {
$form[$pagenum][$key] = array(
'#type' => 'hidden',
'#value' => $value,
);
}
}
}
}
}
// Insert a button. We use a 'submit', which causes the form
// to be sent to Drupal, which puts it through validation AND
// submission routines. Use a 'button' to avoid the submit
// phase (for all but the last page of your form!). The
// wizard uses the submit phase to provide the 'cancel' facility,
// so be careful.
if($step > 1) {
$form['previous'] = array(
'#type' => 'submit',
'#value' => t(WIZARD_PREVIOUS),
);
}
$form['next'] = array(
'#type' => 'submit',
'#value' => t(WIZARD_NEXT),
);
$form['cancel'] = array(
'#type' => 'submit',
'#value' => t(WIZARD_CANCEL),
);
return $form;
}
function _my_module_wizard_validate($form_id, $form_values) {
// If the user presses 'cancel' or 'back', we should do no further
// validation. Also, if they press 'cancel' we should actually
// goto the finish page, because the 'submit' stage won't be called
// if the user hasn't filled in one of the mandatory fields. In fact,
// in that case, Drupal's built in form validation will have set
// errors that we don't need to show the user.
if($form_values['op'] == t(WIZARD_CANCEL)) {
// Clear errors from Drupal's built in validation...
drupal_get_messages('error');
// Tell the user we've cancelled
drupal_set_message('Wizard cancelled.');
// Now go to the 'finish page'
drupal_goto(WIZARD_FINISH_REDIRECT);
return;
} else if($form_values['op'] == t(WIZARD_PREVIOUS)) {
// Clear messages, and do no further validation
drupal_get_messages('error');
return;
}
// Do whatever validation here. It's probably a good idea to do a
// switch/case on the wizard step. It may be a good idea to validate
// everything on each call, as that will catch anyone hacking the
// form with directly injected form posts, although at slightly
// more processing.
}
function _my_module_wizard_submit($form_id, $form_values) {
// If the user presses 'back' or 'cancel' don't do any submission work...
if($form_values['op'] == t(WIZARD_PREVIOUS) || $form_values['op'] == t(WIZARD_CANCEL)) {
// Don't do any submission work here, it's not relevant
return FALSE;
}
// Process the form values. In this example, we only do something
// when we reach the end of the wizard. Our example just displays
// the form values on whatever page we redirect to.
if(isset($form_values['step']) && $form_values['step'] == WIZARD_FINAL_STEP) {
if(!is_null($form_values)) {
foreach (array_keys($form_values) as $pagenum) {
if(is_array($form_values[$pagenum])) {
foreach ($form_values[$pagenum] as $key => $value) {
drupal_set_message("Got page $pagenum key $key = $value");
}
}
}
}
// Now send the browser to the 'finish page'.
return WIZARD_FINISH_REDIRECT;
}
// If we haven't processed the form and completed fully, we have
// to return FALSE so that Drupal redisplays our form.
return FALSE;
}
?>