mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-11-30 04:13:01 +00:00
Debounce user search
This commit is contained in:
parent
5ea1eed76d
commit
83d2c18d1e
@ -36,43 +36,40 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||||||
|
|
||||||
{% block extrajavascript %}
|
{% block extrajavascript %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function () {
|
let pattern = '';
|
||||||
let old_pattern = null;
|
|
||||||
let searchbar_obj = $("#searchbar");
|
|
||||||
var timer_on = false;
|
|
||||||
var timer;
|
|
||||||
|
|
||||||
function reloadTable() {
|
function reloadTable() {
|
||||||
let pattern = searchbar_obj.val();
|
pattern = $("#searchbar").val();
|
||||||
|
|
||||||
if (pattern === old_pattern || pattern === "")
|
if (pattern.length > 2)
|
||||||
return;
|
$("#user_table").load(location.pathname + "?search=" + pattern.replace(" ", "%20") + " #user_table", init_table);
|
||||||
|
}
|
||||||
|
|
||||||
$("#user_table").load(location.pathname + "?search=" + pattern.replace(" ", "%20") + " #user_table", init);
|
function init_table() {
|
||||||
}
|
// On row click, go to object
|
||||||
|
$(".table-row").click(function () {
|
||||||
searchbar_obj.keyup(function () {
|
window.document.location = $(this).data("href");
|
||||||
if (timer_on)
|
|
||||||
clearTimeout(timer);
|
|
||||||
timer_on = true;
|
|
||||||
setTimeout(reloadTable, 0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function init() {
|
// Highlight searched terms
|
||||||
$(".table-row").click(function () {
|
$("tr").each(function () {
|
||||||
window.document.location = $(this).data("href");
|
$(this).find("td:eq(0), td:eq(1), td:eq(2), td:eq(3), td:eq(5)").each(function () {
|
||||||
timer_on = false;
|
$(this).html($(this).text().replace(new RegExp(pattern, 'i'), "<mark>$&</mark>"));
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Highlight searched terms
|
$(document).ready(function () {
|
||||||
$("tr").each(function () {
|
// Recover last search from url
|
||||||
$(this).find("td:eq(0), td:eq(1), td:eq(2), td:eq(3), td:eq(5)").each(function () {
|
let searchParams = new URLSearchParams(window.location.search)
|
||||||
$(this).html($(this).text().replace(new RegExp(searchbar_obj.val(), 'i'), "<mark>$&</mark>"));
|
if (searchParams.has('search'))
|
||||||
});
|
pattern = searchParams.get('search');
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
init();
|
// On search, refresh table
|
||||||
|
$("#searchbar").keyup(debounce(reloadTable, 300));
|
||||||
|
|
||||||
|
// First init
|
||||||
|
init_table();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -7,7 +7,7 @@
|
|||||||
* @param value the balance, in cents
|
* @param value the balance, in cents
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
function pretty_money(value) {
|
function pretty_money (value) {
|
||||||
if (value % 100 === 0)
|
if (value % 100 === 0)
|
||||||
return (value < 0 ? "- " : "") + Math.floor(Math.abs(value) / 100) + " €";
|
return (value < 0 ? "- " : "") + Math.floor(Math.abs(value) / 100) + " €";
|
||||||
else
|
else
|
||||||
@ -21,7 +21,7 @@ function pretty_money(value) {
|
|||||||
* @param alert_type The type of the alert. Choices: info, success, warning, danger
|
* @param alert_type The type of the alert. Choices: info, success, warning, danger
|
||||||
* @param timeout The delay (in millis) after that the message is auto-closed. If negative, then it is ignored.
|
* @param timeout The delay (in millis) after that the message is auto-closed. If negative, then it is ignored.
|
||||||
*/
|
*/
|
||||||
function addMsg(msg, alert_type, timeout = -1) {
|
function addMsg (msg, alert_type, timeout = -1) {
|
||||||
let msgDiv = $("#messages");
|
let msgDiv = $("#messages");
|
||||||
let html = msgDiv.html();
|
let html = msgDiv.html();
|
||||||
let id = Math.floor(10000 * Math.random() + 1);
|
let id = Math.floor(10000 * Math.random() + 1);
|
||||||
@ -42,7 +42,7 @@ function addMsg(msg, alert_type, timeout = -1) {
|
|||||||
* @param errs_obj [{error_code:erro_message}]
|
* @param errs_obj [{error_code:erro_message}]
|
||||||
* @param timeout The delay (in millis) after that the message is auto-closed. If negative, then it is ignored.
|
* @param timeout The delay (in millis) after that the message is auto-closed. If negative, then it is ignored.
|
||||||
*/
|
*/
|
||||||
function errMsg(errs_obj, timeout = -1) {
|
function errMsg (errs_obj, timeout = -1) {
|
||||||
for (const err_msg of Object.values(errs_obj)) {
|
for (const err_msg of Object.values(errs_obj)) {
|
||||||
addMsg(err_msg, 'danger', timeout);
|
addMsg(err_msg, 'danger', timeout);
|
||||||
}
|
}
|
||||||
@ -51,9 +51,9 @@ function errMsg(errs_obj, timeout = -1) {
|
|||||||
var reloadWithTurbolinks = (function () {
|
var reloadWithTurbolinks = (function () {
|
||||||
var scrollPosition;
|
var scrollPosition;
|
||||||
|
|
||||||
function reload() {
|
function reload () {
|
||||||
scrollPosition = [window.scrollX, window.scrollY];
|
scrollPosition = [window.scrollX, window.scrollY];
|
||||||
Turbolinks.visit(window.location.toString(), {action: 'replace'})
|
Turbolinks.visit(window.location.toString(), { action: 'replace' })
|
||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('turbolinks:load', function () {
|
document.addEventListener('turbolinks:load', function () {
|
||||||
@ -69,7 +69,7 @@ var reloadWithTurbolinks = (function () {
|
|||||||
/**
|
/**
|
||||||
* Reload the balance of the user on the right top corner
|
* Reload the balance of the user on the right top corner
|
||||||
*/
|
*/
|
||||||
function refreshBalance() {
|
function refreshBalance () {
|
||||||
$("#user_balance").load("/ #user_balance");
|
$("#user_balance").load("/ #user_balance");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,14 +78,14 @@ function refreshBalance() {
|
|||||||
* @param pattern The pattern that is queried
|
* @param pattern The pattern that is queried
|
||||||
* @param fun For each found note with the matched alias `alias`, fun(note, alias) is called.
|
* @param fun For each found note with the matched alias `alias`, fun(note, alias) is called.
|
||||||
*/
|
*/
|
||||||
function getMatchedNotes(pattern, fun) {
|
function getMatchedNotes (pattern, fun) {
|
||||||
$.getJSON("/api/note/alias/?format=json&alias=" + pattern + "&search=user|club&ordering=normalized_name", fun);
|
$.getJSON("/api/note/alias/?format=json&alias=" + pattern + "&search=user|club&ordering=normalized_name", fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a <li> entry with a given id and text
|
* Generate a <li> entry with a given id and text
|
||||||
*/
|
*/
|
||||||
function li(id, text, extra_css) {
|
function li (id, text, extra_css) {
|
||||||
return "<li class=\"list-group-item py-1 px-2 d-flex justify-content-between align-items-center text-truncate "
|
return "<li class=\"list-group-item py-1 px-2 d-flex justify-content-between align-items-center text-truncate "
|
||||||
+ (extra_css ? extra_css : "") + "\"" + " id=\"" + id + "\">" + text + "</li>\n";
|
+ (extra_css ? extra_css : "") + "\"" + " id=\"" + id + "\">" + text + "</li>\n";
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ function li(id, text, extra_css) {
|
|||||||
* Return style to apply according to the balance of the note and the validation status of the email address
|
* Return style to apply according to the balance of the note and the validation status of the email address
|
||||||
* @param note The concerned note.
|
* @param note The concerned note.
|
||||||
*/
|
*/
|
||||||
function displayStyle(note) {
|
function displayStyle (note) {
|
||||||
if (!note)
|
if (!note)
|
||||||
return "";
|
return "";
|
||||||
let balance = note.balance;
|
let balance = note.balance;
|
||||||
@ -120,7 +120,7 @@ function displayStyle(note) {
|
|||||||
* @param user_note_field
|
* @param user_note_field
|
||||||
* @param profile_pic_field
|
* @param profile_pic_field
|
||||||
*/
|
*/
|
||||||
function displayNote(note, alias, user_note_field = null, profile_pic_field = null) {
|
function displayNote (note, alias, user_note_field = null, profile_pic_field = null) {
|
||||||
if (!note.display_image) {
|
if (!note.display_image) {
|
||||||
note.display_image = '/media/pic/default.png';
|
note.display_image = '/media/pic/default.png';
|
||||||
}
|
}
|
||||||
@ -152,7 +152,7 @@ function displayNote(note, alias, user_note_field = null, profile_pic_field = nu
|
|||||||
* (useful in consumptions, put null if not used)
|
* (useful in consumptions, put null if not used)
|
||||||
* @returns an anonymous function to be compatible with jQuery events
|
* @returns an anonymous function to be compatible with jQuery events
|
||||||
*/
|
*/
|
||||||
function removeNote(d, note_prefix = "note", notes_display, note_list_id, user_note_field = null, profile_pic_field = null) {
|
function removeNote (d, note_prefix = "note", notes_display, note_list_id, user_note_field = null, profile_pic_field = null) {
|
||||||
return (function () {
|
return (function () {
|
||||||
let new_notes_display = [];
|
let new_notes_display = [];
|
||||||
let html = "";
|
let html = "";
|
||||||
@ -199,8 +199,8 @@ function removeNote(d, note_prefix = "note", notes_display, note_list_id, user_n
|
|||||||
* the associated note is not displayed.
|
* the associated note is not displayed.
|
||||||
* Useful for a consumption if the item is selected before.
|
* Useful for a consumption if the item is selected before.
|
||||||
*/
|
*/
|
||||||
function autoCompleteNote(field_id, note_list_id, notes, notes_display, alias_prefix = "alias",
|
function autoCompleteNote (field_id, note_list_id, notes, notes_display, alias_prefix = "alias",
|
||||||
note_prefix = "note", user_note_field = null, profile_pic_field = null, alias_click = null) {
|
note_prefix = "note", user_note_field = null, profile_pic_field = null, alias_click = null) {
|
||||||
let field = $("#" + field_id);
|
let field = $("#" + field_id);
|
||||||
|
|
||||||
// Configure tooltip
|
// Configure tooltip
|
||||||
@ -348,7 +348,7 @@ function autoCompleteNote(field_id, note_list_id, notes, notes_display, alias_pr
|
|||||||
|
|
||||||
|
|
||||||
// When a validate button is clicked, we switch the validation status
|
// When a validate button is clicked, we switch the validation status
|
||||||
function de_validate(id, validated, resourcetype) {
|
function de_validate (id, validated, resourcetype) {
|
||||||
let validate_obj = $("#validate_" + id);
|
let validate_obj = $("#validate_" + id);
|
||||||
|
|
||||||
if (validate_obj.data("pending"))
|
if (validate_obj.data("pending"))
|
||||||
@ -392,3 +392,17 @@ function de_validate(id, validated, resourcetype) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple debouncer
|
||||||
|
* @param callback Function to call
|
||||||
|
* @param wait Debounced milliseconds
|
||||||
|
*/
|
||||||
|
function debounce (callback, wait) {
|
||||||
|
let timeout;
|
||||||
|
return (...args) => {
|
||||||
|
const context = this;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(() => callback.apply(context, args), wait);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user