Skip to content

Commit 3d541dc

Browse files
committed
Make tag selectors fancy
The tag selection dropdown when creating, editing or searching patches now look much nicer. It shows the tag color and the tag description (which is also searchable).
1 parent 1596f52 commit 3d541dc

File tree

2 files changed

+124
-34
lines changed

2 files changed

+124
-34
lines changed
Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,83 @@
11
<script>
22
{% for f, url in form.selectize_fields.items %}
3-
$('#id_{{f}}').selectize({
4-
plugins: ['remove_button'],
5-
valueField: 'id',
6-
labelField: 'value',
7-
searchField: 'value',
8-
{%if url%}
9-
load: function(query, callback) {
10-
if (!query.length) return callback();
11-
$.ajax({
12-
'url': '{{url}}',
13-
'type': 'GET',
14-
'dataType': 'json',
15-
'data': {
16-
'query': query,
17-
},
18-
'error': function() { callback();},
19-
'success': function(res) { callback(res.values);},
20-
});
3+
{% if f == 'tags' or f == 'tag' %}
4+
$('#id_{{f}}').selectize({
5+
plugins: ['remove_button'],
6+
valueField: 'id',
7+
labelField: 'name',
8+
searchField: ['name', 'description'],
9+
placeholder: 'Select tags (type to search by name or description)...',
10+
{% if tags_data %}
11+
options: {{ tags_data|safe }},
12+
{% endif %}
13+
render: {
14+
option: function(item, escape) {
15+
return '<div class="option">' +
16+
'<span class="tag-color" style="background-color: ' + escape(item.color) + '; width: 12px; height: 12px; display: inline-block; border-radius: 2px; margin-right: 6px;"></span>' +
17+
'<strong>' + escape(item.name) + '</strong>' +
18+
(item.description ? '<br><small class="text-muted">' + escape(item.description) + '</small>' : '') +
19+
'</div>';
20+
},
21+
item: function(item, escape) {
22+
return '<div class="item">' +
23+
'<span class="tag-color" style="background-color: ' + escape(item.color) + '; width: 10px; height: 10px; display: inline-block; border-radius: 2px; margin-right: 4px; vertical-align: middle;"></span>' +
24+
escape(item.name) +
25+
'</div>';
26+
}
2127
},
22-
{%endif%}
23-
onFocus: function() {
24-
if (this.$input.is('[multiple]')) {
25-
return;
26-
}
27-
this.lastValue = this.getValue();
28-
this.clear(false);
29-
},
30-
onBlur: function() {
31-
if (this.$input.is('[multiple]')) {
32-
return;
33-
}
34-
if(this.getValue() == '') {
35-
this.setValue(this.lastValue);
28+
onDropdownOpen: function() {
29+
var self = this;
30+
var $dropdown = self.$dropdown;
31+
var $options = $dropdown.find('[data-selectable]');
32+
var totalOptions = self.options ? Object.keys(self.options).length : 0;
33+
var visibleOptions = $options.length;
34+
35+
// Add footer hint if there are more options than visible (due to search filtering or scrolling)
36+
if (totalOptions > 6 && !$dropdown.find('.selectize-scroll-hint').length) {
37+
$dropdown.append('<div class="selectize-scroll-hint text-center text-muted small py-2 px-3" style="border-top: 1px solid #dee2e6; background-color: #f8f9fa;">' +
38+
'⬇ Scroll to see all ' + totalOptions + ' tags, or type to search' +
39+
'</div>');
40+
}
3641
}
37-
},
38-
});
42+
});
43+
{% else %}
44+
$('#id_{{f}}').selectize({
45+
plugins: ['remove_button'],
46+
valueField: 'id',
47+
labelField: 'value',
48+
searchField: 'value',
49+
{%if url%}
50+
load: function(query, callback) {
51+
if (!query.length) return callback();
52+
$.ajax({
53+
'url': '{{url}}',
54+
'type': 'GET',
55+
'dataType': 'json',
56+
'data': {
57+
'query': query,
58+
},
59+
'error': function() { callback();},
60+
'success': function(res) { callback(res.values);},
61+
});
62+
},
63+
{%endif%}
64+
onFocus: function() {
65+
if (this.$input.is('[multiple]')) {
66+
return;
67+
}
68+
this.lastValue = this.getValue();
69+
this.clear(false);
70+
},
71+
onBlur: function() {
72+
if (this.$input.is('[multiple]')) {
73+
return;
74+
}
75+
if(this.getValue() == '') {
76+
this.setValue(this.lastValue);
77+
}
78+
},
79+
});
80+
{% endif %}
3981
{%endfor%}
4082
</script>
4183

pgcommitfest/commitfest/views.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,21 @@ def commitfest(request, cfid):
604604
# the user is logged in. XXX: Figure out how to avoid doing that..
605605
form = CommitFestFilterForm(request.GET)
606606

607+
# Prepare tag data for enhanced selectize dropdown
608+
import json
609+
610+
tags_data = json.dumps(
611+
[
612+
{
613+
"id": tag.id,
614+
"name": tag.name,
615+
"color": tag.color,
616+
"description": tag.description,
617+
}
618+
for tag in Tag.objects.all().order_by("name")
619+
]
620+
)
621+
607622
return render(
608623
request,
609624
"commitfest.html",
@@ -612,6 +627,7 @@ def commitfest(request, cfid):
612627
"form": form,
613628
"patches": patch_list.patches,
614629
"statussummary": statussummary,
630+
"tags_data": tags_data,
615631
"all_tags": {t.id: t for t in Tag.objects.all()},
616632
"has_filter": patch_list.has_filter,
617633
"title": f"{cf.title} ({cf.periodstring})",
@@ -805,6 +821,21 @@ def patchform(request, patchid):
805821
else:
806822
form = PatchForm(instance=patch)
807823

824+
# Prepare tag data for enhanced selectize dropdown
825+
import json
826+
827+
tags_data = json.dumps(
828+
[
829+
{
830+
"id": tag.id,
831+
"name": tag.name,
832+
"color": tag.color,
833+
"description": tag.description,
834+
}
835+
for tag in Tag.objects.all().order_by("name")
836+
]
837+
)
838+
808839
return render(
809840
request,
810841
"base_form.html",
@@ -813,6 +844,7 @@ def patchform(request, patchid):
813844
"form": form,
814845
"patch": patch,
815846
"title": "Edit patch",
847+
"tags_data": tags_data,
816848
"breadcrumbs": [
817849
{"title": cf.title, "href": "/%s/" % cf.pk},
818850
{"title": "View patch", "href": "/%s/%s/" % (cf.pk, patch.pk)},
@@ -861,12 +893,28 @@ def newpatch(request, cfid):
861893
else:
862894
form = NewPatchForm(request=request)
863895

896+
# Prepare tag data for enhanced selectize dropdown
897+
import json
898+
899+
tags_data = json.dumps(
900+
[
901+
{
902+
"id": tag.id,
903+
"name": tag.name,
904+
"color": tag.color,
905+
"description": tag.description,
906+
}
907+
for tag in Tag.objects.all().order_by("name")
908+
]
909+
)
910+
864911
return render(
865912
request,
866913
"base_form.html",
867914
{
868915
"form": form,
869916
"title": "New patch",
917+
"tags_data": tags_data,
870918
"breadcrumbs": [
871919
{"title": f"{cf.title} ({cf.periodstring})", "href": "/%s/" % cf.pk},
872920
],

0 commit comments

Comments
 (0)