第三节 表单API的属性
星期日, 01/04/2009 - 08:03 — lester
表单 API 属性
当表单创建函数对表单进行定义时,会用数组的键值来定义表单的相关信息。以下罗列了一些最常用的键值,其中一些会由表单的创建器自动完成。
表单的根本属性
以下属性具体定义了表单的根本属性。换句话说,你可以这样写$form['#programmed'] = TRUE,但是写成$form['myfieldset']['mytextfield'][#programmed'] = TRUE的形式却不会起作用。
#parameters
此属性是一组传给drupal_get_form()的参数,可由drupal_retrieve_form()函数进行添加。
#programmed
此布尔型的属性会指明表单是否可以以编程方式提交(例如使用drupal_execute())。如果表单优先处理#post,则通过drupal_prepare_form()可以设置#programmed的值。
#build_id
此属性是一个字符串(MD5哈希化的),代表了表单的一个具体实例。可以通过drupal_prepare_form()函数进行定义,并在表单的隐藏字段中进行发送,具体情况如下:
$form['form_build_id'] = array(
'#type' => 'hidden',
'#value' => $form['#build_id'],
'#id' => $form['#build_id'],
'#name' => 'form_build_id',
);
#token
此字符串(MD5哈希化的)是伴随每一个表单发送的唯一的口令,所以Drupal就能判别表单的发送者是Drupal系统还是某个恶意用户。
#id
此属性是form_clean_id($form_id)返回的一个字符串,具有类似HTML ID的特征。$form_id中的任何倒转括号(][),下划线(_)或者空格(“ ”)都会被替换成连字符,以符合CSS的ID习惯。Drupal会确保ID在同一页面下的唯一性。如果某ID在一个页面里出现了两次(比如同一页面下的两个相同的表单),其值就会被加上一个连字符和一个自增的整数,比如foo-form, foo-form-1, and foo-form-2这种形式。
#action
此字符串属性对应的是HTML表单标签的action属性。默认情况下,其值为request_uri()的返回值。
#method
此字符串属性对应了表单的提交方法,通常情况下都是post。表单API是基于post方法建立的,也就不会使用GET方法来处理表单。关于这两种方法的区别参见HTML细节的说明书。如果你在某些情况下需要使用GET方法,那你需要使用的可能是菜单API而不是表单API。
#redirect
此属性是一个字符串或者数组。如果是字符串,则应该是表单被提交后用户所转向的一个Drupal路径。如果是数组,则这个数组的第一个元素应该是用户跳转的路径,而整个数组将会作为参数传递给drupal_goto()函数(这种结构是为了可以同时传递其他参数给drupal_goto(),比如一个查询语句)。
#pre_render
此属性是由函数组成的数组,这些函数将在表单被生成之前调用,并为#pre_render传递设定好的元素。例如,$form['#pre_render'] = array('foo', 'bar')这样设定会导致Drupal先调用foo(&$form),然后是bar(&$form),如果将此属性设置在某个表单元素上,比如$form['mytextfield']['#pre_render'] = array('foo'),则Drupal调用的就是foo(&$element),其中$element就是$form['mytextfield']。这样你就可以在表单验证结束之后,但还没有被解释生成时hook到这个表单处理过程中,对表单的结构进行改写。而在验证函数运行之前对表单的改写,可以通过hook_form_alter()进行。
#post_render
此属性让你可以使用一组函数来修改刚刚生成好的表单内容。比如你想改写刚刚建立的表单,就可以设置$form['mytextfield']['#post_render'] = array('bar'),形如下例:
function bar($content, $element) {
$new_content = t('This element (ID %id) has the following content:',
array('%id' => $element['#id'])) . $content;
return $new_content;
}
#cache
此属性控制着表单是否会被Drupal的缓存系统进行缓存。缓存意味着表单提交之后不必重建。而$form['#cache'] = FALSE,将会使表单每次都被重建。
全体元素都可以添加的属性
当表单建立器检查整个表单定义过程时,它会确保每个元素都有必要的默认值。而默认值是在includes/form.inc 文件中的_element_info()函数里定义的,并可以通过定义hook_elements()中的元素进行改写。
#description
此字符串型的属性可以添加在任何元素里,其默认值是NULL。它是由元素的主题函数解释生成的。例如,一个文本区域的描述将会生成在此文本区域的底部,如图10-2所示。
#required
这是个布尔型的属性,可以添加在任何元素中,默认值是FALSE。而设置成TRUE将会使Drupal内置的表单验证机制会要求用户必须完整的填写此字段,否则系统将会抛出错误。同时,如果其值为TRUE,此元素将会添加一个CSS的类(参见includes/form.inc文件中的theme_form_element())。
#tree
这是一个布尔型的属性,可以为任何元素添加,默认值是FALSE。如果设置成TRUE,则提交表单所生成的$form_state['values']的值将以非平铺的方式呈现。这会影响你访问提交值的方式(参见本章“字段集”一节)。
#post
这是一个数组型的属性,它是原$_POST数据的一份拷贝,会由表单生成器添加给每个表单元素。这样#process 和 #after_build中定义的函数就可以基于#post的内容进行正确的判断了。
#parents
#attributes
此属性是一个联合数组,可以为任何元素添加,其默认值是空数组,但是通常情况下主题函数会对其进行构建。数组的元素会作为HTML属性被添加进来,比如,$form['#attributes'] = array('enctype' => 'multipart/form-data')。
全体元素都可以使用的属性
接下来会讲解全体元素都可以使用的属性。
#type
这是一个字符串,用来声明元素的类型。例如,#type = 'textfield'。而表单的根必须声明#type = 'form'。
#access
这是一个布尔型的属性,用来判断元素是否显示给用户。如果元素有子元素,则元素的#access为FALSE时,其子元素也不显示。例如,元素是字段集,如果#access的值是FALSE的话,字段集中的任何字段都不会被显示出来。
#access属性的值可以直接设置成TRUE或者FALSE,也可以是某个执行后的返回值为TRUE或者FALSE的函数。而此函数会在表单再次定义的时候被执行。下面是一个Drupal默认的节点表单的例子:
$form['revision_information']['revision'] = array(
'#access' => user_access('administer nodes'),
'#type' => 'checkbox',
'#title' => t('Create new revision'),
'#default_value' => $node->revision,
);
#process
此属性是一个联合数组。每个数组的形式都是将函数名作为键,需要传递的值作为值。这些函数将会在建立表单元素的时候被调用,并使建立表单时对元素进行额外的细微操作变为可能。例如,在modules/system/system.module中(此模块定义了checkboxes类型),存在于includes/form.inc文件中的expand_checkboxes()函数就会在表单建立过程中被调用:
$type['checkboxes'] = array(
'#input' => TRUE,
'#process' => array('expand_checkboxes'),
'#tree' => TRUE
);
可以同时参考本章“尽可能收集所有定义了的表单元素”一节中的例子。在#process中的所有函数都被调用过之后,每个元素就都添加了一个#processed属性。
#after_build
这是一个数组类型的属性,由函数组成,这些函数将会在元素被建立后立即调用。每个函数有两个参数:$form 以及$form_state。例如,如果$form['#after_build'] = array('foo', 'bar')那么Drupal在表单建立结束后将会调用foo($form,$form_state) 和bar($form, $form_state)。而在调用结束之后,Drupal会给此元素加上一个#after_build_done属性。
#theme
这是一个可选的属性,定义了一个字符串,用来在Drupal为元素搜寻一个主题函数时使用。例如,#theme = 'foo'会使Drupal在主题清单中搜寻一条与foo相符合的条目。请参考本章前面的“为表单寻找一个主题函数”一节。
#prefix
此属性之中定义的字符串将会在元素被解释生成之后加在输出结果的前面,紧挨着此元素。
#suffix
此属性之中定义的字符串将会在元素被解释生成之后加在输出结果的后面,紧挨着此元素。
#title
作为元素的标题的字符串。
#weight
此属性为一十进制整数。当表单元素被解释生成后,他们将会按权重排序。在页面中,权重值小的将会“上升”,具有一个靠上方的位置,而权重值大的将会“下沉”,具有一个靠下方的位置。
#default_value
这是一个混合型的属性。对于输入型元素,它就是字段在表单还没有提交的时候的值。不要将它与#value元素混淆了,后者是内置的表单值,体现在$form_state['values']中,并且绝不会显示给用户。
表单元素
在这一节,我们将展示几个内置的Drupal表单元素的例子。
Textfield
以下是一个textfield类型的元素的例子:
$form['pet_name'] = array(
'#title' => t('Name'),
'#type' => 'textfield',
'#description' => t('Enter the name of your pet.'),
'#default_value' => $user->pet_name,
'#maxlength' => 32,
'#required' => TRUE,
'#size' => 15,
'#weight' => 5,
'#autocomplete_path' => 'pet/common_pet_names',
);
$form['pet_weight'] = array(
'#title' => t('Weight'),
'#type' => 'textfield',
'#description' => t('Enter the weight of your pet in kilograms.'),
'#field_suffix' => t('kilograms'),
'#default_value' => $user->pet_weight,
'#size' => 4,
'#weight' => 10,
);
结果如图10-11

图10-11 textfield元素
在这里#field_prefix 和 #field_suffix属性对于textfield元素的具体效果是立即在文本输入区域的前面或者后面加上一个字符串。
而#autocomplete属性的作用是定义一个路径,以便让Drupal自动使用JQuery发送HTTP请求来提取JvaScript文件。在当前例子中,是对http://example.com/?q=pet/common_pet_names发送请求。实际应用上的例子请参见modules/user/user.pages.inc文件中的user_autocomplete() 函数。
经常和textfield元素一起使用的属性还有以下几种:#attributes,#autocomplete_path (默认值是 FALSE), #default_value, #description, #field_prefix,#field_suffix, #maxlength (默认值是128),#prefix, #required, #size (默认值是60),#suffix, #title, #process (默认值是form_expand_ahah), 以及#weight.
Password
此元素会建立一个HTML的密码区域,以让用户输入密码并且不直接显示结果(通常在屏幕上用星号*来代替用户输入的内容)。user_login_block()函数中有这样一个例子:
$form['pass'] = array('#type' => 'password',
'#title' => t('Password'),
'#maxlength' => 60,
'#size' => 15,
'#required' => TRUE,
);
通常和password元素一起使用的属性有,#attributes, #description,#maxlength, #prefix, #required, #size (默认值 60), #suffix, #title, #process (默认是 form_expand_ahah), 和 #weight。因为安全上的原因#default_value属性在password元素中并没有使用。
Password with Confirmation
此元素会创建两个HTML的密码区域,并验证两个区域中输入的密码是否匹配。例如,此元素在user模块中的应用以应对用户修改密码的清空:
$form['account']['pass'] = array(
'#type' => 'password_confirm',
'#description' => t('To change the current user password, enter the new
password in both fields.'),
'#size' => 25,
);
Textarea
以下是一个使用textarea元素的例子
$form['pet_habits'] = array(
'#title' => t('Habits'),
'#type' => 'textarea',
'#description' => t('Describe the habits of your pet.'),
'#default_value' => $user->pet_habits,
'#cols' => 40,
'#rows' => 3,
'#resizable' => FALSE,
'#weight' => 15,
);
此元素使用的属性通常有以下几个,#attributes, #cols 默认值是60), #default_value, #description, #prefix, #required, #resizable, #suffix, #title, #rows(默认值 5), #process (默认是 form_expand_ahah),以及 #weight。
如果#resizable的值是TRUE,则会启用动弹文本区模式,此时对于#cols的设置可能起不到预期的作用。
Select
下面是一个在modules/statistics/statistics.admin.inc文件中关于select元素的例子:
$period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800,
259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval');
/* Period now looks like this:
Array (
[3600] => 1 hour
[10800] => 3 hours
[21600] => 6 hours
[32400] => 9 hours
[43200] => 12 hours
[86400] => 1 day
[172800] => 2 days
[259200] => 3 days
[604800] => 1 week
[1209600] => 2 weeks
[2419200] => 4 weeks
[4838400] => 8 weeks
[9676800] => 16 weeks )
*/
$form['access']['statistics_flush_accesslog_timer'] = array(
'#type' => 'select',
'#title' => t('Discard access logs older than'),
'#default_value' => variable_get('statistics_flush_accesslog_timer', 259200),
'#options' => $period,
'#description' => t('Older access log entries (including referrer statistics)
will be automatically discarded. (Requires a correctly configured
<a href="@cron">cron maintenance task</a>.)', array('@cron' =>
url('admin/reports/status'))),
);
Drupal支持将选项分组,这可以通过将#options属性定义成由选项组成的联合数组来实现,就像图10-12中展示的那样。
$options = array(
array(
t('Healthy') => array(
1 => t('wagging'),
2 => t('upright'),
3 => t('no tail')
),
),
array(
t('Unhealthy') => array(
4 => t('bleeding'),
5 => t('oozing'),
),
),
);
$form['pet_tail'] = array(
'#title' => t('Tail demeanor'),
'#type' => 'select',
'#description' => t('Pick the closest match that describes the tail
of your pet.'),
'#options' => $options,
'#multiple' => FALSE,
'#weight' => 20,
);

图10-12 使用了选项分组的选择区域
将#multiple属性的值设为TRUE可以启用多重选项功能。这一改动同时将$form_state['values']中的值从一个字符串(例如'pet_tail' = '2',假设当前例子是upright被选中的情况)变成了一个值的数组(例如,pet_tail= array( 1 => '1', 2 => '2'),假设为当wagging 和upright都被选中的时候)。
通常和select元素一起使用的属性有#attributes, #default_value,#description, #multiple, #options, #prefix, #required, #suffix, #title, #process (默认是 form_expand_ahah), 以及#weight.
Radio Buttons
以下是一个modules/block/block.admin.inc文件中的例子:
$form['user_vis_settings']['custom'] = array(
'#type' => 'radios',
'#title' => t('Custom visibility settings'),
'#options' => array(
t('Users cannot control whether or not they see this block.'),
t('Show this block by default, but let individual users hide it.'),
t('Hide this block by default but let individual users show it.')
),
'#description' => t('Allow individual users to customize the visibility of
this block in their account settings.'),
'#default_value' => $edit['custom'],
);
通常和此元素一起使用的属性有#attributes, #default_value,#description, #options, #prefix, #required, #suffix, #title, 以及#weight。注意#process属性的默认值是设为expand_radios()的(参见includes/form.inc)。
Check Boxes
例子如下,解释生成后的结果如图10-13
$options = array(
'poison' => t('Sprays deadly poison'),
'metal' => t('Can bite/claw through metal'),
'deadly' => t('Killed previous owner') );
$form['danger'] = array(
'#title' => t('Special conditions'),
'#type' => 'checkboxes',
'#description' => (t('Please note if any of these conditions apply to your
pet.')),
'#options' => $options,
'#weight' => 25,
);

图10-13 使用check boxes元素的实例
array_filter()函数经常在验证和提交函数中使用,用于得到复选框的键值。例如,如果图10-13中的前两个选项被选中了,$form_state['values']['danger'] 将会包含以下内容:
array(
'poison' => 'poison',
'metal' => 'metal',
deadly' => 0,
)
运行array_filter($form_state['values']['danger'])的结果是得到一个值含有已勾选的选项的键名的数组:array('poison', 'metal')。
通常和此元素一起使用的属性还有#attributes, #default_value, #description, #options, #prefix, #required, #suffix, #title, #tree (默认值是 TRUE),以及#weight。要注意#process属性的默认值是expand_checkboxes()(参见includes/form.inc)。
Value
此属性的作用是在不发送给浏览器的情况下将$form 的值内部传递给 $form_state['values'],比如:
$form['pid'] = array(
'#type' => 'value',
'#value' => 123,
);
当表单被提交之后,, $form_state['values']['pid'] 的值将是 123。
不要混淆了#type => 'value' 和#value => 123的作用。前者是在声明元素的类型,而后者是在声明元素的值。对于此元素,只有#type和#value属性可以使用。
Hidden
此元素使用隐藏类型的HTML输入字段来向表单传递隐藏值,形如下例:
$form['my_hidden_field'] = array(
'#type' => 'hidden',
'#value' => t('I am a hidden field value'),
);
如果你想通过表单发送某些隐藏信息,通常来说应该使用value元素,而hidden元素只在value元素不够用的时候才被用到。这是因为用户可以通过查看表单源文件的方式来访问hidden元素,而value元素是Drupal的内部元素,并不包含在HTML代码中。
只有 #prefix, #suffix, #process (默认值 form_expand_ahah), 以及 #value properties会在此元素中被使用。
Date
图10-14展示的,是一个带有三个选项的结合型元素
$form['deadline'] = array(
'#title' => t('Deadline'),
'#type' => 'date',
'#description' => t('Set the deadline.'),
'#default_value' => array(
'month' => format_date(time(), 'custom', 'n'),
'day' => format_date(time(), 'custom', 'j'),
'year' => format_date(time(), 'custom', 'Y'),
),
);

图10-14 date字段
通常和此元素一起使用的属性有#attributes, #default_value,#description, #prefix, #required, #suffix, #title,以及#weight。#process p属性的默认值是调用expand_date(),此时years是被硬编码为1900到2050之间的。#element_validate属性的默认值是date_validate()(这两个函数都在includes/form.inc之中)。你在定义date元素的时候可以使用自己的代码来重新定义这两个元素。
Weight
此元素表现为一个使用具体权重的下拉框(不要将它和#weight混淆了):
$form['weight'] = array(
'#type' => 'weight',
'#title' => t('Weight'),
'#default_value' => $edit['weight'],
'#delta' => 10,
'#description' => t('In listings, the heavier vocabularies will sink and
lighter vocabularies will be positioned nearer the top.'),
);
代码的运行结果如图10-15

图10-15 weight元素
#delta属性决定了都能选择哪些权重值,其默认值是10.。例如,如果你将#delta的值设置成50,则可选的权重值的范围会是-50到50.而此元素经常使用的属性有#attributes, #delta (默认值 10),#default_value, #description, #prefix, #required, #suffix, #title, 以及 #weight。#process属性的默认值是数组array('process_weight', 'form_expand_ahah')。
File Upload
file元素建立了一个File Upload接口。下面是以modules/user/user.module中的代码为例:
$form['picture']['picture_upload'] = array(
'#type' => 'file',
'#title' => t('Upload picture'),
'#size' => 48,
'#description' => t('Your virtual face or picture.')
);
元素的生成结果如图10-16

图10-16 file upload元素
注意如果你使用了此元素,你需要在根本表单中设置enctype:
$form['#attributes']['enctype'] = 'multipart/form-data';
file元素经常使用的属性有#attributes, #default_value,#description, #prefix, #required, #size (默认值是 60), #suffix, #title, 以及 #weight.
Fieldset
fieldset元素用来将元素分组。它可以声明成可摺叠的形式,这样当用户访问表单的时候,Drupal封装的JavaScript语句就可以通过点击动作来动态的打开或关闭此字段集。注意在此例子中#access属性的使用,它将控制字段集中所有字段的权限:
// Node author information for administrators.
$form['author'] = array(
'#type' => 'fieldset',
'#access' => user_access('administer nodes'),
'#title' => t('Authoring information'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 20,
);
fieldset元素通常使用的属性有#attributes, #collapsed (默认值FALSE), #collapsible (默认值FALSE), #description, #prefix, #suffix, #title,#process (默认是form_expand_ahah), 以及#weight。
Submit
submit元素用来提交表单。按钮上显示的单词默认情况下是“Submit”,并且可以通过修改#value属性来改写:
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Continue'),
);
此元素通常情况下使用的属性有#attributes, #button_type (默认值'submit'), #executes_submit_callback (默认值TRUE), #name (默认值'op'), #prefix, #suffix, #value, #process (默认是 form_expand_ahah), 以及 #weight.
另外,#validate 和#submit属性可以直接在sunmit元素中指定。例如,如果#submit被设置成array('my_special_form_submit'),则函数my_special_form_submit()将会代替已经定义好的表单提交器用来提交表单。
Button
除了#executes_submit_callback属性的默认值是FALSE以外,此元素基本和submit一样。这个属性是用来告知Drupal究竟是应该处理表单(其值为TRUE的时候),还是简单的重建表单(其值是FALSE的时候)。就像submit按钮一样,可以为button元素直接的指定具体的验证和提交函数。
Image Button
image button元素基本和submit元素的功能一致,除了以下两个特殊之处:第一,此元素有一个#src属性,其值是某个图片的URL。第二,它有一个内置的属性#has_garbage_value并且默认值为TRUE,这是为了防止在Microsoft Internet Explorer浏览器中使用的#default_value引起故障,所以千万不要对image buttons使用#default_value。这里有一个使用了Drupal内置图片的例子:
$form['my_image_button'] = array(
'#type' => 'image_button',
'#src' => 'misc/powered-blue-80x15.png',
'#value' => 'foo',
);
按钮的值可以安全的从$form_state['clicked_button']['#value']中得到。
Markup
如果元素没有指明#type属性,则markup将是此元素的默认类型。它用来在表单中间加入一段文本或者HTML代码。
$form['disclaimer'] = array(
'#prefix' => '<div>',
'#value' => t('The information below is entirely optional.'),
'#suffix' => '</div>',
);
此元素经常使用的属性有#attributes, #prefix (默认值是空字符 ''), #suffix (默认值是空字符 ''), #value, 以及#weight。
Caution如果你输出的文本是在一个可摺叠的字段集中,用<div>标签将它打包吧,就像例子中做的那样,这样你的文本就会随着字段集一起摺叠了。
Item
Item元素的格式和其他输入类型的元素基本一致,比如textfield 和select field,但是它并没有输入字段。
$form['removed'] = array(
'#title' => t('Shoe size'),
'#type' => 'item',
'#description' => t('This question has been removed because the law prohibits us
from asking your shoe size.'),
);
元素将被解释生成为图10-17的样子

图10-17 一个item元素的例子
和item元素一起使用的属性通常有#attributes, #description, #prefix(默认值是空字符, ''), #required, #suffix (默认值是空字符, ''),#title, #value, 以及 #weight。

评论
tiffany co jewelry
tiffany & co
Tiffany Necklaces
Tiffany Charms
Tiffany Bracelets
Tiffany Earrings
Tiffany Rings
tiffany jewelry
gucci jewelry
gucci uk