Drupal默认的节点表单(entity form)输入有时候并不能满足我们的需求,比如我想做一个类似excel表格输入形式的表单呢?
- = DEMO点这里
(PS. 用Pantheon的sandbox做了一个随意折腾的drupal站点,真的是折腾死我了= =)
首先,新建一个自定义模块,在你的*.module
文件中hook_menu()
指定一个页面路径,设置页面调用表单,比如这样:
1function demo_tableform_menu(){
2 $items = array();
3 $items['demo/theme_table_into_form'] = array(
4 'title callback' => '表格方式輸入表單',
5 'page callback' => 'drupal_get_form',
6 'page arguments' => array('classroomtable_form'),
7 'access callback' => TRUE,
8 );
9
10 return $items;
11}
然后hook_form()
把这个表格的基本元素写出来,用#header
标签设置表格的表头部分,填充表格的每一行就用#rows
标签,表单元素常见的input name用#name
表示,标签#theme
是用来设置之后如何渲染这个表单的,最后用$form['submit']
设置表单提交后的动作。这整段的代码可以写成这样:
1function classroomtable_form($form, &$form_state){
2 $header = array(
3 'sex'=>'性別',
4 'number'=>'人數',
5 'height'=>'平均身高',
6 'classroom'=>'班級',
7 );
8 $options = array();
9 $options[] = array(
10 'sex' =>array(
11 'data' =>array(
12 '#type'=>'select',
13 '#name'=>'sex',
14 '#options'=>array(
15 'F'=>'女',
16 'M'=>'男'
17 ),
18 ),
19 ),
20 'number'=>array(
21 'data'=>array(
22 '#type'=>'textfield',
23 '#name'=>'number',
24 '#attributes'=>array(
25 'placeholder' => 0,
26 ),
27 '#size'=>12,
28 ),
29 ),
30 'height'=>array(
31 'data'=>array(
32 '#type'=>'textfield',
33 '#name' => 'height',
34 '#attributes' => array(
35 'placeholder' => 0,
36 ),
37 '#size'=>12,
38 ),
39 ),
40 'classroom'=>array(
41 'data'=>array(
42 '#type'=>'textfield',
43 '#name' => 'classroom',
44 '#size' => 12,
45 ),
46 ),
47 );
48
49 $form['table'] = array(
50 '#theme' => 'demo_tableform_form',
51 '#header' => $header,
52 '#tree' => TRUE,
53 '#rows' => $options,
54 '#empty' => t('No content available.'),
55 );
56
57 $form['submit'] = array(
58 '#type' => 'submit',
59 '#submit' => array('classroomtable_submit'),
60 '#value' => t('Save'),
61 );
62
63 return $form;
64}
比较方便的是,利用rows array key的设置还能区分每一行的不同值,比如下面这段代码,表单提交后sex[3]
就是用户在这行选择的值了,在多行表单中这种区分有时是非常有用的 :
1 $key = 3;
2 $options[$key] = array(
3 'sex' =>array(
4 'data' =>array(
5 '#type'=>'select',
6 '#name'=>'sex[{$key}]',
7 '#options'=>array(
8 'F'=>'女',
9 'M'=>'男'
10 ),
11 ),
12 ),
13...
表格(table render)渲染部分:
1/**
2 * @return array
3 */
4function demo_tableform_theme()
5{
6 return array(
7 'demo_tableform_form' => array(
8 'render element' => 'form',
9 ),
10 );
11}
12
13/**
14 * @param $variable
15 * @return string
16 */
17function theme_demo_tableform_form(&$variable)
18{
19 $form = $variable['form'];
20 $rows = $form['#rows'];
21 $header = $form['#header'];
22 $content = array(
23 '#theme' => 'table',
24 '#header' => $header,
25 '#rows' => $rows,
26 );
27 return drupal_render($content);
28}
最后把表单提交后的逻辑写一写就大功告成啦!表单提交内容用的是$form_state['input']
内的值。
1function classroomtable_submit($form, &$form_state){
2 $sex = $form_state['input']['sex']; //F or M
3 $number = $form_state['input']['number']; //int
4 $height = $form_state['input']['height']; //demecal
5 $classroom = $form_state['input']['classroom']; //text
6 if($number <= 0 || !(is_numeric($number) && is_int($number+0))){
7 form_set_error('number','请输入正确的人数');
8 }elseif($height <= 0|| !(is_numeric($height))){
9 form_set_error('height','请输入正确的身高');
10 }else{
11 $entity = entity_create('class_resourece',array('type'=>'class_resourece_basic'));
12 $ew = entity_metadata_wrapper('class_resourece', $entity);
13 $ew->created->set(time());
14 $ew->field_gender->set($sex);
15 $ew->field_numberof->set($number);
16 $ew->field_heights->set($height);
17 $ew->field_class->set($classroom);
18 $ew->save();
19 $form_state['redirect'] = '<front>';
20 }
21}