Skip to content

Commit a2eb0d8

Browse files
committed
#7084: Fix issue where hidden VLAN form fields were incorrectly included in the form submission
1 parent 6f94198 commit a2eb0d8

File tree

5 files changed

+76
-19
lines changed

5 files changed

+76
-19
lines changed

docs/release-notes/version-3.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* [#7082](https://github.com/netbox-community/netbox/issues/7082) - Avoid exception when referencing invalid content type in table
1515
* [#7083](https://github.com/netbox-community/netbox/issues/7083) - Correct labeling for VM memory attribute
1616
* [#7084](https://github.com/netbox-community/netbox/issues/7084) - Fix KeyError exception when editing access VLAN on an interface
17+
* [#7084](https://github.com/netbox-community/netbox/issues/7084) - Fix issue where hidden VLAN form fields were incorrectly included in the form submission
1718
* [#7089](https://github.com/netbox-community/netbox/issues/7089) - Fix ContentTypeFilterSet not filtering on q filter
1819
* [#7090](https://github.com/netbox-community/netbox/issues/7090) - Fix Cable Bulk Edit Form - allow decimal input on Length field
1920
* [#7091](https://github.com/netbox-community/netbox/issues/7091) - Ensure API requests from the UI are aware of `BASE_PATH`

netbox/project-static/dist/netbox.js

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

netbox/project-static/dist/netbox.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

netbox/project-static/src/forms/vlanTags.ts

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { all, getElement, resetSelect, toggleVisibility } from '../util';
1+
import { all, getElement, resetSelect, toggleVisibility as _toggleVisibility } from '../util';
22

33
/**
44
* Get a select element's containing `.row` element.
@@ -14,6 +14,38 @@ function fieldContainer(element: Nullable<HTMLSelectElement>): Nullable<HTMLElem
1414
return null;
1515
}
1616

17+
/**
18+
* Toggle visibility of the select element's container and disable the select element itself.
19+
*
20+
* @param element Select element.
21+
* @param action 'show' or 'hide'
22+
*/
23+
function toggleVisibility<E extends Nullable<HTMLSelectElement>>(
24+
element: E,
25+
action: 'show' | 'hide',
26+
): void {
27+
// Find the select element's containing element.
28+
const parent = fieldContainer(element);
29+
if (element !== null && parent !== null) {
30+
// Toggle container visibility to visually remove it from the form.
31+
_toggleVisibility(parent, action);
32+
// Create a new event so that the APISelect instance properly handles the enable/disable
33+
// action.
34+
const event = new Event(`netbox.select.disabled.${element.name}`);
35+
switch (action) {
36+
case 'hide':
37+
// Disable the native select element and dispatch the event APISelect is listening for.
38+
element.disabled = true;
39+
element.dispatchEvent(event);
40+
break;
41+
case 'show':
42+
// Enable the native select element and dispatch the event APISelect is listening for.
43+
element.disabled = false;
44+
element.dispatchEvent(event);
45+
}
46+
}
47+
}
48+
1749
/**
1850
* Toggle element visibility when the mode field does not have a value.
1951
*/
@@ -29,7 +61,7 @@ function handleModeNone(): void {
2961
resetSelect(untaggedVlan);
3062
resetSelect(taggedVlans);
3163
for (const element of elements) {
32-
toggleVisibility(fieldContainer(element), 'hide');
64+
toggleVisibility(element, 'hide');
3365
}
3466
}
3567
}
@@ -46,9 +78,9 @@ function handleModeAccess(): void {
4678
if (all(elements)) {
4779
const [taggedVlans, untaggedVlan, vlanGroup] = elements;
4880
resetSelect(taggedVlans);
49-
toggleVisibility(fieldContainer(vlanGroup), 'show');
50-
toggleVisibility(fieldContainer(untaggedVlan), 'show');
51-
toggleVisibility(fieldContainer(taggedVlans), 'hide');
81+
toggleVisibility(vlanGroup, 'show');
82+
toggleVisibility(untaggedVlan, 'show');
83+
toggleVisibility(taggedVlans, 'hide');
5284
}
5385
}
5486

@@ -63,9 +95,9 @@ function handleModeTagged(): void {
6395
];
6496
if (all(elements)) {
6597
const [taggedVlans, untaggedVlan, vlanGroup] = elements;
66-
toggleVisibility(fieldContainer(taggedVlans), 'show');
67-
toggleVisibility(fieldContainer(vlanGroup), 'show');
68-
toggleVisibility(fieldContainer(untaggedVlan), 'show');
98+
toggleVisibility(taggedVlans, 'show');
99+
toggleVisibility(vlanGroup, 'show');
100+
toggleVisibility(untaggedVlan, 'show');
69101
}
70102
}
71103

@@ -81,9 +113,9 @@ function handleModeTaggedAll(): void {
81113
if (all(elements)) {
82114
const [taggedVlans, untaggedVlan, vlanGroup] = elements;
83115
resetSelect(taggedVlans);
84-
toggleVisibility(fieldContainer(vlanGroup), 'show');
85-
toggleVisibility(fieldContainer(untaggedVlan), 'show');
86-
toggleVisibility(fieldContainer(taggedVlans), 'hide');
116+
toggleVisibility(vlanGroup, 'show');
117+
toggleVisibility(untaggedVlan, 'show');
118+
toggleVisibility(taggedVlans, 'hide');
87119
}
88120
}
89121

netbox/project-static/src/select/api/apiSelect.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ export class APISelect {
320320
this.slim.slim.multiSelected.container.setAttribute('disabled', '');
321321
}
322322
}
323+
this.slim.disable();
323324
}
324325

325326
/**
@@ -335,6 +336,7 @@ export class APISelect {
335336
this.slim.slim.multiSelected.container.removeAttribute('disabled');
336337
}
337338
}
339+
this.slim.enable();
338340
}
339341

340342
/**
@@ -357,6 +359,11 @@ export class APISelect {
357359
this.fetchOptions(this.more, 'merge'),
358360
);
359361

362+
// When the base select element is disabled or enabled, properly disable/enable this instance.
363+
this.base.addEventListener(`netbox.select.disabled.${this.name}`, event =>
364+
this.handleDisableEnable(event),
365+
);
366+
360367
// Create a unique iterator of all possible form fields which, when changed, should cause this
361368
// element to update its API query.
362369
// const dependencies = new Set([...this.filterParams.keys(), ...this.pathValues.keys()]);
@@ -578,6 +585,23 @@ export class APISelect {
578585
Promise.all([this.loadData()]);
579586
}
580587

588+
/**
589+
* Event handler to be dispatched when the base select element is disabled or enabled. When that
590+
* occurs, run the instance's `disable()` or `enable()` methods to synchronize UI state with
591+
* desired action.
592+
*
593+
* @param event Dispatched event matching pattern `netbox.select.disabled.<name>`
594+
*/
595+
private handleDisableEnable(event: Event): void {
596+
const target = event.target as HTMLSelectElement;
597+
598+
if (target.disabled === true) {
599+
this.disable();
600+
} else if (target.disabled === false) {
601+
this.enable();
602+
}
603+
}
604+
581605
/**
582606
* When the API returns an error, show it to the user and reset this element's available options.
583607
*

0 commit comments

Comments
 (0)