Drupal7 表單內載入 css, js, attach

Edit: 2012-11-07: external css

Drupal7 中以下的代碼是不會達到你想要的效果的

<?php
function hook_form_alert(&$form, &$form_states) {
 
drupal_add_js(drupal_get_path('module', 'example') . "/js/example.js");
}
?>

hook_form_alter 中使用 drupal_add_css() drupal_add_js() 是沒有效果的

正確的做法是 form 的 preprocess 或者使用 form API 的 #attach:

<?php
$form
['#attached']['css'] = array(
 
drupal_get_path('module', 'ajax_example') . '/ajax_example.css',
);

$form['#attached']['js'] = array(
 
drupal_get_path('module', 'ajax_example') . '/ajax_example.js',
);
?>

Attach external js, key 是 URL, value 是 array:

<?php
$form
['#attached']['js'] = array(
 
'//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js' => array('type' => 'external'),
);
?>

ref:
http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.ht...

Drupal7 AJAX 提交表單 submit form

Drupal7 原生已經提供一大堆 AJAX 的 API 可以使用
令一些基本的 AJAX 工作變得很簡單,例如

<?php
$form
['howmany_select'] = array(
   
'#title' => t('How many checkboxes do you want?'),
   
'#type' => 'select',
   
'#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4),
   
'#default_value' => $default,
   
'#ajax' => array(
     
'callback' => 'ajax_example_autocheckboxes_callback',
     
'wrapper' => 'checkboxes-div',
     
'method' => 'replace',
     
'effect' => 'fade',
    ),
?>

直接入建到 $form 之內
開發人員也不需要自己手動處理 javascript 的問題
只要提供一個正確的 wrapper ID,正確的 method 便可以了

而最重要的 AJAX 提交卻不在文檔之中
而要參考 example module 的例子:

<?php
$form
['submit']['#ajax'] = array(
 
'callback' => 'ajax_example_autocheckboxes_callback',
 
'wrapper' => 'checkboxes-div',
 
'method' => 'append',   
);
?>

直接將 AJAX 加到 submit button 的陣列之中
而最有用的是 method => append
AJAX submit 完成之後常見的動作是加一個成功的訊息
或者轉到一個感謝的頁面

加一個成功的訊息可以使用 method => append
轉到一個感謝的頁面便應該使用 replace,replace 整個wrapper 為感謝頁面

參考
AJAX in Drupal7
Example module

Drupal7 Javascript, once()

once() 是我碰到 ajax submit 的時候第一次使用到
它是一個已經內建到 Drupal 的一個 jQuery 插件
令一個 event 不會 bind 兩次

原意是一條連結觸發 ajax
我bind 了 click event 到增加一個 loading 的 gif
取代 (replaceWith) 的方式將一個 form 更換
因為 replaceWith 之後都會再一次執行 javascript
下一次解發連結便會有兩個 loading gif
可以使用 once() 解決:

$('.views-field-edit-node a').once().click(function(){
  $(this).after('<div class="ajax-progress ajax-progress-throbber"><div class="throbber">&nbsp;</div></div>');
  $.ajax({
    //..
  });
});

ref:
http://drupal.org/node/756722
http://archive.plugins.jquery.com/project/once

Drupal 培訓 Training

提供基本的使用者培訓
學習使用簡易的伺服器
安裝 Drupal,下載,安裝第三方模組
使用 Views,CCK,Rules 等大型模組
建立一個基本的網站

也提供開發者的專業 Drupal 模組開發培訓
Drupal 版型,hooks,APIs
使用 git,提交 patch 等進階使用技巧

立即到 DocuemtnOnReady 聯絡我們!

Drupal 7 theming a node form

我慢慢發現 content type node form 是繼 exposed views form 之後最常要修改的 form
(我明明有寫過 alter exposed views form, 但找不到...)

特定 content type 本身是沒有 theme function 的
先定義一個,順便定義使用一個 tpl 檔輸出

<?php
/**
 * Implements hook_theme().
 */
function MYMODULE_theme($existing, $type, $theme, $path) {

  return array(
   
'article_node_form' => array(
     
'render element' => 'form',
     
'template' => 'article-node-form',
     
// this will set to module/theme path by default:
     
'path' => drupal_get_path('module', 'MYMODULE'),
    ),
  );
}
?>

接著便可以使用 preprocess 加入其他需要的 variables

<?php
/**
 * Preprocessor for theme('article_node_form').
 */
function template_preprocess_article_node_form(&$variables) {

 
// nodeformcols is an alternative for this solution.
 
if (!module_exists('nodeformcols')) {

   
$variables['sidebar'] = array();   // Put taxonomy fields in sidebar.

   
$variables['sidebar'][] = $variables['form']['field_tags'];
   
hide($variables['form']['field_tags']);

   
// Extract the form buttons, and put them in independent variable.
   
$variables['buttons'] = $variables['form']['actions'];
   
hide($variables['form']['actions']);
  }
}
?>

模組資料夾內的 article.tpl.php: (當然可以修改成你需要的樣子)

<?php echo drupal_render_children($form)?>

參考 http://drupal.org/node/1092122

Pages

Google