TOMSELECT

Tomselect

Tomselect là một thư viện JavaScript mã nguồn mở giúp bạn tạo các <select> box nâng cao (autocomplete, đa chọn, tạo tag, tìm kiếm nhanh...) với trải nghiệm người dùng tốt hơn so với <select> mặc định của HTML.


    data = [
    {
        className: ".cbDanToc",
        action: "DM_DanToc",
        placeholder: "-- Dân tộc --",
        dieuKien: function (response) {
                return response.filter(x => x.ma > 50);
        }
    }
    ]
    configCb(data)

Sử dụng tomselect trong dự án

Tomselect đã được tích hợp sẵn trong dự án lúc cần dùng chỉ cần gọi đến hàm có sẵn.

Cú pháp

configCb(datas, callback)

configCbWithCode(datas, callback)

Hàm configCb dữ liệu lấy được sẽ là cột "id" của dữ liệu.

Hàm configCbWithCode dữ liệu lấy được sẽ là cột "mã" của dữ liệu.

Tham số: datas là danh sách(list) các đối tượng(object) cần cấu hình.


Ví dụ: 
    datas = [
        {
            className: ".cbDanToc",
            placeholder: "-- Dân tộc --",
            action: "DM_DanToc",
            dieuKien: function (response) {
                return response.filter(x => x.ma > 50);
            }
        }
    ]

Trong đó: className là đối tượng bạn muốn cấu hình Tomselect. Có thể truyền vào class, name hoặc id.

placeholder là văn vản hiển thị mặc định.

action là tên file json chứa dữ liệu.

dieuKien(có thể sử dụng hoặc không) thêm điều kiện lọc dữ liệu được lấy ra từ file json.

Tham số:callback là một hàm được thực thi sau khi việc cấu hình cho các đối tượng hoàn tất.

Ví dụ khác


data = 
[
    {
        className: "select[name=nhom_dvkt]",
        action: "DM_NhomDichVuKyThuat",
        placeholder: "-- Nhóm dịch vũ kỹ thuật --",
    }
]
configCb(data) 

data1 = 
[
    {
        className: ".dvkt",
        action: "DM_DichVuKyThuat",
        placeholder: "-- Dịch vụ kỹ thuật --",
        dieuKien: function (response) {
                return response.filter(x => x.id > 1);
        }
    }
]
configCbWithCode(data1, function() {
    $(".dvkt")[0].tomselect.on("focus", function() {
        this.popper = Popper.createPopper(this.control, this.dropdown, {
            placement: "top-start", // Điều chỉnh placement theo ý muốn
        });
    })
})
                                            

Tự xây dựng tomselect

Trong một vài trường hợp hàm dùng sẵn không thể đáp ứng yêu cầu bạn có thể tự tạo một hàm cấu hình tùy ý


function configCb(datas, callback) {
    var requests = []; // Mảng để chứa tất cả các request Ajax
    
    datas.forEach((data) => {
        // Tạo một request AJAX lấy file JSON dựa theo 'action' được truyền
        var request = $.ajax({
            dataType: "json",
            url: "/dist/data/json/" + data.action + ".json",
        }).done(function (response) {
            // Nếu có điều kiện lọc (dieuKien), áp dụng vào dữ liệu
            if (data.dieuKien) {
                response = data.dieuKien(response);
            }

            // Áp dụng cho tất cả phần tử có class tương ứng
            $(data.className).each(function () {
                var arr = [];

                // Nếu thẻ select có thuộc tính required thì clone lại dữ liệu
                if ($(this).prop('required')) {
                    arr = response.map(obj => ({ ...obj })); // clone object
                } else {
                    arr = response; // dùng dữ liệu gốc
                }

                var el = this;

                // Cấu hình cho TomSelect
                let setting = {
                    selectOnTab: true,                     // Cho phép chọn bằng phím Tab
                    loadingClass: "Đang tìm kiếm...",     // Text hiển thị khi đang loading
                    valueField: "id",                     // Giá trị sẽ được submit
                    labelField: "ten",                    // Text hiển thị
                    placeholder:                          // Placeholder mặc định hoặc tùy chỉnh
                        data.placeholder == ""
                            ? $(el).attr("placeholder")
                            : data.placeholder,
                    options: arr,                         // Dữ liệu hiển thị trong dropdown
                    openOnFocus: false,                   // Không tự mở dropdown khi focus
                    searchField: ["ten", "ma", "viettat"], // Các trường cho tìm kiếm

                    // Tùy chỉnh giao diện option hiển thị
                    render: {
                        option: function (item, escape) {
                            return (
                                '<div class="d-flex"><span style="width: 70%;">' +
                                escape(item.ten) +
                                '</span><span style="width: 30%; white-space: nowrap; overflow: hidden;text-overflow: ellipsis;text-align: end;" class="ms-auto text-muted">[' +
                                escape(item.viettat) +
                                "]</span></div>"
                            );
                        },
                        no_results: function (data, escape) {
                            return '<div class="no-results">Không tìm thấy dữ liệu </div>';
                        },
                    },

                    loadThrottle: 400, // Giới hạn tốc độ gọi lại khi nhập (ms)

                    onFocus: function () {
                        // Nếu có thuộc tính 'dropdown-top', hiển thị dropdown ở phía trên
                        if ($(el).attr("dropdown-top")) {
                            this.popper = Popper.createPopper(this.control, this.dropdown, {
                                placement: "top-start",
                            });
                        }
                    }
                };

                // Nếu người dùng muốn thêm tùy chỉnh khác vào setting
                if (data.moreSetting) {
                    data.moreSetting(setting);
                }

                // Chỉ khởi tạo TomSelect nếu chưa tồn tại trên phần tử
                if (!el.tomselect) {
                    var mySelect = new TomSelect(el, setting);
                    mySelect.positionDropdown(); // Cập nhật vị trí dropdown sau khi render

                    // Mở dropdown khi click vào vùng control
                    $(el).next()
                        .children("div.ts-control")
                        .on("click", function () {
                            mySelect.open();
                        });
                }

                // Gọi hàm callback nếu có
                if (data.callback) {
                    data.callback();
                }
            });
        });

        // Thêm mỗi request vào danh sách để xử lý đồng thời
        requests.push(request);
    });

    // Khi tất cả các request đều hoàn tất
    if (callback) {
        $.when
            .apply($, requests)
            .done(function () {
                callback(); // Gọi callback tổng sau khi tất cả xong
            })
            .fail(function () {
                console.error("Lỗi JSON"); // Log nếu có lỗi
            });
    }
}