php
form须要用drupal_get_form来加工,system才会把它认为是form,其实最终form的array也是drupal_render进行处理,drupal_get_form仅仅是给array添加让system认定为form的基本数据。html
drupal_render接收的参数是一个array,它认为array嵌套的元素都是一个array,除非用#这个特殊键值声明。例如array('#markup' => '<span>....</span>');node
form的callback function都会有form和form_state两个参数,form用于生成form的结构,最终输出到页面上,form_state用于保存form的状态,并能够在callback之间转递数据。api
在$form中,全部不带#开头的键名会被视为表单元素或分组元素;带#开头的键名会被视为表单元素的属性。架构
$form_state除了交互数据外,还有一些键名有特殊做用:函数
$form_state['input'] $form_state['values'] : 从form post过来的全部值 $form_state['redirect'] : 让form完成submit后自动跳转到指定页面 $form_state['rebuild']
从官方的drupal api document中可获得form有#theme这个参数,它能够指定form使用一个模板来用于form的基本布局,#theme的值必须是经过hook_theme声明的key。通常状况下,即便不去声明#theme,#theme也会有一个与本form同名的默认值,因此只须要用hook_theme声明一个与form name同样的key就能够。
mymodule.module:布局
function mymodule_form(){ // ... return $form; } function mymodule_theme() { return array( // theme name与form ID同样。这是因为每一个form[#theme]都有一个等于form ID的默认值。 'mymodule_form' => array( 'render element' => 'form', 'template' => 'mymodule-form', // 对应文件名mymodule-form.tpl.php ), ); }
mymodule-form.tpl.php:post
<?php $form = $variables['form'];?> <?php echo drupal_render($form['name']); // 'name' form element ?> <?php echo drupal_render_children($form); // print other all form element ?>
修改其它form同理,先用devel确认form的#theme值,而后使用hook_theme建立对应的key。若是form已经有template,可使用hook_form_alter把#theme修改成另外的名。ui
可使用hook_form_alter修改form的内容,前提是获得form ID(drupal中全部form都会有一个form ID,通常与建立form的函数名相同)
Linkspa
如下方法能够输出全部form的form ID,获得form ID才能够对form进行单独操做,建议加到theme下的template.php中,命名为mytheme_form_alter (mytheme要改成当前theme的名字)
function mytheme_form_alter(&$form, &$form_state, $form_id) { $print = '<pre>' . print_r($form, TRUE) . '</pre>'; if (module_exists('devel')) { dsm($form_id); // print form ID to messages } else { drupal_set_message($form_id); // print form ID to messages } if (module_exists('devel')) { dsm($form); // pretty print array using Krumo to messages } else { drupal_set_message($print); // print array to messages } }
function example_form($form, &$form_state, $node = NULL) { if (!$node) { $node = new stdClass(); $node->type = 'page'; $node->title = ''; $node->language = LANGUAGE_NONE; } $form_state['#node'] = $node; field_attach_form('node', $node, $form, $form_state); $form['actions'] = array( '#type' => 'actions' ); $form['actions']['submit'] = array( '#type' => 'submit', '#value' => t('Save') ); return $form; } function example_form_submit($form, &$form_state) { global $user; $node = $form_state['#node']; if(!isset($node->uid)){ $node->uid = $user->uid; } field_attach_submit('node', $node, $form, $form_state); node_save($node); }
function mymodule_form(){ // 必须存在,不然submit没法获得chk的值 $form['chk']= array( '#type' => 'hidden', '#printed' => true ); $form['html'] = array( '#markup' => '<input type="checkbox" name="chk[]" value="1"/>|||<input type="checkbox" name="chk[]" value="2"/>' ); $form['submit'] = array('#type' => 'submit', '#value' => t('Submit')); return $form; }
$form['any']['#access'] = false; // 不可见 $form['any']['#value'] = $default_value; // 强制设置value,不接受post数据
通常用法:form_set_error('field_image', $message);
若是form用了多层次的element,例如$form['group'][0]['field_image'],这时须要写成:form_set_error('group][0][field_image', $message);
$form['parent'] = array( '#type' => 'fieldset', '#tree' => true, // 认可有子元素,不然只能取值$form_state['value']['child'] 'child' => array( '#type' => 'textfield' ) ); // 以上元素取值以下 $form_state['values']['parent']['child'];
drupal中很常见用drupal_goto进行跳转,不管在什么地方,都会强调被跳转。但不该该用在form的validate和submit的callback中,这是由于validate和submit能够接受多个callback,若是中途被GOTO了,后台的callback就没法执行。正常的方法是使用redirect参数
$form_state['redirect'] = 'node/1';
若是form function不在module引入,有可能在提交后或者AJAX后找不到对应的function
/** * Implementation of hook_form_alter(). */ function mymodule_form_alter(&$form, &$form_state, $form_id){ if($form_id == 'article_node_form')) { $form['actions']['submit']['#submit'][] = 'mymodule_article_node_form_submit'; } } function mymodule_article_node_form_submit($form, &form_state) { // 表单提交后跳转到首页 $form_state['redirect'] = 'node'; }
// register a new user $form_state = array(); $form_state['values']['name'] = 'robo-user'; $form_state['values']['mail'] = 'robouser@example.com'; $form_state['values']['pass'] = 'password'; $form_state['values']['op'] = t('Create new account'); drupal_execute('user_register', $form_state);