diff --git a/games/static/js/add_edition.js b/games/static/js/add_edition.js
deleted file mode 100644
index 334f069..0000000
--- a/games/static/js/add_edition.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { syncSelectInputUntilChanged } from "./utils.js";
-
-let syncData = [
- {
- source: "#id_game",
- source_value: "dataset.name",
- target: "#id_name",
- target_value: "value",
- },
- {
- source: "#id_game",
- source_value: "textContent",
- target: "#id_sort_name",
- target_value: "value",
- },
- {
- source: "#id_game",
- source_value: "dataset.year",
- target: "#id_year_released",
- target_value: "value",
- },
-];
-
-syncSelectInputUntilChanged(syncData, "form");
diff --git a/games/static/js/add_game.js b/games/static/js/add_game.js
deleted file mode 100644
index d35ade7..0000000
--- a/games/static/js/add_game.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { syncSelectInputUntilChanged } from "./utils.js";
-
-let syncData = [
- {
- source: "#id_name",
- source_value: "value",
- target: "#id_sort_name",
- target_value: "value",
- },
-];
-
-syncSelectInputUntilChanged(syncData, "form");
diff --git a/games/views/purchase.py b/games/views/purchase.py
index 91135ba..b7c599a 100644
--- a/games/views/purchase.py
+++ b/games/views/purchase.py
@@ -194,7 +194,7 @@ def _pricing_controls() -> Node:
By default the form's own single Price field is the bundle price. When 2+
games are selected and "Separate price per game" is checked, the per-game
inputs (the general ``selection-fields`` element) take over and the bundle
- Price is hidden. Toggle/visibility wiring lives in add_purchase.js; the
+ Price is hidden. Toggle/visibility wiring lives in ts/add_purchase.ts; the
hidden ``pricing_mode`` tells the view which path to take.
"""
return Div(attributes=[("id", "pricing-controls")])[
@@ -301,7 +301,7 @@ def add_purchase(request: HttpRequest, game_id: int = 0) -> HttpResponse:
),
title="Add New Purchase",
scripts=mark_safe(
- ModuleScript("search_select.js") + ModuleScript("add_purchase.js")
+ ModuleScript("search_select.js") + ModuleScript("dist/add_purchase.js")
),
)
@@ -319,7 +319,7 @@ def edit_purchase(request: HttpRequest, purchase_id: int) -> HttpResponse:
AddForm(form, request=request, additional_row=_purchase_additional_row()),
title="Edit Purchase",
scripts=mark_safe(
- ModuleScript("search_select.js") + ModuleScript("add_purchase.js")
+ ModuleScript("search_select.js") + ModuleScript("dist/add_purchase.js")
),
)
diff --git a/tests/test_rendered_pages.py b/tests/test_rendered_pages.py
index 4cbe8f0..48a86f1 100644
--- a/tests/test_rendered_pages.py
+++ b/tests/test_rendered_pages.py
@@ -125,14 +125,14 @@ class RenderedPagesTest(TestCase):
def test_add_game_form(self):
html = self.get("games:add_game").content.decode()
- self.assertIn("add_game.js", html)
+ self.assertIn("dist/add_game.js", html)
self.assertIn("submit_and_redirect", html)
self.assertIn("Submit & Create Purchase", html) # & correctly escaped
self.assertNoEscapedTags(html)
def test_add_purchase_form(self):
html = self.get("games:add_purchase").content.decode()
- self.assertIn("add_purchase.js", html)
+ self.assertIn("dist/add_purchase.js", html)
self.assertIn("Submit & Create Session", html)
self.assertIn("
", html)
self.assertNoEscapedTags(html)
diff --git a/games/static/js/add_purchase.js b/ts/add_purchase.ts
similarity index 53%
rename from games/static/js/add_purchase.js
rename to ts/add_purchase.ts
index 11cfdea..b80b650 100644
--- a/games/static/js/add_purchase.js
+++ b/ts/add_purchase.ts
@@ -1,58 +1,70 @@
-import { getEl, disableElementsWhenTrue, onSwap } from "./utils.js";
+import { disableElementsWhenTrue, onSwap } from "./utils.js";
+
+interface SearchSelectOption {
+ value: string;
+ label: string;
+ data: Record;
+}
+
+interface SearchSelectChangeDetail {
+ name: string;
+ values: string[];
+ last: SearchSelectOption | null;
+}
// Switch between a single bundle price and one price per game. The per-game
// inputs are the selection-fields element; this only sets the policy: the
// hidden pricing_mode the view reads, the element's "active" flag, and whether
// the bundle Price field is shown.
-function applyPricingMode(separate) {
- const pricingMode = getEl("#id_pricing_mode");
+function applyPricingMode(separate: boolean): void {
+ const pricingMode = document.querySelector("#id_pricing_mode");
if (pricingMode) pricingMode.value = separate ? "per_game" : "combined";
const selectionFields = document.querySelector("selection-fields");
if (selectionFields)
selectionFields.setAttribute("active", separate ? "true" : "false");
- const priceInput = getEl("#id_price");
+ const priceInput = document.querySelector("#id_price");
if (priceInput) {
const wrapper = priceInput.closest("div");
if (wrapper) wrapper.classList.toggle("hidden", separate);
}
}
-// The games field is now a SearchSelect widget (a