Drupal7 form

php

drupal_get_form, 讓drupal認得它是個form

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, form_state - form用於先後交互的變量

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']

給form製做一個template

從官方的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

修改一個已存在的form

可使用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
  }
}

提取node form

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);
}

free element, 使用傳統的方法呈現element

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數據

element group的form error,當form的元素層次不少時,error的處理會比較特別

通常用法:form_set_error('field_image', $message);

若是form用了多層次的element,例如$form['group'][0]['field_image'],這時須要寫成:form_set_error('group][0][field_image', $message);

form element 分組

$form['parent'] = array(
    '#type' => 'fieldset',
    '#tree' => true, // 認可有子元素,不然只能取值$form_state['value']['child']
    'child' => array(
        '#type' => 'textfield'
    )
);
// 以上元素取值以下
$form_state['values']['parent']['child'];

redirect,form提交後將去到什麼頁面?

drupal中很常見用drupal_goto進行跳轉,不管在什麼地方,都會強調被跳轉。但不該該用在form的validate和submit的callback中,這是由於validate和submit能夠接受多個callback,若是中途被GOTO了,後臺的callback就沒法執行。正常的方法是使用redirect參數

$form_state['redirect'] = 'node/1';

全部form的架構、驗證、提交函數,必須在.module或者顯式引入外部文件

若是form function不在module引入,有可能在提交後或者AJAX後找不到對應的function

給一個form增長更多的動做

/**
 * 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

// 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);
相關文章
相關標籤/搜索