译者:老葛 ESKALATE科技公司
使用form_set_value()传递数据
如果你的验证函数做了大量的处理,而你又想把结果保存此阿莱以在提交函数中使用,那么你可以使用form_set_value()暗中将结果保存到表单数据中。首先要做的是,当你在你的表单定义函数中创建表单时,你将需要为验证函数中要保存的处理结果预留一个位置:
$form['my_placeholder'] = array(
'#type' => 'value',
'#value' => array()
);
接下来,在你的验证程序中,你把数据保存起来:
// Lots of work here to generate $my_data as part of validation.
...
// Now save our work.
form_set_value($form['my_placeholder'], $my_data);
然后在你的提交函数中你就可以访问数据了:
// Instead of repeating the work we did in the validation function,
// we can just use the data that we stored.
$my_data = $form_values['my_placeholder'];
或者假定你想将数据转化为标准形式。例如,你在数据库中存有国家代码列表,你需要使用它们进行验证,但是你的不讲道理的老板坚持让用户可以在文本输入框中键入国家名称。你需要在你的表单中创建一个占位表单元素,通过使用一种聪明的方式对用户进行验证,这样你就可以同时将“The Netherlands”和 “Nederland”都映射为ISO 3166 国家代码“NL”了。
$form['country'] = array(
'#title' => t('Country'),
'#type' => 'textfield',
'#description' => t('Enter your country.')
);
// Create a placeholder. Will be filled in during validation.
$form['country_code'] = array(
'#type' => 'value',
'#value' => ''
);
在验证函数内部,你将国家代码保存到占位表单元素中:
// Find out if we have a match.
$country_code = formexample_find_country_code($form_values['country']);
if ($country_code) {
// Found one. Save it so that the submit handler can see it.
form_set_value($form['country_code'], $country_code);
}
else {
form_set_error('country', t('Your country was not recognized. Please use
a standard name or country code.'));
}
现在,在提交处理器(函数)中就可以使用$form_values['country_code']来访问国家代码了。
针对表单元素的验证
一般情况下,一个表单使用一个验证函数,但是也可以像为整个表单设置验证函数一样,为单个表单元素设置一个验证函数。为了实现这一点,我们需要为元素的属性#validate设置为一个数组,其中验证函数的名称作为键,任何你要传递的参数作为值。表单数据结构中该元素分支的一份完全拷贝,将被作为验证函数的第一个参数。下面是一个专门用来说明这一点的示例,在这里我们强制用户只能向文本输入框中输入香料(spicy)和糖果(sweet):
$allowed_flavors = array(t('spicy'), t('sweet'));
$form['flavor'] = array(
'#type' => 'textfield',
'#title' => 'flavor',
'#validate' => array('formexample_flavor_validate' => array($allowed_flavors))
);
那么你的表单元素验证函数应该如下所示:
function formexample_flavor_validate($element, $allowed_flavors) {
if (!in_array($element['#value'], $allowed_flavors) {
form_error($element, t('You must enter spicy or sweet.');
}
}
在调用完所有的表单元素验证函数以后,仍需调用表单验证函数。
提示:在你的表单元素未通过验证,你希望为它给出一条错误消息时,如果你知道表单元素的名称,那么使用form_set_error,如果你拥有表单元素本身,那么使用form_error()。后者对前者做了简单封装。
编写提交函数
提交函数是表单在被验证以后负责实际表单处理的函数。只有当表单验证完全通过时它才执行。如果要返回的还是同一页面,那么在提交函数中不需要使用关键字”return”.
如果在表单提交以后,你想让用户转到另一个页面,那么你就需要返回一个你要用户接下来访问的Drupal路径:
function formexample_form_submit($form, $form_values) {
// Do some stuff.
...
// Now send user to node number 3.
return 'node/3';
}
如果你有多个函数用来处理表单提交(参看本章前面的“提交表单”部分),只有从最后一个函数返回的值才被认为有效(但是如果Drupal在第一个函数执行完以后进行了重定向(译者注:重定向应该使用drupal_goto()),那么其它函数就不被执行了,这是因为用户已经被重定向到了别的页面了)。可以通过在表单中定义#redirect来覆盖提交函数中的重定向(参看本章前面的“为用户重定向”部分)。通常使用钩子函数form_alter()来做这项工作。
使用form_alter()来修改表单
使用form_alter(),你可以修改任何表单。你只需要知道表单的ID就可以了。让我们修改一下位于用户登录区块和用户登录页面的登录表单。
function formexample_form_alter($form_id, &$form) {
// We'll get called for every form Drupal builds; use an if statement
// to respond only to the user login block and user login forms.
if ($form_id == 'user_login_block' || $form_id == 'user_login') {
// Add a dire warning to the top of the login form.
$form['warning'] = array(
'#value' => t('We log all login attempts!'),
'#weight' => -5
);
// Change 'Log in' to 'Sign in'.
$form['submit']['#value'] = t('Sign in');
}
}
由于&$form是通过引用传递过来的,所以在这里我们对表单定义拥有完全的访问权并且可以做出任何我们想要的修改。在示例中,我们使用表单默认元素(参看本章后面的“标示字体(markup)”部分)添加了一些文本并接着修改了提交按钮的值。
使用drupal_execute()通过程序来提交表单
从Drupal5开始,可在网页浏览器中展示的任何表单,也都可以使用程序的方式填充表单。让我们通过程序填入我们的名称和喜欢的颜色。
$form_id = 'formexample_nameform';
$field_values = array(
'user_name' => t('Marvin'),
'favorite_color' => t('green')
);
// Submit the form using these values.
drupal_execute($form_id, $field_values);
要做的就是这些!简单的提供表单的ID和表单的数值,然后调用drupal_execute()即可。
警告:大多数提交函数都假定制造请求的的用户与提交表单的用户是同一个人。当通过程序来提交表单时,你需要对此格外小心,因为此时这两种用户不必相同。