Cảm ơn bạn!
Thay thế select boxes đơn giản với select2
Select2 Jquery là gì?
Select2 là một plugin của Jquery, nó cung cấp cho bạn một select box với các tùy chỉnh như hỗ trợ tìm kiếm với kết quả trả về từ database, infinite scrolling và nhiều tùy chọn khác. Plugin này cũng hỗ trợ nhiều trình duyệt bao gồm Internet Explorer 11 nên các bạn có thể yên tâm sử dụng.
Cài đặt select2
Để cài đặt thì các bạn có 2 lựa chọn:
- Tải folder select2 về: https://github.com/select2/select2/tags
Include file vào phần head.
<link href="path/to/select2.min.css" rel="stylesheet" />
<script src="path/to/select2.min.js"></script>
- Sử dụng CDN (content delivery network):
Các bạn copy 2 link này về và chèn vào phần head là xong.
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
Sử dụng Select2
Trong trường hợp bạn đang sử dụng <select>
và muốn style thì các phải sẽ phải tự tạo một select box sử dụng javascript hay jquery. Vì <select>
chỉ hỗ trợ một số thuộc tính style. Cách nhanh chóng là sử dụng một plugin như
Select2.
Select2 được sử dụng để thay thế cho <select>
giúp các bạn tiết kiệm thời gian tạo select box và style, việc tự tạo select box khá mất thời gian và nhiều khi kết quả không như mong muốn 🥴. Select2 hỗ trợ tất cả các tùy chọn có sẵn của một select box nhưng có thêm tính linh hoạt trong một số trường hợp. Cùng mình tìm hiểu về cách sử dụng Select2 nhé!
Single select boxes
Đầu tiên chúng ta sẽ tạo một select box đơn giản:
<select class="basic-select" name="pet">
<option value="dog">Dog</option>
<option value="cat">Cat</option>
<option value="squirrel">squirrel</option>
...
</select>
Để sử dụng select2 các bạn chỉ cần tạo 1 thẻ <select>
, đặt một class hoặc id để select2 có thể tạo một phần tử mới với các thông tin từ thẻ đó.
Vì select2 được build từ jquery nên để sử dụng, các bạn phải nhúng jquery trước link select2.
Sau khi hoàn tất các bước trên chúng ta chỉ cần sử dụng $(element).select2()
, việc còn lại select2 sẽ giúp bạn giải quyết.
$('.basic-select').select2();
Để sử dụng select2 các bạn nên đảm DOM đã load xong, sau khi DOM được load các bạn có thể sử dụng select2. Lý do là các dữ liệu truy xuất từ database có thể được truyền vào option
sau khi select2 thực thi. Việc này dẫn đến dữ liệu sẽ bị thiếu gây ra lỗi không mong muốn.
Để an toàn khi sử dụng 😁 chúng ta sẽ làm như sau:
$(document).ready(function() {
$('.basic-select').select2();
});
Kết quả chúng ta sẽ được như sau:
Multi-select boxes
Để select được nhiều option chúng ta có thêm tùy chọn multi-select:
<select class="multiple-select" name="categories[]" multiple="multiple">
<option value="reactjs">ReactJS</option>
<option value="nestjs">NestJS</option>
<option value="laravel">Laravel</option>
...
</select>
Options
Giới hạn select
Để giới hạn số option khi sử dụng multiple các bạn cần sử dụng thuộc tính maximumSelectionLength
:
$(".multiple-select").select2({
maximumSelectionLength: 2
});
Thêm các option mới
Giả sử chúng ta muốn thêm một category mới ở ví dụ trên, chúng ta sẽ sử dụng tùy chọn tags
và set thành true
:
<select class="multiple-select" name="categories[]" multiple="multiple">
<option value="reactjs">ReactJS</option>
<option value="nestjs">NestJS</option>
<option value="laravel">Laravel</option>
</select>
$(".multiple-select").select2({
tags: true
});
Placeholder
Các bạn có thể thêm placeholder
vào select2 bằng cách sau:
$(".multiple-select").select2({
placeholder: "Select a category",
});
Kết quả chúng ta được như sau:
select2 ajax
Chúng ta có thể sử dụng ajax với select2, bây giờ chúng ta sẽ xem thử một ví dụ để xem cách sử dụng ajax với select2 thế nào nhé!
Ở trên là một ví dụ dùng select2 với ajax. Dữ liệu được ajax trả về và chúng ta sẽ sử dụng select2 để show ra.
Các bước thực hiện:
Tạo một <select>
với multiple="multiple"
nếu bạn muốn có thể chọn nhiều option.
Khi chúng ta chọn option thì select2 sẽ tự push dữ liệu đã chọn vào mảng users
chúng ta đã tạo ra ở thuộc tính name
của select.
<div class="select-box">
<select
class="multiple-select"
name="users[]"
multiple="multiple">
</select>
</div>
Tiếp theo chúng ta sẽ sử dụng select2 với thẻ <select>
ở trên:
$('.multiple-select').select2();
Lúc này dữ liệu trong <select>
ta chưa có, chúng ta sẽ tiến hành lấy dữ liệu từ một api có sẵn là https://randomuser.me/api/
.
Để sử dụng ajax các bạn có thể thêm vào options của select2:
$('.multiple-select').select2({
ajax: {
url: 'https://randomuser.me/api/',
dataType: 'json',
delay: 250,
}
});
Nếu bạn muốn delay thì thêm thuộc tính delay (đơn vị: milliseconds), nó sẽ dừng khoảng 250ms và bắt đầu thực hiện request.
Muốn có dữ liệu trả về chúng ta phải thêm 1 số thông tin query, vào docs của https://randomuser.me/api/ để tìm hiểu. Ở đây mình sẽ sử dụng seeds của api này. Chúng ta chỉ cần truyền các ký tự bất kỳ, nó sẽ trả về cho chúng ta một danh sách user.
Đây là một ví dụ truyền parameter là seed
với giá trị là foobar:
https://randomuser.me/api/?seed=foobar
Lấy nhiều kết quả chúng ta sẽ truyền thêm param là results
:
https://randomuser.me/api/?seed=foobar&results=5000
Mình sẽ truyền các giá trị này vào ajax như sau:
$('.multiple-select').select2({
ajax: {
url: 'https://randomuser.me/api/',
dataType: 'json',
delay: 250,
data: function (params) {
// Query parameters will be ?seed=[seed]&page=[page]
return {
seed: params.seed,
page: params.page || 1,
results: 40,
};
},
}
});
Ở đây mình có thêm param là page với giá trị ban đầu là params.page. Như ở url trên mình không truyền vào nên nó sẽ là 1.
Với request trên, mình sẽ thực hiện lấy dữ liệu theo seed, page là 1 và kết quả sẽ trả về 40 users.
Để sử dụng kết quả trả về chúng ta làm như sau:
function (data, params) {
params.page = params.page || 1;
console.log(data.results); // mảng gồm các user
const results = [];
$.each(data.results, function (index, user) {
results.push({
picture: user.picture.medium,
id: user.id.value,
email: user.email,
fullname: user.name.first + ' ' + user.name.last,
});
});
return {
results,
pagination: {
more: params.page * 20 < data.results.length,
},
};
}
Chúng ta sẽ tạo một function, function này sẽ lấy kết quả trả về từ ajax.
Để dữ liệu hiển thị chính xác, bạn cần truyền cho mỗi user một id, để khi chúng ta select. Select2 sẽ hiển thị user chính xác. Đây chính là lí do mình tạo một biến results
để push các dữ liệu cần hiển thị, nhớ truyền id nhé ^^.
Cuối cùng chúng ta sẽ return dữ liệu đã lấy. Các bạn thấy chúng ta có một thuộc tính pagination
, thuộc tính này giúp select2 phân trang. Bạn cần truyền vào more
giá trị true hoặc false, nếu true select2 sẽ tính toán và phân trang theo kiểu infinite scrolling
.
Chúng ta có điều kiện true/false: phần tử trả về ít hơn phần tử quy định trong 1 trang thì return false. Ở trên mình đã truyền results: 40
nên lúc này more sẽ là true.
Tổng hợp lại những ý trên chúng ta có:
$('.multiple-select').select2({
ajax: {
url: 'https://randomuser.me/api/',
dataType: 'json',
delay: 250,
data: function (params) {
// Query parameters will be ?seed=[seed]&page=[page]
return {
seed: params.seed,
page: params.page || 1,
results: 40,
};
},
processResults: function (data, params) {
params.page = params.page || 1;
const results = [];
$.each(data.results, function (index, user) {
results.push({
picture: user.picture.medium,
id: user.id.value,
email: user.email,
fullname: user.name.first + ' ' + user.name.last,
});
});
return {
results,
pagination: {
more: params.page * 20 < data.results.length,
},
};
},
cache: true,
},
})
Như vậy là chúng ta đã có được dữ liệu cần lấy và xử lí phân trang. Tiếp theo, làm sao để hiển thị dữ liệu từ select2? Để làm điều này select2 có thuộc tính là: templateResult
và templateSelection
.
Cả 2 thuộc tính yêu cầu truyền vào function để xử lý. Chúng ta sẽ tạo các function cho các thuộc tính trên:
- templateResult:
function formatUser(user) {
if (user.loading) return user.text;
const container = $(
`<div class='select2-result-user'>
<div class='select2-result-user__avatar'>
<img src="${user.picture}"/>
</div>
<div class='select2-result-user__meta'>
<div class="fullname">${user.fullname}</div>
<div class="email">${user.email}</div>
</div>
`
);
return container;
}
function formatUser
giúp select2 hiển thị dữ liệu user với param user
là object lấy từ kết quả return trong processResults
.
- templateSelection:
function formatUserSelection(user) {
return user.fullname;
}
function formatUserSelection
có nhiệm vụ đơn giản là khi chúng ta select một user bất kỳ, user được select sẽ hiển thị fullname ra select box ^^. Đồng thời user này cũng được push vào trong biến users
của <select>
.
Khi submit dữ liệu, ví dụ như sử dụng laravel, chúng ta sẽ có danh sách users
đã chọn được gửi lên cho serve xử lý😁.
Kết luận
Như vậy là chúng ta đã tìm hiểu về plugin select2 khá hay này. Hi vọng bài viết sẽ giúp ích cho các bạn ^^.
Chúc các bạn học tốt 🌝.