Drupal7.x javascript function after ajax - ajax invoke

初探 Drupal 中使用 ajax 之後
使想在 AJAX complete 之後執行一些自定義的 javascript

例如ajax form submit 之後 slideUp form
submit 之後需要修改某些內容

使用的是 ajax callback 的command, 加上 ajax_command_invoke
Form array:

<?php
  $form
['actions']['submit']['#ajax'] = array(
   
'callback' => 'example_callback',
   
'wrapper' => 'field-wrapper',
   
'method' => 'append',
   
'effect' => 'slide',
  );
?>

callback:

<?php
function example_callback($form, $form_state) {
 
$commands = array();
 
$commands[] = ajax_command_prepend(NULL, theme('status_messages'));
 
$commands[] = ajax_command_invoke('.field-form', 'slideUp', array(2000));
  return array(
'#type' => 'ajax', '#commands' => $commands);
}
?>

ajax_command_invoke 可以對 selector 執行一個函數
第三個參數是一個 array, 是傳給函數的參數

ref:
http://api.drupal.org/api/drupal/includes%21ajax.inc/group/ajax/7
http://api.drupal.org/api/drupal/includes%21ajax.inc/function/ajax_comma...

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 聯絡我們!

Pages

Google