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