You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I’m experimenting with building more dynamic forms for NetBox Scripts and I’d like to ask whether my current approach is considered acceptable, and what pitfalls I should be aware of.
NetBox version: 4.4.x
Use case: A Script that edits a custom field (rack_todo) for all racks in the same site as the rack from which the script is launched.
I override as_form() in a Script to:
Resolve the “base” rack from api_path.
Collect all racks in the same site.
Build a JSON payload with id, name, location, todo.
Inject an HTML
+ <script> into the help_text of a hidden TextVar field.
On page load, the JavaScript:
Hides the original form fields (api_path, payload).
Renders one textarea per rack with some styling and a small helper text.
Shows a “Add TODO” button when a particular rack has no TODO yet.
On form submit, the JS collects all textarea values back into the hidden payload field as JSON, and the Script’s run() method parses that JSON and updates the rack_todo custom field.
Very simplified example (only the relevant part):
class ShowRacksTodo(Script):
api_path = StringVar(
label="API path",
required=True,
description="Automatically filled when launched from a rack page.",
)
payload = TextVar(
label="",
required=False,
description="",
)
def as_form(self, data=None, files=None, initial=None):
# ... resolve base_rack, collect racks, build rack_payload ...
payload_json = json.dumps(rack_payload)
js = f"""
<div id="rack_todo_container"></div>
<script>
document.addEventListener("DOMContentLoaded", function() {{
const racks = {payload_json};
const payloadInput = document.getElementById("id_payload");
if (!payloadInput) return;
// Hide payload field and API path row
payloadInput.style.display = "none";
const payloadLabel = document.querySelector('label[for="id_payload"]');
if (payloadLabel) payloadLabel.style.display = "none";
const apiInput = document.getElementById("id_api_path");
if (apiInput) {{
const apiRow = apiInput.closest(".row.mb-3");
if (apiRow) apiRow.style.display = "none";
}}
const container = document.getElementById("rack_todo_container");
if (!container) return;
racks.forEach(function(rack) {{
const row = document.createElement("div");
row.className = "row mb-3";
const colLabel = document.createElement("div");
colLabel.className = "col-md-3 col-sm-12";
const label = document.createElement("label");
label.className = "form-label";
label.textContent = "Rack " + rack.name;
colLabel.appendChild(label);
const colField = document.createElement("div");
colField.className = "col-md-9 col-sm-12";
const textarea = document.createElement("textarea");
textarea.className = "form-control";
textarea.rows = 10;
textarea.setAttribute("data-rack-id", rack.id);
textarea.value = rack.todo || "";
colField.appendChild(textarea);
row.appendChild(colLabel);
row.appendChild(colField);
container.appendChild(row);
}});
// Before submit: collect all textarea values into JSON and write to payload
const form = payloadInput.closest("form");
if (form) {{
form.addEventListener("submit", function() {{
const items = [];
container.querySelectorAll("textarea[data-rack-id]").forEach(function(ta) {{
const rid = parseInt(ta.getAttribute("data-rack-id"), 10);
if (!isNaN(rid)) {{
items.push({{id: rid, todo: ta.value || ""}});
}}
}});
payloadInput.value = JSON.stringify(items);
}});
}}
}});
</script>
"""
form = super().as_form(data, files, initial)
form.fields["payload"].label = ""
form.fields["payload"].help_text = js
return form
def run(self, data, commit):
# ... parse JSON from payload and update rack_todo custom field ...
...
Is this approach (injecting custom JavaScript into Script forms) something you consider acceptable / supported for NetBox scripts? As far as I know there is no “official” way to build dynamic script forms (multiple textareas, conditional visibility, etc.) that I should prefer instead of custom JS.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
I’m experimenting with building more dynamic forms for NetBox Scripts and I’d like to ask whether my current approach is considered acceptable, and what pitfalls I should be aware of.
NetBox version: 4.4.x
Use case: A Script that edits a custom field (rack_todo) for all racks in the same site as the rack from which the script is launched.
I override as_form() in a Script to:
Hides the original form fields (api_path, payload).
Renders one textarea per rack with some styling and a small helper text.
Shows a “Add TODO” button when a particular rack has no TODO yet.
Very simplified example (only the relevant part):
Is this approach (injecting custom JavaScript into Script forms) something you consider acceptable / supported for NetBox scripts? As far as I know there is no “official” way to build dynamic script forms (multiple textareas, conditional visibility, etc.) that I should prefer instead of custom JS.
Beta Was this translation helpful? Give feedback.
All reactions