Sử dụng Javascript và AJAX/JSON

Một phần của tài liệu phát triển ứng dụng dịch vụ hướng vị trí trên nền drupal (Trang 35)

2.6.1 Giới thiệu về jQuery

jQuery là một trong số các thư viện JavaScript mạnh mẽ hiện nay. Sử dụng một mô hình thiết kế hướng đối tượng là Fluent Interface, jQuery cho phép liên kết một chuỗi các lời gọi hàm với nhau để tạo nên các truy vấn phức tạp.

Thông thường, jQuery truy vấn tới cây DOM. Một cây DOM (Document Object Model) là một cấu trúc dữ liệu định nghĩa nên cấu trúc của một văn bản, thường là HTML hoặc XML. Văn bản này sẽ được biểu diễn dưới dạng cây với thành phần đầu tiên là gốc. DOM được biết đến là một mô hình đối tượng phức tạp. jQuery cung cấp một API nhẹ hơn và dễ sử dụng hơn cho người lập trình.

Tuy nhiên, jQuery được sử dụng trong nhiều trường hợp, không chỉ riêng truy vấn. Nó có một bộ công cụ AJAX, công cụ xử lý sự kiện, hiệu ứng ảo và một số hàm tiện ích khác.

Thông tin thêm về jQuery có tại địa chỉ http://jquery.com

2.6.2 jQuery hoạt động như thế nào

Trong phần này, chúng tôi sẽ tìm hiểu cách jQuery tìm kiếm trong một văn bản có cấu trúc bằng cách sử dụng CSS và XPath. CSS được sử dụng cho một văn bản HTML hoặc XHTML. XPath sử dụng trong văn bản XML. Thay cho việc tạo các cú pháp để tìm kiếm trong JavaScript, jQuery triển khai cú pháp truy vấn sẵn có của CSS và XPath, giúp cho người phát triển không phải nhớ các ngôn ngữ khác nhau.

2.6.2.1 Sử dụng bộ lọc ID của CSS

Giả sử đoạn mã HTML cần thao tác là :

<p id="#intro">Welcome to the World of Widgets</p>

Nếu muốn đặt màu sắc cho nền của đoạn trong thẻ <p></p>, chúng ta sẽ sử dụng CSS để xác định đoạn văn bản thông qua ID #intro. ID này không được trùng với các ID khác trong cùng một trang.

#intro {

background-color: blue; }

Việc này có thể được thử hiện bằng cách sử dụng jQuery như sau:

// Định nghĩa biến jQuery như một hàm. var jQuery = function(a,c) {...}

// Ánh xạ không gian tên jQuery đến ký hiệu “$” var $ = jQuery;

$("#intro").css("background-color", "blue");

Trong trường hợp sử dụng lớp CSS, đoạn mã jQuery sẽ là:

$(".intro").css("background-color", "blue").fadeIn("slow");

jQuery cũng có thể thực hiện một số hiệu ứng lên trang web, ví dụ:

$("#intro").css("background-color", "blue").fadeIn("slow");

hoặc:

$("p.intro").css("background-color", "blue").fadeIn("slow");

2.6.2.2 Sử dụng XPath

Nếu một thành phần của trang HTML không được đánh dấu bằng ID hoặc bộ lọc lớp, cách truy vấn trên sẽ không thực hiện được. Lúc đó, XPath là một giải pháp tốt để thay thế. XPath có phần linh hoạt hơn trong việc tạo các quy tắc để xác định thành phần trong HTML. Ngoài ra, XPath còn hỗ trợ sử dụng biểu thức chính quy.

Ví dụ:

- Tìm các thẻ có thuộc tính target là _blank:

$(“a[@target=_blank]”)

- Tìm các checkbox trong form:

Chi tiết về các biểu thức sử dụng trong XPath có thể xem thêm tại địa chỉ

http://docs.jquery.com/DOM/Traversing/Selectors (adsbygoogle = window.adsbygoogle || []).push({});

2.6.3 jQuery trong Drupal

Mặc định, jQuery sẽ được cài đặt cùng với Drupal, vì thế việc sử dụng là khá dễ dàng. Mã nguồn của jQuery được chứa trong file jquery.js nằm trong thư mục misc. File này sẽ được nạp khi có lời gọi hàm drupal_add_js(). Hàm này có nhiệm vụ nhận mã JavaScript và thêm vào mã nguồn trang web. Ví dụ:

