Những điểm cần biết về Javascript trong Drupal 7

Bản Drupal 7 được đội ngũ code giải quyết nhiều vấn đề về Javascript mà các bản trước đó đã gặp phải. Chúng ta nên biết những điểm này để tiện cho việc nâng cấp các module của mình lên cho bản Drupal 7 khi bản này chính thức ra mắt. Dưới đây là các vấn đề đã được giải quyết trong bản Drupal 7 mà chúng ta nên biết.

Dùng jQuery với các bộ thư viện khác:

Mặc định trong các phiên bản trước Drupal dùng cách viết shorthand của jQuery là $ và các bộ thư viện khác cũng dùng chung cách viết này do đó sẽ bị lỗi khi ta sử dụng chung với các thư viện khác.

$(document).ready(function () {
//...
});

Từ bản Drupal 7 trở đi các file được viết lại bằng cách sử dụng jQuery chứ không dùng shorthand là $ nữa. Và khi muốn sử dụng dấu $ thì ta chỉ việc bỏ vào trong một anomynous function như sau:
(function ($) {
// .... Dùng dấu $ ở đây thoải mái mà không sợ bị đụng các thư viện khác
})(jQuery);

Không đủ flexibility để thêm các đoạn javascript theo ý muốn

Ở các bản Drupal trước chúng ta không thể thay đổi thứ tự của các file javascript, không thể đưa vào một file javascript từ một trang web khác (Ví dụ như Google CDN, Microsoft CDN...). Ở Drupal 6 khi cần thêm một file javascript chúng ta sử dụng như sau:

<?php
drupal_add_js
('path/to/some_js_file.js', 'module', 'header');
?>

Ở Drupal 7 hàm drupal_add_js đã được chỉnh sửa và định nghĩa ra các mức độ quan trọng của một file javascript hay một đoạn mã javascript nào đó. Cụ thể hơn có các cấp sau:

  • JS_LIBRARY: Một thư viện bất kỳ, cấu hình, hoặc là jQuery plugin
  • JS_DEFAULT: Một file javascript của một module
  • JS_THEME: Một file javascript của một theme

Ví dụ:

<?php
drupal_add_js
('jQuery(document).ready(function () {
  alert("Hello!");
});'
, array(
 
'type' => 'inline',
 
'scope' => 'footer',
 
'weight' => 5
));
?>

Ngoài ra còn cho phép chúng ta đưa vào một file javascript từ một trang web khác. Ví dụ:

<?php
drupal_add_js
('<a href="http://example.com/example.js'">http://example.com/example.js'</a>, 'external');
?>

Cập nhật phiên bản cho các file javascript

Ở các bản Drupal trước có thể xảy ra trường hợp bản javascript được phân phối cùng với mã nguồn của Drupal sẽ bị cũ đi vì thư viện javascript đó đã được nâng cấp lên phiên bản mới hơn. Chúng ta có thể giải quyết bằng module jQuery Update nếu như chỉ cần nâng cấp bộ thư viện jQuery đi kèm.
Bản Drupal 7 cho phép chúng ta thay thế các file javascript được phân phối trong core bằng phiên bản mới hơn do chúng ta định nghĩa bằng một hook mới là: hook_js_alter. Ví dụ:

<?php
function hook_js_alter(&$javascripts) {
 
$javascripts['misc/jquery.js']['data'] = drupal_get_path('module', 'jquery_update') . '/jquery.js');
}
?>

Renderable arrays và #attached js:

Ví dụ:

<?php
function render_my_content() {
 
$build['myelement'] = array(
    
'#theme' => 'my_theme_function',
    
'#myvar' => $myvar,
    
'#attached' => array(
     
'js' => drupal_get_path('module', 'mymodule') . '/myjs.js',
     
'css' => drupal_get_path('module', 'mymodule') . '/ styles.css'
    
),
  );
 
$output = drupal_render($build);
  return
$output;
}
?>

Thêm vào các bộ thư viện như jQuery plugin

Ở các bản Drupal trước không có cách nào để cùng đưa các file javascipt cùng các file css vào chung mà phải đưa từng thành phần riêng lẻ. Khi ta muốn thêm vào một jQuery plugin thì phải làm lần lượt từng file trong plugin đó.
Bản Drupal 7 định nghĩa ra một hook mới là: hook_library. Ví dụ:

<?php
function system_library() {
 
$libraries['vertical-tabs'] = array(
   
'title' => 'Vertical Tabs',
   
'website' => '<a href="http://drupal.org/node/323122',
">http://drupal.org/node/323122',
</a>    'version' => '1.0',
    'js' => array(
      'misc/vertical-tabs.js' => array(),
    ),
    'css' => array(
      'misc/vertical-tabs.css' => array(),
    ),
  );
  // ...
  return $libraries;
}
?>

