mirror of https://gitlab.crans.org/bde/nk20
Made searchbar completely client-based
This commit is contained in:
parent
08b2fabe07
commit
5e39209ab1
|
@ -130,11 +130,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<div class="tab-pane" id="search">
|
<div class="tab-pane" id="search">
|
||||||
<input class="form-control mx-auto d-block mb-3"
|
<input class="form-control mx-auto d-block mb-3"
|
||||||
placeholder="{% trans "Search button..." %}" type="text" id="search-input"/>
|
placeholder="{% trans "Search button..." %}" type="search" id="search-input"/>
|
||||||
<div class="d-inline-flex flex-wrap justify-content-center" id="search-results">
|
<div class="d-inline-flex flex-wrap justify-content-center" id="search-results">
|
||||||
{% for button in search_results %}
|
{% for button in all_buttons %}
|
||||||
{% if button.display %}
|
{% if button.display %}
|
||||||
<button class="btn btn-outline-dark rounded-0 flex-fill"
|
<button class="btn btn-outline-dark rounded-0 flex-fill" hidden
|
||||||
id="search_button{{ button.id }}" name="button" value="{{ button.name }}">
|
id="search_button{{ button.id }}" name="button" value="{{ button.name }}">
|
||||||
{{ button.name }} ({{ button.amount | pretty_money }})
|
{{ button.name }} ({{ button.amount | pretty_money }})
|
||||||
</button>
|
</button>
|
||||||
|
@ -202,33 +202,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
searchbar = document.getElementById("search-input")
|
{% for button in all_buttons %}
|
||||||
|
|
||||||
const parser = new DOMParser();
|
|
||||||
old_pattern = null;
|
|
||||||
function updateSearch(force = false) {
|
|
||||||
let pattern = searchbar.value
|
|
||||||
if ((pattern === old_pattern || pattern === "") && !force)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const xhr = new XMLHttpRequest();
|
|
||||||
xhr.open("GET", location.pathname + "?search=" +
|
|
||||||
encodeURI(pattern) + "#search", true)
|
|
||||||
xhr.onload = () => {
|
|
||||||
let newdoc = parser.parseFromString(xhr.responseText, "text/html");
|
|
||||||
document.getElementById("search-results").innerHTML =
|
|
||||||
newdoc.getElementById("search-results").innerHTML;
|
|
||||||
eval(newdoc.getElementById("search-script").text);
|
|
||||||
};
|
|
||||||
xhr.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
searchbar.addEventListener("input", function (e) {
|
|
||||||
debounce(updateSearch)()
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<script type="text/javascript" id="search-script">
|
|
||||||
{% for button in search_results %}
|
|
||||||
{% if button.display %}
|
{% if button.display %}
|
||||||
document.getElementById("search_button{{ button.id }}").addEventListener("click", function() {
|
document.getElementById("search_button{{ button.id }}").addEventListener("click", function() {
|
||||||
addConso({{ button.destination_id }}, {{ button.amount }},
|
addConso({{ button.destination_id }}, {{ button.amount }},
|
||||||
|
@ -237,5 +211,41 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
});
|
});
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
const searchbar = document.getElementById("search-input")
|
||||||
|
const search_results = document.getElementById("search-results")
|
||||||
|
|
||||||
|
var old_pattern = null;
|
||||||
|
var firstMatch = null;
|
||||||
|
/**
|
||||||
|
* Updates the button search tab
|
||||||
|
* @param force Forces the update even if the pattern didn't change
|
||||||
|
*/
|
||||||
|
function updateSearch(force = false) {
|
||||||
|
let pattern = searchbar.value
|
||||||
|
if (pattern === "")
|
||||||
|
firstMatch = null;
|
||||||
|
if ((pattern === old_pattern || pattern === "") && !force)
|
||||||
|
return;
|
||||||
|
firstMatch = null;
|
||||||
|
const re = new RegExp(pattern, "i");
|
||||||
|
Array.from(search_results.children).forEach(function(b) {
|
||||||
|
if (re.test(b.innerText)) {
|
||||||
|
b.hidden = false;
|
||||||
|
if (firstMatch === null) {
|
||||||
|
firstMatch = b;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
b.hidden = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
searchbar.addEventListener("input", function (e) {
|
||||||
|
debounce(updateSearch)()
|
||||||
|
});
|
||||||
|
searchbar.addEventListener("keyup", function (e) {
|
||||||
|
if (firstMatch && e.key === "Enter")
|
||||||
|
firstMatch.click()
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -190,17 +190,14 @@ class ConsoView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
|
||||||
).order_by('name').all()
|
).order_by('name').all()
|
||||||
context['polymorphic_ctype'] = ContentType.objects.get_for_model(RecurrentTransaction).pk
|
context['polymorphic_ctype'] = ContentType.objects.get_for_model(RecurrentTransaction).pk
|
||||||
|
|
||||||
if "search" in self.request.GET and self.request.GET["search"]:
|
context['all_buttons'] = TransactionTemplate.objects.filter(
|
||||||
pattern = self.request.GET["search"]
|
|
||||||
context['search_results'] = TransactionTemplate.objects.filter(
|
|
||||||
name__iregex=pattern
|
|
||||||
).filter(
|
|
||||||
PermissionBackend.filter_queryset(self.request, TransactionTemplate, "view")
|
PermissionBackend.filter_queryset(self.request, TransactionTemplate, "view")
|
||||||
).filter(display=True).order_by('name').all()
|
).filter(display=True).order_by('name').all()
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TransactionSearchView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
class TransactionSearchView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView):
|
||||||
model = Note
|
model = Note
|
||||||
context_object_name = "note"
|
context_object_name = "note"
|
||||||
|
|
Loading…
Reference in New Issue