<?php drupal_add_js( '$(document).ready(function(){ $("p").fadeIn("slow"); });', 'inline' ); ?>

Tham số đầu tiên của hàm drupal_add_js() là đoạn mã JavaScript sẽ được thực thi. Tham số thứ hai (inline) cho biết Drupal sẽ ghi đoạn mã vào giữa hai thẻ

<script></script> ở trong thẻ <head> của trang HTML.

Tuy nhiên, để đảm bảo rằng module hoạt động đúng như mong đợi, chúng ta cần phải đảm bảo các truy vấn jQuery chỉ chạy khi trình duyệt hỗ trợ JavaScript và AJAX. Nếu trình duyệt không hỗ trợ, các thay đổi đối với HTML phía máy khách sẽ không được thực hiện. Thư viện JavaScript của Drupal có hàm Drupal.jsEnabled() sẽ kiểm tra điều kiện này.

if(Drupal.jsEnabled) { // code goes here }

Giá trị trả về của hàm này là TRUE hoặc FALSE tương ứng với kết quả kiểm tra.

2.7 Form API

Từ phiên bản 4.7 trở về sau, Drupal cung cấp một API hỗ trợ việc tạo, xác thực và xử lý form trong HTML. API này biểu diễn các form bằng một mảng chứa các thuộc tính và giá trị. Một số ưu điểm của bộ máy này:

• Dễ sử dụng.

• Không cần phải viết mã HTML mà chỉ cần khai báo các thuộc tính và giá trị của form.

• Dễ dàng thêm, xoá, đảo thứ tự và thay đổi các form. Điều này thuận tiện khi muốn chỉnh sửa một form được tạo bởi module khác.

• Mỗi thành phần trong một form có thể được liên kết với một hàm giao diện riêng.

• Có thể thêm các bước xác thực và xử lý riêng cho từng form.

• Các thao tác liên quan được bảo vệ tránh việc tấn công bằng cách thực hiện những thay đổi ảnh hưởng xấu đến hệ thống.

Trong phần này, chúng tôi sẽ tìm hiểu về Form API và ứng dụng vào một số ví dụ cụ thể.

2.7.1 Quá trình thao tác với form

Biều đồ dưới đây mô tả quá trình xây dựng, kiểm tra tính hợp lệ và trình bày form.

Để có thể sử dụng Form API một cách hiệu quả, người phát triển phải biết được cách mà bộ máy phía sau API hoạt động.

Các bước trong quá trình xử lý:

• Khởi tạo: hàm drupal_get_form() bắt đầu bằng việc khởi tạo giá trị

$form_values (mảng chứa các giá trị được gửi lên) bằng rỗng và

$form_submitted bằng FALSE.

• Đặt một token: Drupal đặt giá trị khoá riêng cho mỗi bản cài đặt. Khi khoá được tạo ra sẽ được lưu trong bảng variables với trường drupal_private_key. Một token giả ngẫu nhiên dựa vào khoá này để kiểm tra một form khi được gửi lên. • Đặt ID: Một trường thông tin dạng ẩn chứa ID của form hiện tại sẽ được gửi đến

trình duyệt. Mỗi ID thường tương ứng với hàm định nghĩa của form và là tham số đầu tiên của drupal_get_form().

• Tập hợp thông tin các thành phần của form: Hàm element_info() sẽ được gọi. Hàm này sẽ thực thi hook_elements() trong tất cả các module có bản triển khai. Các thành phần cơ bản như nút checkbox, radio... được định nghĩa trong

system.module. Một module cũng có thể tự định nghĩa kiểu thành phần riêng bằng cách sử dụng hook_elements().

• Tìm kiếm hàm kiếm tra giá trị: Một hàm kiểm tra giá trị có thể được gán bằng cách đặt thuộc tính #validate trong form vào một mảng với tên hàm là khoá và mảng khác làm giá trị.

• Tìm kiếm hàm gửi form: Hệ thống sẽ tìm kiếm những hàm có thuộc tính #submit (adsbygoogle = window.adsbygoogle || []).push({});

và thực thi. Nếu không tìm thấy, Drupal thực thi hàm có ID plus_submit nếu có.

• Xây dựng form: Tại bước này, form sẽ được chuyển sang hàm form_builder()

để xử lý thông qua một cây đệ quy và thêm các giá trị bắt buộc theo chuẩn. • Tìm hàm chuyển đổi giao diện cho form: Nếu giá trị $form[‘#theme’] được đặt

trong một hàm, Drupal sẽ sử dụng hàm đó. Nếu không, hàm

theme_get_function() sẽ được gọi để xác định nếu có hàm giao diện cho form hiện tại.

• Thể hiện form trong HTML: Bộ xây dựng form sẽ gọi hàm drupal_render().

Đây là một hàm đệ quy, duyệt qua mỗi cấp của cây biểu diễn form và xử lý từng node. Với mỗi node, hàm drupal_render() sẽ phân tích thông tin của các thành phần có trong form và tạo ra mã HTML.

2.7.2 Một số thao tác cơ bản

2.7.2.1 Tạo form

Các thành phần của một form được khai báo trong một mảng có cấu trúc phân cấp và có thể ghép lồng nhau. Mỗi thành phần gồm có các cặp thuộc tính/giá trị. Ví dụ sau định nghĩa một thành phần textfield:

<?php $form['foo'] = array( '#type' => 'textfield', '#title' => t('bar'), '#default_value' => $object['foo'], '#size' => 60, '#maxlength' => 64, '#description' => t('baz'), ); ?>

Tạo một nút bấm gửi dữ liệu: <?php $form['submit'] = array( '#type' => 'submit', '#value' => t('Save'), ); ?>

Một vài điểm lưu ý:

• Thuộc tính name của thành phần được khai báo trong mảng $form và nằm ở cuối mảng. Ví dụ:

$form['account_settings']['username']

• Kiểu của thành phần form được khai báo qua thuộc tính #type.

• Các khoá thuộc tính được khai báo trong dấu [], giá trị của khoá có kiểu xâu.

• Thứ tự khai báo các thuộc tính không quan trọng. Một số thuộc tính có giá trị mặc định.

• Không nên sử dụng thuộc tính #valuecho các thành phần có thể được thay đổi bởi người dùng, thay vào đó, nên sử dụng thuộc tính #default_value.

2.7.2.2 Giao diện hoá form

Form API cho phép tuỳ chỉnh giao diện đối với từng form, thậm chí đối với riêng từng thành phần trong một form. Việc tuỳ chỉnh được thực hiện bằng cách nạp chồng các thành phần giao diện tại thời điểm tạo form:

• Thêm thuộc tính #theme vào form chính hoặc các thành phần, cho phép chỉ định hàm giao diện nào sẽ được áp dụng.

• Chèn thẻ đánh dấu trực tiếp vào form như một thành phần của form đó. Các thẻ đánh dấu có thể là #prefix, #suffix hoặc #markup. Thẻ này dùng để chỉ định vị trí các đoạn mã thiết lập giao diện trong form. Ví dụ:

$form['access'] = array( '#type' => 'fieldset',

'#title' => t('Access log settings'), '#prefix' => '<div class="foo">', '#suffix' => '</div>',

);

• Ghép các đoạn mã của từng thành phần trong form để hiển thị ra trang web. Ở bước này, hàm drupal_render() sẽ được gọi.

2.7.2.3 Kiểm tra dữ liệu

Form API có bước kiểm tra dữ liệu vào, thực hiện trên tất cả các form được gửi lên. Ngoài các hàm có sẵn, người phát triển cũng có thể tự tạo các hàm kiểm tra theo ý muốn. Tên hàm phải được đặt theo quy tắc <formID>_validate. Hàm này nhận hai tham số: $form và $form_state. $form là mảng chứa khai báo của form.

$form_state[‘values’] chứa giá trị cần kiểm tra. Ví dụ: (adsbygoogle = window.adsbygoogle || []).push({});

function test_form_validate($form, &$form_state) { if ($form_state['values']['name'] == '') {

form_set_error('', t('You must select a name.'));

}

2.7.2.4 Gửi form lên trang web

Cách thức thông thường được sử dụng để gửi form lên là thông qua hàm. Một form được gửi lên bằng nút bấm có thuộc tính type =&gt; 'submit' sẽ được truyền tới hàm tương ứng. Ví dụ:

function test_form_submit($form, &$form_state) {

db_query("INSERT INTO {table} (name, log, hidden) VALUES ('%s', %d, '%s')", $form_state['values']['name'],

$form_state['values']['access']['log'], $form_state['values']['hidden']);

drupal_set_message(t('Your form has been saved.')); }

Hàm gửi dữ liệu chỉ được gọi khi nhận lệnh từ nút bấm submit có phương thức POST và dữ liệu được kiểm tra hợp lệ.

2.8 Làm việc với cơ sở dữ liệu

Phần này sẽ giới thiệu sơ lược về cách kết nối và truy vấn CSDL trong Drupal.

2.8.1 Định nghĩa các tham số trong CSDL

Drupal xác định được CSDL, tài khoản và mật khẩu của người dùng khi thiết lập kết nối bằng cách phân tích file settings.php. nằm trong thư mục sites/default. Dòng thông tin định nghĩa kết nối tới CSDL có dạng:

$db_url = 'mysql://username:password@localhost/databasename';

Phương thức định nghĩa kết nối là mysql hoặc pgsql phụ thuộc vào CSDL được sử dụng là MySQL hay PostgreSQL.

Dựa vào đó, Drupal xác định file thiết lập CSDL sẽ tham chiếu tới và khởi động CSDL tương ứng. Quá trình này được minh hoạ bởi hình dưới đây:

Hình 2.8.1. Quá trình thao tác với CSDL.

Một đoạn mã bên ngoài muốn truy cập vào CSDL của Drupal sẽ phải gọi

include_once(‘includes/bootstrap.inc’) sau đó gọi

drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE) để tạo kết nối, sau đó thực hiện truy vấn bằng hàm db_query().

2.8.2 Một số truy vấn đơn giản

Drupal cung cấp hàm db_query() để thực thi một truy vấn tới kết nối đang hoạt động. Những truy vấn được hỗ trợ bao gồm SELECT, INSERT, UPDATE và DELETE. Dưới đây là một số ví dụ.

Lấy tất cả các hàng của một trường từ bảng joke có vid là số nguyên, có giá trị bằng $node->vid:

db_query('SELECT * FROM {joke} WHERE vid = %d', $node->vid);

Chèn một hàng mới vào bảng joke. Hàng mới chứa 2 giá trị nguyên và một xâu ký tự:

db_query("INSERT INTO {joke} (nid, vid, punchline) VALUES (%d, %d, '%s')",$node->nid, $node->vid, $node->punchline);

Cập nhật tất cả các hàng trong bảng joke có trường vid là số nguyên có giá trị bằng $node->vid. Các hàng thoả mãn điều kiện này sẽ thay đổi bằng cách đặt trường punchline bằng giá trị của xâu chứa trong $node->punchline:

db_query("UPDATE {joke} SET punchline = '%s' WHERE vid = %d", $node->punchline,$node->vid);

Xoá các hàng trong bảng joke có cột nid chứa giá trị nguyên bằng với $node- >nid: (adsbygoogle = window.adsbygoogle || []).push({});

db_query('DELETE FROM {joke} WHERE nid = %d', $node->nid);

Drupal đặt ra một số quy tắc về cú pháp trong phát biểu SQL. Đầu tiên, tên bảng phải được đặt trong dấu {}. Quy ước này cho phép những người dùng bị giới hạn số lượng CSDL tạo ra có thể cài đặt Drupal trong một CSDL có sẵn mà không bị xung đột.

Tiếp theo là cờ giữ chỗ trong truy vấn. Ở ví dụ trên, %d sẽ tự động được thay thế bằng giá trị $node->nid tương ứng. Dưới đây là bảng ký hiệu giữ chỗ và kiểu dữ liệu thay thế:

Hình 2.8.2. Bảng ký hiệu giữ chỗ trong truy vấn CSDL.

2.8.3 Lấy kết quả truy vấn

Có nhiều cách khác nhau để lấy kết quả truy vấn.

Lấy một giá trị: Nếu muốn kết quả trả về chỉ một giá trị thì có thể sử dụng hàm

$sql = "SELECT COUNT(*) FROM {node} WHERE type = 'blog' AND status = 1";

$total = db_result(db_query($sql));

Trả về nhiều hàng: Với kết quả là một tập gồm nhiều hàm, hàm

db_fetch_object() giúp chọn ra từng hàng để xử lý.

$sql = "SELECT * FROM {node} WHERE type = 'blog' AND status = 1"; $result = db_query(db_rewrite_sql($sql));

while ($data = db_fetch_object($result)) { //code goes here

}

Để nhận được kết quả là một mảng, chúng ta có thể sử dụng hàm

db_fetch_array() thay cho db_fetch_object().

Giới hạn phạm vi kết quả: Với những truy vấn cho ra rất nhiều hàng, có thể giới hạn phạm số lượng như sau:

$sql = "SELECT * FROM {node} n WHERE type = 'blog' AND status = 1 ORDER BY n.created DESC";

$result = db_query_range(db_rewrite_sql($sql), 0, 10);

Trong trường hợp này, hàm db_query_range() được sử dụng thay cho điều kiện

Chương 3: Xây dựng module tích hợp Google Maps vào Drupal

Với lý thuyết đã nêu ra ở những phần trên của khoá luận, chúng tôi sẽ ứng dụng vào thực tế bằng cách xây dựng một module cho Drupal. Module này có tên là Google Maps, có chức năng hiển thị bản đồ trên trang web.

Trước hết, chúng tôi sẽ giới thiệu sơ lược về dịch vụ Google Maps.

3.1 Giới thiệu về Google Maps

Google Maps (trước đây được gọi là Google Local) là một ứng dụng dịch vụ bản đồ web và công nghệ miễn phí được cung cấp bởi Google, có thể dùng để nhúng vào các trang web của bên thứ ba thông qua Google Maps API. Nó cho phép hiển thị bản đồ đường xá, đường đi cho xe đạp, cho người đi bộ hoặc xe hơi, và những địa điểm kinh doanh trong khu vực cũng như khắp nơi trên thế giới. (Theo wikipedia.org)

Địa chỉ chính thức của Google Maps: http://maps.google.com.

Google Maps cung cấp các cách thể hiện bản đồ khác nhau gồm có bản đồ ranh giới, bản đồ vệ tinh và bản đồ dạng 3 chiều. Giao diện của chương trình rất thân thiện với người dùng.

3.2 Nhúng bản đồ vào trang web

Việc nhúng bản đồ vào trang web được thực hiện Google Maps API. Người dùng không cần phải tìm kiếm và quản lý dữ liệu hay thiết lập máy chủ mà chỉ cần viết một ít đoạn mã JavaScript.

Với mỗi người phát triển, Google cung cấp một khoá API riêng. Khoá này có thể đăng ký miễn phí tại http://code.google.com/apis/maps/signup.html. (adsbygoogle = window.adsbygoogle || []).push({});

Mỗi khi muốn nhúng bản đồ của Google vào trang web, trong thẻ <head> phải khai báo chèn file JavaScript:

<script src=http://maps.google.com/maps?file=api&v=2&key=xyz type="text/javascript"></script>

Trong đó, xyz được thay bằng khoá API. Lúc này, trang web có thể sử dụng các hàm và đối tượng được cung cấp trong API của Google Maps.

3.2.1 Tạo một bản đồ đơn giản

Thông thường, việc nhúng bản đồ trên một trang web được thực hiện bằng cách sử dụng một thẻ <div> giữ chỗ và dùng JavaScript hiển thị bản đồ vào vị trí đó. Ví dụ:

<div id="map" style="width: 500px; height: 400px"></div> <script type="text/javascript">

var map = new GMap2(document.getElementById("map")); //zoom levels 0-17+, 0 == world

map.setCenter(new GLatLng(39.754286, -104.994637), 16); </script>

Ví dụ trên sẽ cho kết quả như sau:

Hình 3.2.1. Minh họa trang web tích hợp bản đồ Google Maps.

Phần bản đồ hiển thị được gán vào đối tượng map dựa vào toạ độ của điểm trung tâm.

Tài liệu chi tiết về các dịch vụ của Google Maps API cũng như tính năng cao cấp

Một phần của tài liệu phát triển ứng dụng dịch vụ hướng vị trí trên nền drupal (Trang 35)