<?php
function mymodule_library() {
 
$libraries['mylibrary'] = array(
   
'title' => 'Theme builder',
   
'website' => '<a href="http://asaleo.com',
">http://asaleo.com',
</a>    'version' => '1.0 pre-alpha1',
    'js' => array(
      // có thể dùng mảng sau để đưa vào Drupal.settings, dùng đường dẫn tới file theo cách ở trên nếu muốn đưa vào file
      array(
        'type' => 'setting',
        'data' => array('mylibrary' => TRUE),
      ),
    ),
    'dependencies' => array(
      // cần có thư viện jQuery UI trong module System
      array('system', 'ui'),
      // Một bộ thư viện nào đó
      array('other-module', 'library-1'),
    ),
  );
  return $libraries;
}
?>

Ngoài ra còn có hàm drupal_add_library cho việc làm theme:
<?php
function theme_vertical_tabs($variables) {
 
$element = $variables['element'];
 
drupal_add_library('system', 'vertical-tabs');
  return
'<div class="vertical-tabs-panes">' . $element['#children'] . '</div>';
}
?>

Thay thế AHAH bằng AJAX

Thử coi việc xây dụng một form AHAH trên Drupal 6:

<?php
function quicktabs_ahah() {
 
$form_state = array(
   
'storage' => NULL,
   
'submitted' => FALSE
 
);
 
$form_build_id = $_POST['form_build_id'];
 
$form = form_get_cache($form_build_id, $form_state);
 
$args = $form['#parameters'];
 
$form_id = array_shift($args);
 
$form['#post'] = $_POST;
 
$form['#redirect'] = FALSE;
 
$form['#programmed'] = FALSE;
 
$form_state['post'] = $_POST;
 
drupal_process_form($form_id, $form, $form_state);
 
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
 
$qt_form = $form['qt_wrapper']['tabs'];
  unset(
$qt_form['#prefix'], $qt_form['#suffix']); // Prevent duplicate wrappers.
 
$javascript = drupal_add_js(NULL, NULL, 'header');
 
drupal_json(array(
   
'status'   => TRUE,
   
'data'     => theme('status_messages') . drupal_render($qt_form),
   
'settings' => call_user_func_array('array_merge_recursive', $javascript['setting']),
  ));
}
?>

Và AHAH đã được thay thế bằng AJAX ở Drupal 7:
<?php
function quicktabs_ajax($form, $form_state) {
 
$form_tabs = $form['qt_wrapper']['tabs'];
 
$output = drupal_render($form_tabs);
  return
$output;
}
?>

Từ bản Drupal 7 AJAX đã được xây dựng lại thành một framework do vậy ta xem cách tạo ra 1 form như trên không còn quá phức tạp nữa.

Đưa jQuery UI vào Core:

Các thành phần sau của jQuery UI được đưa vào trong Core:

  • accordion
  • datepicker
  • dialog
  • draggable
  • droppable
  • progressbar
  • resizable
  • selectable
  • sortable
  • tabs

Hiệu ứng:

  • bounce
  • explode
  • fold
  • pulsate

Ví dụ:

<?php
function render_accordion_block() {
 
$build['myelement'] = array(
   
'#theme' => 'my_accordion',
  );
 
$build['myelement']['#attached']['library'][] = array('system', 'ui.accordion');
 
$build['myelement'][['#attched']['js'][] = array('data' => '(function($) { $("#accordion").accordion();})(jQuery);', 'type' => 'inline';
 
$output = drupal_render($build);
  return
$output;
}
?>

Còn cần cập nhật:

  • Drupal AJAX framework
  • Drupal.behaviors giờ có hàn khởi tạo và hủy
  • drupal_to_js giờ thành drupal_json_encode
  • drupal_json giờ thành drupal_json_output
  • Dùng jQuery.once() để tạo các sự kiện.

Categogy: 

Tags: 

16 Comments

Nguyễn Tuấn Dũng's picture

Cho mình hỏi là mình bật

Cho mình hỏi là mình bật Input format = plain text thì được nhưng từ full HTML thì không được.Bác có cách gì bật được trong FULL HTML không ạ.Vì tiện trong việc soạn thảo.
Thanks

Nguyễn Tuấn Dũng's picture

Mình bật trong Filtered HTML

Mình bật trong Filtered HTML rồi.Nhưng khi đánh adsdsa thì nó hiện y nguyên ra ngoài bài viết.Mình dùng FCKeditor.Mình mới học nên rất muốn sự giúp đỡ của bạn

Nguyễn Tuấn Dũng's picture

Thêm một vấn đề nữa là.Nếu em

Thêm một vấn đề nữa là.Nếu em disable richtext đánh vào thì được.Enable Richtext thì đoạn code biến mất.Code ra màn hình xuất đúng ra <?php $a = 4;?> .Nhưng khi vào edit lại thì lại hiện ra .Thật sự em vẫn chưa hiểu a.Em đang dùng bản 7

Add new comment