Repository: netbox-community/netbox

Issue:
Allow arbitrary rack selection in Rack Elevation view
### Environment
* NetBox version:  2.5.11

### Proposed Functionality

Allow selection of arbitrary racks in Rack Elevations view.

### Use Case

It is not always possible to limit racks shown in Rack Elevations using existing filters. Physical DC layout might be misaligned with groups/tenants/roles, or racks are shared.

Following feature and MR would allow operator to select arbitrary racks for Rack Elevation and other view where `RackFilterForm` is used.

### Database Changes

None.

### External Dependencies

None.
Allow arbitrary rack selection in Rack Elevation view
### Environment
* NetBox version:  2.5.11

### Proposed Functionality

Allow selection of arbitrary racks in Rack Elevations view.

### Use Case

It is not always possible to limit racks shown in Rack Elevations using existing filters. Physical DC layout might be misaligned with groups/tenants/roles, or racks are shared.

Following feature and MR would allow operator to select arbitrary racks for Rack Elevation and other view where `RackFilterForm` is used.

### Database Changes

None.

### External Dependencies

None.


Discussion:
What is the specific implementation being proposed?
I propose adding multiple choice field to rack search form.

Current set of fields does not include multiple choice of racks. Search field provides "fuzzy" search as opposed to arbitrary selection, thus new field  is complementary to existing fields.

![select_rack](https://user-images.githubusercontent.com/835808/58588840-e01d5200-8260-11e9-991d-7f49beb8c7d1.png)

If racks can be displayed in the order they are added, that would be useful. Looking towards the front of some of my racks, they are numbered 100, 99, 98 in that order - the front faces in to the cold aisle and the numbering goes up the hall so racks on the left of the cold aisle are numbered 98, 99, 100, but on the right the order appears right to left.
Related to #1755
What is the specific implementation being proposed?
I propose adding multiple choice field to rack search form.

Current set of fields does not include multiple choice of racks. Search field provides "fuzzy" search as opposed to arbitrary selection, thus new field  is complementary to existing fields.

![select_rack](https://user-images.githubusercontent.com/835808/58588840-e01d5200-8260-11e9-991d-7f49beb8c7d1.png)

If racks can be displayed in the order they are added, that would be useful. Looking towards the front of some of my racks, they are numbered 100, 99, 98 in that order - the front faces in to the cold aisle and the numbering goes up the hall so racks on the left of the cold aisle are numbered 98, 99, 100, but on the right the order appears right to left.
Related to #1755

Resolving patch:
diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py
--- a/netbox/dcim/forms.py
+++ b/netbox/dcim/forms.py
@@ -703,6 +703,34 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
     )
 
 
+#
+# Rack elevations
+#
+
+class RackElevationFilterForm(RackFilterForm):
+    field_order = ['q', 'region', 'site', 'group_id', 'id', 'status', 'role', 'tenant_group', 'tenant']
+    id = ChainedModelChoiceField(
+        queryset=Rack.objects.all(),
+        label='Rack',
+        chains=(
+            ('site', 'site'),
+            ('group_id', 'group_id'),
+        ),
+        required=False,
+        widget=APISelectMultiple(
+            api_url='/api/dcim/racks/',
+            display_field='display_name',
+        )
+    )
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        # Filter the rack field based on the site and group
+        self.fields['site'].widget.add_filter_for('id', 'site')
+        self.fields['group_id'].widget.add_filter_for('id', 'group_id')
+
+
 #
 # Rack reservations
 #
diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py
--- a/netbox/dcim/views.py
+++ b/netbox/dcim/views.py
@@ -388,7 +388,7 @@ def get(self, request):
             'page': page,
             'total_count': total_count,
             'face_id': face_id,
-            'filter_form': forms.RackFilterForm(request.GET),
+            'filter_form': forms.RackElevationFilterForm(request.GET),
         })
 
 


Test patch: