form

改變 form 的 template

這次修改的是 views 的 exposed form
需要比較大的修改便想要使用 tpl 而不使用 template.php
舊文 form 也可以使用template (*.tpl.php)也有說明, 但已經不是 Drupal6.x 作法了

以下更新為 Drupal6.x 的作法:
先自建一個模組, 使用 hook_theme
定義如下:

<?php
function mymodule_theme($existing, $type, $theme, $path) {
  return array(
   
//form id
   
'form_id' => array(
     
'arguments' => array('node' => NULL),
     
'template' => 'search_form', //表示使用 search_form.tpl.php
   
),
  );
}
?>

重點在於提供一個 template 的值, 你便可以在該 tpl 檔使用 <?php $form; ?>
再使用 <?php drupal_render($form['title']); ?> 之類完成 form 的 各欄位和 html 碼

最後, 實作的時候記得清緩存就可以了

查找一個選單的欄位的可選項 Get display values of a dropdown list

在 views 的 $views->exposed filter 可以提取已經提交的表單值
但除了值之外, 一般還需要欄位的其他資料,
例如欄位旳值和顯示值不一樣的時候,

可以使用:

<?php
//field_hotel_group 是欄位名
$mappings = optionwidgets_options(content_fields('field_hotel_group'));
?>

可得到類似:

你便可以自己再處理了


You can get the value of view's exposed filter value by $views->exposed filter
But other than value, the display value is also needed
Especially when the submit value is not the same as display value:

Actually you can use:


and you will obtain:

and then you can map back those values for your own use.

2011-02-07 為 form 增加新的 validation 規則

hook_form_alter() 本來是為了修改 form 的各種屬性
例如增加欄位, 修改欄位的預設值等等
但其實還可以增加 validation 規則和增加提交後的處理

增加 validation 規則:

<?php
function mymodule_form_alter(&$form,$form_state, $form_id) {
  if(
$form_id=='user_register') { //只是一個例子, 你可以填入需要的 form id
    //為 #validate 陣列增加一個元素, 元素的值就是新的 validate 函數名
   
$form['#validate'][] = 'mymodule_new_user_register_validation';
  }
}

//然後定義新的 validate 函數, 帶入兩個參數
function mymodule_new_user_register_validation($form, &$form_state) {
 
//$form_state['values'] 儲存用戶提交的數據
 
if(strpos('admin',$form_state['values']['username'])===false) {
   
//用戶名字不可以有 admin 的字眼
   
form_set_error('username', '用戶名字不可以有 admin 的字眼');
  }
}
?>

增加提交後的處理:

<?php
function mymodule_form_alter(&$form,$form_state, $form_id) {
  if(
$form_id=='user_register') {
   
//為 #submit 陣列增加一個元素, 元素的值就是新的提交後處理函數
   
$form['#submit'][] = 'mymodule_new_user_register_submit';
  }
}

//然後定義新的 validate 函數, 帶入兩個參數
function mymodule_new_user_register_submit($form, &$form_state) {
 
//$form_state['values'] 儲存用戶提交的數據
 
drupal_set_message('Welcome, '.$form_state['values']['username']);
}
?>

相關:
Drupal form API
hook_submit, hook_form_alter, hook_validate in Drupal 6.x

hook_submit, hook_form_alter, hook_validate in Drupal 6.x

EDIT: 2011-02-07 更詳細的 hook_form_alter 例子

hook_submit() 是每一張form 提交的時候會經過的 hook
可以用作發電郵之類的自定義動作

類似的, hook_validate() 是驗證每一張 form 的時候會經過的hook
可以自定義更多驗證的 logic

而從Drupal 5.x 之中, hook_submit() 的 function callback 可以在form API 使用如下 syntax:

<?php
$form
['submit']['#submit'] = array('function1','function2');
?>

那 function1 和 function2 都會在 hook_submit() 之中callback 了

而 Drupal 6.x 之中, #submit 在不再在 submit button 之中定義:

<?php
$form
['#submit'][] = 'my_module_submit_handler'
?>

雖然 D5 的方法都可以, 但便不可以用 hook_form_alter() 從一個 module 修改另一個module 的 form 了

例如, contact form 需要一個contact number,
submit 時將 contact number 加到 body 之內:

<?php
function my_module_form_alter($form,&$form_statues) {
 
$form['#submit'][] = 'my_module_submit_handler';
}
function
my_module_submit_handler($form,&$form_statues){
 
//processing
}
?>

EDIT: 2011-02-07 更詳細的 hook_form_alter 例子

將註冊時連續輸入兩次密碼的表單的字眼改掉

將註冊時連續輸入兩次密碼的表單的字眼改掉的方法:

theme 的 template.php 內:

<?php
function phptemplate_password($element) {
  if(
$element['#id']=='edit-pass-pass1'){
   
$element['#title']=t('joe');
  }

  if(
$element['#id']=='edit-pass-pass2'){
   
$element['#title']=t('confirm joe');
  }

 
$size = $element['#size'] ? ' size="'. $element['#size'] .'" ' : '';
 
$maxlength = $element['#maxlength'] ? ' maxlength="'. $element['#maxlength'] .'" ' : '';

 
_form_set_class($element, array('form-text'));
 
$output = '<input type="password" name="'. $element['#name'] .'" id="'. $element['#id'] .'" '. $maxlength . $size . drupal_attributes($element['#attributes']) .' />';
  return
theme('form_element', $element, $output);
}
?>

其實其他的form 元素都可以用同一個方法改
甚至改為select 都可以
但亂改一通可能會令數據庫資料丟失
所以, 結構邏輯的修改還是使用 hook_form_alter() 吧