Nhựt (WordPress Developer)

Nhựt
2 năm trước

Sử dụng AJAX trong WordPress

Trước khi đến phần Sử dụng AJAX trong WordPress, chúng ta nên tìm hiểu qua Ajax là gì?Ajax hoạt động như thế nào?

Ajax là gì?

Thông thường, một trang web cần phải reload (tải lại trang), để hiển thị thông tin mới. Ajax ra đời để giải quyết vấn đề này, Ajax là một một nghệ dựa trên JavaScript cho phép một trang web tìm nạp thông tin mới và hiển thị mà không cần reload trang.

Ajax hoạt động như thế nào?

Về cơ bản, khi người dụng thực hiện một thao tác nào đó (nhấp vào nút, lăn chuột,…), chương trình JavaScript sẽ gửi yêu cầu đến một URL trên web server. Tiếp theo chương trình trên web server sẽ xử lý yêu cầu đó và phản hồi lại. Khi dữ liệu phản hồi được gửi đến trình duyệt, chương trình JavaScript sẽ nhận được thông báo asynchronous (bất đồng bộ) để nó có thể xử lý hoặc hiển thị lên giao diện người dùng mà không cần reload trang.

Ajax trong WordPress

Ajax đã được tích hợp sẳn trong WordPress, nên việc phát triển thêm nhiều chức năng liên quan đến Ajax khá đơn giản. Để sử dụng được Ajax trong WordPress chúng ta cần lưu ý một số vấn đề sau:

Tất cả các yêu cầu đều được gửi đến admin-ajax.php

admin_url( 'admin-ajax.php' )

Hai action thực thi là wp_ajax_*wp_ajax_nopriv_*:
wp_ajax_* dành cho người dùng đã đăng nhập, ví dụ:

add_action( 'wp_ajax_my_action', 'my_action' );

wp_ajax_nopriv_* dành cho người dùng chưa đăng nhập, ví dụ:

add_action( 'wp_ajax_nopriv_my_action', 'my_action' );

Sử dụng Ajax trong WordPress

Sau khi tìm hiểu cơ bản về Ajax trong WordPress, chúng ta đi đến ví dụ thực tế. Mình sẽ viết một chương trình gửi hai số AB đến cho WP Ajax xử lý (phép tính cộng) sau đó trả về giá trị và hiển thị lên giao diện.

HTML

Phần giao diện, là một form cho người dùng nhập số và tính. Bạn có thể viết ở các file template của theme ví dụ: index.php, single.php, page.php,… bạn muốn hiển thị ở đâu thì viết ở đó.

<form method="post" name="sandbox-form" id="sandbox-form">
    <p id="error-msg" class="mb-0"></p>
    <div id="simple-msg"></div>
    <div class="row">
        <div class="col-md-6">
            <div class="mb-3">
                <label for="number-a" class="form-label">Số A <span class="text-danger">*</span></label>
                <input name="number-a" id="number-a" type="number" class="form-control" placeholder="Số A">
            </div>
        </div>
        <div class="col-md-6">
            <div class="mb-3">
                <label for="number-b" class="form-label">Số B <span class="text-danger">*</span></label>
                <input name="number-b" id="number-b" type="number" class="form-control" placeholder="Số B">
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-12">
            <button type="submit" id="submit">Tính</button>
        </div>
    </div>
</form>
Ajax trong WordPress

Mình sử dụng Bootstrap để khỏi phải CSS, giao diện sẽ như thế này:

JavaScript

Tiếp theo là JavaScript, mình sẽ tạo file script.js trong theme/assets/js/script.js và nhúng vào WordPress bằng hàm wp_enqueue_script()action wp_enqueue_scripts.
Viết đoạn code bên dưới vào functions.php

add_action( 'wp_enqueue_scripts', 'enqueue_scripts' );
 
function enqueue_scripts() {
    wp_enqueue_script( 'script', get_theme_file_uri( '/assets/js/script.js' ), array( 'jquery' ), wp_get_theme()->get( 'Version' ), true );
}

Như đã giải thích bên trên, tất cả yêu cầu đều được gửi đến URL admin_url( 'admin-ajax.php' ), đây là một hàm PHP nên mình không thể viết trong JavaScript được. Đây củng chính là lý do một số người viết JavaScript trong PHP để có thể echo admin_url( 'admin-ajax.php' ) vào code JavaScript.

Mình có một giải pháp như sau, mình sẽ tạo một biến toàn cục ajax_url có giá trị là admin_url( 'admin-ajax.php' ) để JavaScript có thể sử dụng.
Bổ sung dòng code sau vào function enqueue_scripts()

