diff --git a/docs/release-notes/version-2.6.md b/docs/release-notes/version-2.6.md
index 88cd9c120..c313d7e1b 100644
--- a/docs/release-notes/version-2.6.md
+++ b/docs/release-notes/version-2.6.md
@@ -6,6 +6,7 @@
* [#2050](https://github.com/netbox-community/netbox/issues/2050) - Preview image attachments when hovering the link
* [#2113](https://github.com/netbox-community/netbox/issues/2113) - Allow NAPALM driver settings to be changed with request headers
* [#2589](https://github.com/netbox-community/netbox/issues/2589) - Toggle for showing available prefixes/ip addresses
+* [#2921](https://github.com/netbox-community/netbox/issues/2921) - Replace tags filter with Select2 widget
* [#3009](https://github.com/netbox-community/netbox/issues/3009) - Search by description when assigning IP address
* [#3090](https://github.com/netbox-community/netbox/issues/3090) - Add filter field for device interfaces
* [#3187](https://github.com/netbox-community/netbox/issues/3187) - Add rack selection field to rack elevations
diff --git a/netbox/templates/circuits/circuit_list.html b/netbox/templates/circuits/circuit_list.html
index d686bdf7a..169aab072 100644
--- a/netbox/templates/circuits/circuit_list.html
+++ b/netbox/templates/circuits/circuit_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/circuits/provider_list.html b/netbox/templates/circuits/provider_list.html
index e4ee7fb2b..4126f75ec 100644
--- a/netbox/templates/circuits/provider_list.html
+++ b/netbox/templates/circuits/provider_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/dcim/device_list.html b/netbox/templates/dcim/device_list.html
index 623d69aa2..8b991689f 100644
--- a/netbox/templates/dcim/device_list.html
+++ b/netbox/templates/dcim/device_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/dcim/devicetype_list.html b/netbox/templates/dcim/devicetype_list.html
index 3b8988ed8..75f587f5d 100644
--- a/netbox/templates/dcim/devicetype_list.html
+++ b/netbox/templates/dcim/devicetype_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/dcim/powerfeed_list.html b/netbox/templates/dcim/powerfeed_list.html
index cfe2c989c..e384cb2c2 100644
--- a/netbox/templates/dcim/powerfeed_list.html
+++ b/netbox/templates/dcim/powerfeed_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/dcim/rack_list.html b/netbox/templates/dcim/rack_list.html
index 72da3048e..2724e4427 100644
--- a/netbox/templates/dcim/rack_list.html
+++ b/netbox/templates/dcim/rack_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/dcim/site_list.html b/netbox/templates/dcim/site_list.html
index 64948a6f9..ef9e0e411 100644
--- a/netbox/templates/dcim/site_list.html
+++ b/netbox/templates/dcim/site_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/dcim/virtualchassis_list.html b/netbox/templates/dcim/virtualchassis_list.html
index 8c26f3c3e..55cfc1691 100644
--- a/netbox/templates/dcim/virtualchassis_list.html
+++ b/netbox/templates/dcim/virtualchassis_list.html
@@ -13,7 +13,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/inc/tags_panel.html b/netbox/templates/inc/tags_panel.html
deleted file mode 100644
index a7923fbed..000000000
--- a/netbox/templates/inc/tags_panel.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% load helpers %}
-
-
diff --git a/netbox/templates/ipam/aggregate_list.html b/netbox/templates/ipam/aggregate_list.html
index aad747b2d..27363a56d 100644
--- a/netbox/templates/ipam/aggregate_list.html
+++ b/netbox/templates/ipam/aggregate_list.html
@@ -17,7 +17,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
Statistics
diff --git a/netbox/templates/ipam/ipaddress_list.html b/netbox/templates/ipam/ipaddress_list.html
index 12f227301..b7920a434 100644
--- a/netbox/templates/ipam/ipaddress_list.html
+++ b/netbox/templates/ipam/ipaddress_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/ipam/prefix_list.html b/netbox/templates/ipam/prefix_list.html
index b80af8e1d..f0754d37b 100644
--- a/netbox/templates/ipam/prefix_list.html
+++ b/netbox/templates/ipam/prefix_list.html
@@ -21,7 +21,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/ipam/service_list.html b/netbox/templates/ipam/service_list.html
index a39bec22e..4aac520d9 100644
--- a/netbox/templates/ipam/service_list.html
+++ b/netbox/templates/ipam/service_list.html
@@ -12,7 +12,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/ipam/vlan_list.html b/netbox/templates/ipam/vlan_list.html
index b4d313a8c..24d538f88 100644
--- a/netbox/templates/ipam/vlan_list.html
+++ b/netbox/templates/ipam/vlan_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/ipam/vrf_list.html b/netbox/templates/ipam/vrf_list.html
index 566e2f3e6..975c73a37 100644
--- a/netbox/templates/ipam/vrf_list.html
+++ b/netbox/templates/ipam/vrf_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/secrets/secret_list.html b/netbox/templates/secrets/secret_list.html
index b6d792765..ee631b439 100644
--- a/netbox/templates/secrets/secret_list.html
+++ b/netbox/templates/secrets/secret_list.html
@@ -15,7 +15,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/tenancy/tenant_list.html b/netbox/templates/tenancy/tenant_list.html
index 91463c52c..a77636a5b 100644
--- a/netbox/templates/tenancy/tenant_list.html
+++ b/netbox/templates/tenancy/tenant_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/virtualization/cluster_list.html b/netbox/templates/virtualization/cluster_list.html
index 3fef90c03..6f5f058ad 100644
--- a/netbox/templates/virtualization/cluster_list.html
+++ b/netbox/templates/virtualization/cluster_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/templates/virtualization/virtualmachine_list.html b/netbox/templates/virtualization/virtualmachine_list.html
index b10341547..821f956a2 100644
--- a/netbox/templates/virtualization/virtualmachine_list.html
+++ b/netbox/templates/virtualization/virtualmachine_list.html
@@ -16,7 +16,6 @@
{% include 'inc/search_panel.html' %}
- {% include 'inc/tags_panel.html' %}
{% endblock %}
diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py
index 1aa358fba..525fd92a9 100644
--- a/netbox/utilities/views.py
+++ b/netbox/utilities/views.py
@@ -8,7 +8,7 @@ from django.core.exceptions import ValidationError
from django.db import transaction, IntegrityError
from django.db.models import Count, ProtectedError
from django.db.models.query import QuerySet
-from django.forms import CharField, Form, ModelMultipleChoiceField, MultipleHiddenInput, Textarea
+from django.forms import CharField, Form, ModelMultipleChoiceField, MultipleChoiceField, MultipleHiddenInput, Textarea
from django.http import HttpResponse, HttpResponseServerError
from django.shortcuts import get_object_or_404, redirect, render
from django.template import loader
@@ -24,7 +24,7 @@ from django_tables2 import RequestConfig
from extras.models import CustomField, CustomFieldValue, ExportTemplate
from extras.querysets import CustomFieldQueryset
-from utilities.forms import BootstrapMixin, CSVDataField
+from utilities.forms import BootstrapMixin, CSVDataField, StaticSelect2Multiple
from utilities.utils import csv_format
from .error_handlers import handle_protectederror
from .forms import ConfirmationForm
@@ -94,6 +94,7 @@ class ObjectListView(View):
model = self.queryset.model
content_type = ContentType.objects.get_for_model(model)
+ filter_form = self.filter_form(request.GET, label_suffix='') if self.filter_form else None
if self.filter:
self.queryset = self.filter(request.GET, self.queryset).qs
@@ -142,11 +143,17 @@ class ObjectListView(View):
if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
table.columns.show('pk')
- # Construct queryset for tags list
- if hasattr(model, 'tags'):
+ # Add the tags filter field to the from if the model has tags
+ if hasattr(model, 'tags') and filter_form:
tags = model.tags.annotate(count=Count('extras_taggeditem_items')).order_by('name')
- else:
- tags = None
+ choices = [(str(tag.slug), '{} ({})'.format(tag.name, tag.count)) for tag in tags]
+
+ filter_form.fields['tag'] = MultipleChoiceField(
+ label='Tags',
+ choices=choices,
+ required=False,
+ widget=StaticSelect2Multiple(),
+ )
# Apply the request context
paginate = {
@@ -159,8 +166,7 @@ class ObjectListView(View):
'content_type': content_type,
'table': table,
'permissions': permissions,
- 'filter_form': self.filter_form(request.GET, label_suffix='') if self.filter_form else None,
- 'tags': tags,
+ 'filter_form': filter_form,
}
context.update(self.extra_context())