wp_localize_script( 'script', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );

Vậy hoàn thiện sẽ là:

add_action( 'wp_enqueue_scripts', 'enqueue_scripts' );
 
function enqueue_scripts() {
    wp_enqueue_script( 'script', get_theme_file_uri( '/assets/js/script.js' ), array( 'jquery' ), wp_get_theme()->get( 'Version' ), true );
    wp_localize_script( 'script', 'ajax_object', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}

Giờ đây trong JavaScript bạn cứ gọi ajax_object.ajax_url là được.

Trong file script.js:

jQuery(function ($) {
    $('#sandbox-form').submit(function (e) {
        // Ngăn chặn form gửi dữ liệu, vì mình sẽ gửi bằng JavaScript
        // Nói cách khác là ngăn không cho reload trang khi bấm submit
        e.preventDefault();
 
        // Khai báo các biến
        let error_msg = $('#sandbox-form #error-msg');
        let button = $('#sandbox-form button[type=submit]');
        let number_a = $('#sandbox-form input[name=number-a]').val();
        let number_b = $('#sandbox-form input[name=number-b]').val();
 
        // Reset thông báo
        error_msg.html('');
 
        // Hiển thị thông báo khi người dùng không nhập số
        if (number_a === "" || number_a == null || number_b === "" || number_b == null) {
            error_msg.html("<div class='alert alert-danger'>Vui lòng nhập số</div>");
            return false;
        }
 
        // Bắt đầu sử dụng Ajax
        $.ajax({
            type: "post", // Phương thức truyền dữ liệu post hoặc get
            dataType: "json", // Kiểu dữ liệu trả về xml, json, script, hoặc html
            url: ajax_object.ajax_url, // URL xử lý, đã giải thích bên trên
            data: {
                action: "calculator", // Tên action
                number_a: number_a, // Biến $_POST['number_a']
                number_b: number_b, // Biến $_POST['number_b']
            },
            beforeSend: function () {
                // Trước khi gửi dữ liệu
                button.attr('disabled', 'disabled');
                button.html('<span class="spinner-grow spinner-grow-sm" role="status" aria-hidden="true"></span> Đang tính...');
            },
            success: function (response) {
                // Nhận dữ liệu trả về và xử lý
                button.removeAttr('disabled');
                button.html('Tính');
                if (response.success) {
                    error_msg.html("<div class='alert alert-success'>Kết quả là: " + response.data + "</div>");
                }else{
                    error_msg.html("<div class='alert alert-danger'>Đã có lỗi xảy ra</div>");
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
                // Lỗi
                error_msg.html("<div class='alert alert-danger'>Đã có lỗi xảy ra, vui lòng thử lại</div>");
                button.removeAttr('disabled', 'disabled');
                button.html('Tính');
                console.log('The following error occured: ' + textStatus, errorThrown);
            }
        });
        return false;
    });
});

PHP

Tiếp theo mình sẽ xử lý dữ liệu nhận được bằng PHP thông qua hai actionwp_ajax_*wp_ajax_nopriv_*.

add_action( 'wp_ajax_calculator', 'calculator' ); // dành cho người dùng đã đăng nhập
add_action( 'wp_ajax_nopriv_calculator', 'calculator' ); // dành cho người dùng chưa đăng nhập
 
function calculator() {
    // Nhận dữ liệu từ JavaScript gửi lên
    $number_a = isset( $_POST['number_a'] ) ? esc_attr( $_POST['number_a'] ) : '';
    $number_b = isset( $_POST['number_b'] ) ? esc_attr( $_POST['number_b'] ) : '';
 
    // Kiểm tra dữ liệu đầu vào
    if ( $number_a === '' || $number_b === '' ):
        // Trả về lỗi
        wp_send_json_error( 'Lỗi: không đủ dữ liệu để tính toán!' );
    else:
        // Trả về kết quả tính toán
        wp_send_json_success( $number_a + $number_b );
    endif;
 
    wp_die(); // Đây là bắt buộc khi kết thúc chương trình
}

Giải thích:

  • Trong JavaScript mình đặt tên action là calculator vậy hai action của mình sẽ là wp_ajax_calculatorwp_ajax_nopriv_calculator.
  • Trong JavaScript mình đặt kiểu dữ liệu trả về là json (dataType: "json") nên mình sử dụng hàm wp_send_json_error()wp_send_json_success() để trả về lỗi hoặc kết quả.

Kết quả

su dung ajax trong wordpress 3

Mình có giải thích cơ bản trong bài viết và trong comment code, nếu vẫn còn chổ chưa hiểu bạn có thể để lại bình luận bên dưới mình sẽ giải đáp.