From 9a1c35e059f846944c0703a9659119caeebe6deb Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 00:39:11 -0600 Subject: [PATCH 01/33] Add +5 buttons to counter --- resources/js/scoutingPASS.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 9c5517c45..ab09fc204 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -165,6 +165,14 @@ function addCounter(table, idx, name, data) { } cell2.classList.add("field"); + if (data.hasOwnProperty('plusX1')) { + var buttonX1m = document.createElement("input"); + buttonX1m.setAttribute("type", "button"); + buttonX1m.setAttribute("id", "minusX1_" + data.code); + buttonX1m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusX1 + ")"); + buttonX1m.setAttribute("value", "-" + data.plusX1); + cell2.appendChild(buttonX1m); + } var button1 = document.createElement("input"); button1.setAttribute("type", "button"); button1.setAttribute("id", "minus_" + data.code); @@ -195,6 +203,15 @@ function addCounter(table, idx, name, data) { button2.setAttribute("value", "+"); cell2.appendChild(button2); + if (data.hasOwnProperty('plusX1')) { + var buttonX1p = document.createElement("input"); + buttonX1p.setAttribute("type", "button"); + buttonX1p.setAttribute("id", "minusX1_" + data.code); + buttonX1p.setAttribute("onclick", "counter(this.parentElement, +" + data.plusX1 + ")"); + buttonX1p.setAttribute("value", "+" + data.plusX1); + cell2.appendChild(buttonX1p); + } + if (data.hasOwnProperty('cycleTimer')) { if (data.cycleTimer != "") { inp = document.createElement('input'); @@ -1432,3 +1449,4 @@ window.onload = function () { } } }; + From 115951158e798f3ff6a5c0471db630139691d2c1 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 00:41:41 -0600 Subject: [PATCH 02/33] Add plusX1 property to Fuel Scored configuration --- 2026/rebuilt_config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/2026/rebuilt_config.js b/2026/rebuilt_config.js index 49851dfb0..64c6fc610 100644 --- a/2026/rebuilt_config.js +++ b/2026/rebuilt_config.js @@ -78,6 +78,7 @@ var config_data = ` { "name": "Fuel Scored", "code": "afs", "expectedMax": 32, + "plusX1": 10, "type": "counter" }, { "name": "Pass from Neutral Zone", From 89268a33bee56f974ca20532fcc041c0e325e710 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 00:47:21 -0600 Subject: [PATCH 03/33] Add plusX2 property to scoring configurations --- 2026/rebuilt_config.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/2026/rebuilt_config.js b/2026/rebuilt_config.js index 64c6fc610..67b9dae84 100644 --- a/2026/rebuilt_config.js +++ b/2026/rebuilt_config.js @@ -79,11 +79,14 @@ var config_data = ` "code": "afs", "expectedMax": 32, "plusX1": 10, + "plusX2": 5, "type": "counter" }, { "name": "Pass from Neutral Zone", "code": "apn", "expectedMax": 60, + "plusX1": 10, + "plusX2": 5, "type": "counter" }, { "name": "Climb (L1)", @@ -122,11 +125,15 @@ var config_data = ` { "name": "Fuel Scored", "code": "tfs", "expectedMax": 150, + "plusX1": 10, + "plusX2": 5, "type": "counter" }, { "name": "Pass from Neutral Zone", "code": "pnz", "expectedMax": 250, + "plusX1": 10, + "plusX2": 5, "type": "counter" }, { "name": "Pass from Opp
Alliance Zone", From 78d6c64ae120eadb830b2016ba392919ef2f498e Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 00:51:36 -0600 Subject: [PATCH 04/33] Add two new configurable counter buttons --- resources/js/scoutingPASS.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index ab09fc204..aa722e4e1 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -173,6 +173,16 @@ function addCounter(table, idx, name, data) { buttonX1m.setAttribute("value", "-" + data.plusX1); cell2.appendChild(buttonX1m); } + + if (data.hasOwnProperty('plusX2')) { + var buttonX2m = document.createElement("input"); + buttonX2m.setAttribute("type", "button"); + buttonX2m.setAttribute("id", "minusX2_" + data.code); + buttonX2m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusX2 + ")"); + buttonX2m.setAttribute("value", "-" + data.plusX2); + cell2.appendChild(buttonX2m); + } + var button1 = document.createElement("input"); button1.setAttribute("type", "button"); button1.setAttribute("id", "minus_" + data.code); @@ -203,10 +213,19 @@ function addCounter(table, idx, name, data) { button2.setAttribute("value", "+"); cell2.appendChild(button2); + if (data.hasOwnProperty('plusX2')) { + var buttonX2p = document.createElement("input"); + buttonX2p.setAttribute("type", "button"); + buttonX2p.setAttribute("id", "plusX2_" + data.code); + buttonX2p.setAttribute("onclick", "counter(this.parentElement, +" + data.plusX2 + ")"); + buttonX2p.setAttribute("value", "+" + data.plusX2); + cell2.appendChild(buttonX2p); + } + if (data.hasOwnProperty('plusX1')) { var buttonX1p = document.createElement("input"); buttonX1p.setAttribute("type", "button"); - buttonX1p.setAttribute("id", "minusX1_" + data.code); + buttonX1p.setAttribute("id", "plusX1_" + data.code); buttonX1p.setAttribute("onclick", "counter(this.parentElement, +" + data.plusX1 + ")"); buttonX1p.setAttribute("value", "+" + data.plusX1); cell2.appendChild(buttonX1p); @@ -1450,3 +1469,4 @@ window.onload = function () { } }; + From c23e0d19934c123b5d7a097af7a2cd0adf0532fb Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 01:13:07 -0600 Subject: [PATCH 05/33] Fix button spacing --- resources/js/scoutingPASS.js | 53 ++++++++++-------------------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index aa722e4e1..03787e597 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -151,38 +151,32 @@ function addTimer(table, idx, name, data) { function addCounter(table, idx, name, data) { var row = table.insertRow(idx); var cell1 = row.insertCell(0); + if (data.hasOwnProperty('plusX1') || data.hasOwnProperty('plusX2')) { + cell1.setAttribute("colspan", 2); + cell1.setAttribute("style", "text-align: center;"); + cell1.style.display = "flex"; + cell.style.gap = "10px"; + } cell1.style.width = ColWidth; cell1.classList.add("title"); if (!data.hasOwnProperty('code')) { cell1.innerHTML = `Error: No code specified for ${name}`; return idx + 1; } - var cell2 = row.insertCell(1); - cell2.style.width = ColWidth; + var cell2 + if (data.hasOwnProperty('plusX1') || data.hasOwnProperty('plusX2')) { + cell2 = cell1 + } else { + cell2 = row.insertCell(1); + cell2.style.width = ColWidth; + } + cell1.innerHTML = name + ' '; if (data.hasOwnProperty('tooltip')) { cell1.setAttribute("title", data.tooltip); } cell2.classList.add("field"); - if (data.hasOwnProperty('plusX1')) { - var buttonX1m = document.createElement("input"); - buttonX1m.setAttribute("type", "button"); - buttonX1m.setAttribute("id", "minusX1_" + data.code); - buttonX1m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusX1 + ")"); - buttonX1m.setAttribute("value", "-" + data.plusX1); - cell2.appendChild(buttonX1m); - } - - if (data.hasOwnProperty('plusX2')) { - var buttonX2m = document.createElement("input"); - buttonX2m.setAttribute("type", "button"); - buttonX2m.setAttribute("id", "minusX2_" + data.code); - buttonX2m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusX2 + ")"); - buttonX2m.setAttribute("value", "-" + data.plusX2); - cell2.appendChild(buttonX2m); - } - var button1 = document.createElement("input"); button1.setAttribute("type", "button"); button1.setAttribute("id", "minus_" + data.code); @@ -213,24 +207,6 @@ function addCounter(table, idx, name, data) { button2.setAttribute("value", "+"); cell2.appendChild(button2); - if (data.hasOwnProperty('plusX2')) { - var buttonX2p = document.createElement("input"); - buttonX2p.setAttribute("type", "button"); - buttonX2p.setAttribute("id", "plusX2_" + data.code); - buttonX2p.setAttribute("onclick", "counter(this.parentElement, +" + data.plusX2 + ")"); - buttonX2p.setAttribute("value", "+" + data.plusX2); - cell2.appendChild(buttonX2p); - } - - if (data.hasOwnProperty('plusX1')) { - var buttonX1p = document.createElement("input"); - buttonX1p.setAttribute("type", "button"); - buttonX1p.setAttribute("id", "plusX1_" + data.code); - buttonX1p.setAttribute("onclick", "counter(this.parentElement, +" + data.plusX1 + ")"); - buttonX1p.setAttribute("value", "+" + data.plusX1); - cell2.appendChild(buttonX1p); - } - if (data.hasOwnProperty('cycleTimer')) { if (data.cycleTimer != "") { inp = document.createElement('input'); @@ -1469,4 +1445,3 @@ window.onload = function () { } }; - From 286303067d55805e05118fa62d8c6bcbbe356d19 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 01:18:35 -0600 Subject: [PATCH 06/33] Update scoutingPASS.js --- resources/js/scoutingPASS.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 03787e597..e2ff81e14 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -155,7 +155,7 @@ function addCounter(table, idx, name, data) { cell1.setAttribute("colspan", 2); cell1.setAttribute("style", "text-align: center;"); cell1.style.display = "flex"; - cell.style.gap = "10px"; + cell1.style.gap = "10px"; } cell1.style.width = ColWidth; cell1.classList.add("title"); @@ -1445,3 +1445,4 @@ window.onload = function () { } }; + From e8b1cf40eb2fee9f58e5d9e0982772ccfba8440a Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 01:31:44 -0600 Subject: [PATCH 07/33] Update scoutingPASS.js --- resources/js/scoutingPASS.js | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index e2ff81e14..268a231c5 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -177,6 +177,24 @@ function addCounter(table, idx, name, data) { } cell2.classList.add("field"); + if (data.hasOwnProperty('plusX1')) { + var buttonX1m = document.createElement("input"); + buttonX1m.setAttribute("type", "button"); + buttonX1m.setAttribute("id", "minusX1_" + data.code); + buttonX1m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusX1 + ")"); + buttonX1m.setAttribute("value", "-" + data.plusX1); + cell2.appendChild(buttonX1m); + } + + if (data.hasOwnProperty('plusX2')) { + var buttonX2m = document.createElement("input"); + buttonX2m.setAttribute("type", "button"); + buttonX2m.setAttribute("id", "minusX2_" + data.code); + buttonX2m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusX2 + ")"); + buttonX2m.setAttribute("value", "-" + data.plusX2); + cell2.appendChild(buttonX2m); + } + var button1 = document.createElement("input"); button1.setAttribute("type", "button"); button1.setAttribute("id", "minus_" + data.code); @@ -207,6 +225,24 @@ function addCounter(table, idx, name, data) { button2.setAttribute("value", "+"); cell2.appendChild(button2); + if (data.hasOwnProperty('plusX2')) { + var buttonX2p = document.createElement("input"); + buttonX2p.setAttribute("type", "button"); + buttonX2p.setAttribute("id", "plusX2_" + data.code); + buttonX2p.setAttribute("onclick", "counter(this.parentElement, " + data.plusX2 + ")"); + buttonX2p.setAttribute("value", "+" + data.plusX2); + cell2.appendChild(buttonX2p); + } + + if (data.hasOwnProperty('plusX1')) { + var buttonX1p = document.createElement("input"); + buttonX1p.setAttribute("type", "button"); + buttonX1p.setAttribute("id", "plusX1_" + data.code); + buttonX1p.setAttribute("onclick", "counter(this.parentElement, " + data.plusX1 + ")"); + buttonX1p.setAttribute("value", "+" + data.plusX1); + cell2.appendChild(buttonX1p); + } + if (data.hasOwnProperty('cycleTimer')) { if (data.cycleTimer != "") { inp = document.createElement('input'); @@ -1446,3 +1482,4 @@ window.onload = function () { }; + From adb2e63759caa89033c90cc8af24cb62611923b6 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 01:35:51 -0600 Subject: [PATCH 08/33] Clean up formatting --- resources/js/scoutingPASS.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 268a231c5..1107f9030 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -155,7 +155,7 @@ function addCounter(table, idx, name, data) { cell1.setAttribute("colspan", 2); cell1.setAttribute("style", "text-align: center;"); cell1.style.display = "flex"; - cell1.style.gap = "10px"; + cell1.style.gap = "5px"; } cell1.style.width = ColWidth; cell1.classList.add("title"); @@ -177,6 +177,11 @@ function addCounter(table, idx, name, data) { } cell2.classList.add("field"); + if (data.hasOwnProperty('plusX1') || data.hasOwnProperty('plusX2')) { + var br = document.createElement("br"); + cell2.appendChild(br); + } + if (data.hasOwnProperty('plusX1')) { var buttonX1m = document.createElement("input"); buttonX1m.setAttribute("type", "button"); @@ -1483,3 +1488,4 @@ window.onload = function () { + From abf1b0698f4174b9dcc41124624bf975a1c65b3d Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 01:44:42 -0600 Subject: [PATCH 09/33] Fix formatting --- resources/js/scoutingPASS.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 1107f9030..ae4979414 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -166,22 +166,18 @@ function addCounter(table, idx, name, data) { var cell2 if (data.hasOwnProperty('plusX1') || data.hasOwnProperty('plusX2')) { cell2 = cell1 + cell1.innerHTML = '
' + name + '
'; } else { cell2 = row.insertCell(1); cell2.style.width = ColWidth; + cell1.innerHTML = name + ' '; } - cell1.innerHTML = name + ' '; if (data.hasOwnProperty('tooltip')) { cell1.setAttribute("title", data.tooltip); } cell2.classList.add("field"); - if (data.hasOwnProperty('plusX1') || data.hasOwnProperty('plusX2')) { - var br = document.createElement("br"); - cell2.appendChild(br); - } - if (data.hasOwnProperty('plusX1')) { var buttonX1m = document.createElement("input"); buttonX1m.setAttribute("type", "button"); @@ -266,6 +262,10 @@ function addCounter(table, idx, name, data) { cell2.appendChild(def); } + if (data.hasOwnProperty('plusX1') || data.hasOwnProperty('plusX2')) { + cell1.innerHTML = '
'; + } + return idx + 1; } @@ -1489,3 +1489,4 @@ window.onload = function () { + From 370e0d01ef4811cfd6b72aec43013ca4916970bd Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 13:30:11 -0600 Subject: [PATCH 10/33] Change counter incremental tag --- resources/js/scoutingPASS.js | 65 ++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index ae4979414..947dd93ad 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -151,7 +151,7 @@ function addTimer(table, idx, name, data) { function addCounter(table, idx, name, data) { var row = table.insertRow(idx); var cell1 = row.insertCell(0); - if (data.hasOwnProperty('plusX1') || data.hasOwnProperty('plusX2')) { + if (data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2')) { cell1.setAttribute("colspan", 2); cell1.setAttribute("style", "text-align: center;"); cell1.style.display = "flex"; @@ -163,8 +163,8 @@ function addCounter(table, idx, name, data) { cell1.innerHTML = `Error: No code specified for ${name}`; return idx + 1; } - var cell2 - if (data.hasOwnProperty('plusX1') || data.hasOwnProperty('plusX2')) { + var cell2; + if (data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2')) { cell2 = cell1 cell1.innerHTML = '
' + name + '
'; } else { @@ -178,22 +178,22 @@ function addCounter(table, idx, name, data) { } cell2.classList.add("field"); - if (data.hasOwnProperty('plusX1')) { - var buttonX1m = document.createElement("input"); - buttonX1m.setAttribute("type", "button"); - buttonX1m.setAttribute("id", "minusX1_" + data.code); - buttonX1m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusX1 + ")"); - buttonX1m.setAttribute("value", "-" + data.plusX1); - cell2.appendChild(buttonX1m); + if (data.hasOwnProperty('plusInc1')) { + var buttonInc1m = document.createElement("input"); + buttonInc1m.setAttribute("type", "button"); + buttonInc1m.setAttribute("id", "minusInc1_" + data.code); + buttonInc1m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusInc1 + ")"); + buttonInc1m.setAttribute("value", "-" + data.plusInc1); + cell2.appendChild(buttonInc1m); } - if (data.hasOwnProperty('plusX2')) { - var buttonX2m = document.createElement("input"); - buttonX2m.setAttribute("type", "button"); - buttonX2m.setAttribute("id", "minusX2_" + data.code); - buttonX2m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusX2 + ")"); - buttonX2m.setAttribute("value", "-" + data.plusX2); - cell2.appendChild(buttonX2m); + if (data.hasOwnProperty('plusInc2')) { + var buttonInc2m = document.createElement("input"); + buttonInc2m.setAttribute("type", "button"); + buttonInc2m.setAttribute("id", "minusInc2_" + data.code); + buttonInc2m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusInc2 + ")"); + buttonInc2m.setAttribute("value", "-" + data.plusInc2); + cell2.appendChild(buttonInc2m); } var button1 = document.createElement("input"); @@ -226,22 +226,22 @@ function addCounter(table, idx, name, data) { button2.setAttribute("value", "+"); cell2.appendChild(button2); - if (data.hasOwnProperty('plusX2')) { - var buttonX2p = document.createElement("input"); - buttonX2p.setAttribute("type", "button"); - buttonX2p.setAttribute("id", "plusX2_" + data.code); - buttonX2p.setAttribute("onclick", "counter(this.parentElement, " + data.plusX2 + ")"); - buttonX2p.setAttribute("value", "+" + data.plusX2); - cell2.appendChild(buttonX2p); + if (data.hasOwnProperty('plusInc2')) { + var buttonInc2p = document.createElement("input"); + buttonInc2p.setAttribute("type", "button"); + buttonInc2p.setAttribute("id", "plusInc2_" + data.code); + buttonInc2p.setAttribute("onclick", "counter(this.parentElement, " + data.plusInc2 + ")"); + buttonInc2p.setAttribute("value", "+" + data.plusInc2); + cell2.appendChild(buttonInc2p); } - if (data.hasOwnProperty('plusX1')) { - var buttonX1p = document.createElement("input"); - buttonX1p.setAttribute("type", "button"); - buttonX1p.setAttribute("id", "plusX1_" + data.code); - buttonX1p.setAttribute("onclick", "counter(this.parentElement, " + data.plusX1 + ")"); - buttonX1p.setAttribute("value", "+" + data.plusX1); - cell2.appendChild(buttonX1p); + if (data.hasOwnProperty('plusInc1')) { + var buttonInc1p = document.createElement("input"); + buttonInc1p.setAttribute("type", "button"); + buttonInc1p.setAttribute("id", "plusInc1_" + data.code); + buttonInc1p.setAttribute("onclick", "counter(this.parentElement, " + data.plusInc1 + ")"); + buttonInc1p.setAttribute("value", "+" + data.plusInc1); + cell2.appendChild(buttonInc1p); } if (data.hasOwnProperty('cycleTimer')) { @@ -262,7 +262,7 @@ function addCounter(table, idx, name, data) { cell2.appendChild(def); } - if (data.hasOwnProperty('plusX1') || data.hasOwnProperty('plusX2')) { + if (data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2')) { cell1.innerHTML = '
'; } @@ -1490,3 +1490,4 @@ window.onload = function () { + From ee76672100bb2c5023604154eba5232d0476fbeb Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 13:32:37 -0600 Subject: [PATCH 11/33] Replace plusX1 and plusX2 with plusInc1 and plusInc2 --- 2026/rebuilt_config.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/2026/rebuilt_config.js b/2026/rebuilt_config.js index 67b9dae84..1fc8c846e 100644 --- a/2026/rebuilt_config.js +++ b/2026/rebuilt_config.js @@ -78,15 +78,15 @@ var config_data = ` { "name": "Fuel Scored", "code": "afs", "expectedMax": 32, - "plusX1": 10, - "plusX2": 5, + "plusInc1": 10, + "plusInc2": 5, "type": "counter" }, { "name": "Pass from Neutral Zone", "code": "apn", "expectedMax": 60, - "plusX1": 10, - "plusX2": 5, + "plusInc1": 10, + "plusInc2": 5, "type": "counter" }, { "name": "Climb (L1)", @@ -125,20 +125,22 @@ var config_data = ` { "name": "Fuel Scored", "code": "tfs", "expectedMax": 150, - "plusX1": 10, - "plusX2": 5, + "plusInc1": 10, + "plusInc2": 5, "type": "counter" }, { "name": "Pass from Neutral Zone", "code": "pnz", "expectedMax": 250, - "plusX1": 10, - "plusX2": 5, + "plusInc1": 10, + "plusInc2": 5, "type": "counter" }, { "name": "Pass from Opp
Alliance Zone", "code": "poa", "expectedMax": 250, + "plusInc1": 10, + "plusInc2": 5, "type": "counter" }, { "name": "Pickup from Depot", From 6579067560c1718983e9a16e59eced9a699ca5d6 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 13:41:44 -0600 Subject: [PATCH 12/33] Fix UI bug --- resources/js/scoutingPASS.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 947dd93ad..743ccdcd2 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -262,10 +262,6 @@ function addCounter(table, idx, name, data) { cell2.appendChild(def); } - if (data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2')) { - cell1.innerHTML = ''; - } - return idx + 1; } @@ -1491,3 +1487,4 @@ window.onload = function () { + From fe9cb3ceb0c1e059b9a9f2457d12b846ff95d540 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 13:45:06 -0600 Subject: [PATCH 13/33] Fix UI bug --- resources/js/scoutingPASS.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 743ccdcd2..206584431 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -166,7 +166,7 @@ function addCounter(table, idx, name, data) { var cell2; if (data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2')) { cell2 = cell1 - cell1.innerHTML = '
' + name + '
'; + cell1.innerHTML = name + '
'; } else { cell2 = row.insertCell(1); cell2.style.width = ColWidth; @@ -1488,3 +1488,4 @@ window.onload = function () { + From 2f2114ea826025d950631606f85730fa72e0c5d7 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 14:25:49 -0600 Subject: [PATCH 14/33] Refactor addCounter --- resources/js/scoutingPASS.js | 206 ++++++++++++++++++----------------- 1 file changed, 105 insertions(+), 101 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 206584431..6ddef26d9 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -149,118 +149,121 @@ function addTimer(table, idx, name, data) { } function addCounter(table, idx, name, data) { - var row = table.insertRow(idx); - var cell1 = row.insertCell(0); - if (data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2')) { - cell1.setAttribute("colspan", 2); - cell1.setAttribute("style", "text-align: center;"); - cell1.style.display = "flex"; - cell1.style.gap = "5px"; - } - cell1.style.width = ColWidth; - cell1.classList.add("title"); + const row = table.insertRow(idx); + const hasExtraInc = data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2'); + + // Error Handling if (!data.hasOwnProperty('code')) { - cell1.innerHTML = `Error: No code specified for ${name}`; + const errorCell = row.insertCell(0); + errorCell.classList.add("title"); + errorCell.innerHTML = `Error: No code specified for ${name}`; return idx + 1; - } - var cell2; - if (data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2')) { - cell2 = cell1 - cell1.innerHTML = name + '
'; - } else { - cell2 = row.insertCell(1); - cell2.style.width = ColWidth; - cell1.innerHTML = name + ' '; - } - - if (data.hasOwnProperty('tooltip')) { - cell1.setAttribute("title", data.tooltip); - } - cell2.classList.add("field"); + } + +// 2. Cell Configuration + const cell1 = row.insertCell(0); + let targetCell; // Where the buttons will actually go - if (data.hasOwnProperty('plusInc1')) { - var buttonInc1m = document.createElement("input"); - buttonInc1m.setAttribute("type", "button"); - buttonInc1m.setAttribute("id", "minusInc1_" + data.code); - buttonInc1m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusInc1 + ")"); - buttonInc1m.setAttribute("value", "-" + data.plusInc1); - cell2.appendChild(buttonInc1m); - } - - if (data.hasOwnProperty('plusInc2')) { - var buttonInc2m = document.createElement("input"); - buttonInc2m.setAttribute("type", "button"); - buttonInc2m.setAttribute("id", "minusInc2_" + data.code); - buttonInc2m.setAttribute("onclick", "counter(this.parentElement, -" + data.plusInc2 + ")"); - buttonInc2m.setAttribute("value", "-" + data.plusInc2); - cell2.appendChild(buttonInc2m); - } - - var button1 = document.createElement("input"); - button1.setAttribute("type", "button"); - button1.setAttribute("id", "minus_" + data.code); - button1.setAttribute("onclick", "counter(this.parentElement, -1)"); - button1.setAttribute("value", "-"); - cell2.appendChild(button1); + cell1.style.width = ColWidth; + cell1.classList.add("title"); + if (data.hasOwnProperty('tooltip')) cell1.setAttribute("title", data.tooltip); - var inp = document.createElement("input"); - inp.classList.add("counter"); - inp.setAttribute("id", "input_" + data.code); - inp.setAttribute("type", "text"); - if (enableGoogleSheets && data.hasOwnProperty('gsCol')) { - inp.setAttribute("name", data.gsCol); + if (hasExtraInc) { + cell1.setAttribute("colspan", 2); + // Apply Vertical Stack to the merged cell + Object.assign(cell1.style, { + display: "flex", + flexDirection: "column", + alignItems: "center", + gap: "8px" + }); + + const label = document.createElement("div"); + label.textContent = name; + cell1.appendChild(label); + + targetCell = cell1; } else { - inp.setAttribute("name", data.code); - } - inp.setAttribute("style", "background-color: black; color: white;border: none; text-align: center;"); - inp.setAttribute("disabled", ""); - inp.setAttribute("value", 0); - inp.setAttribute("size", 2); - inp.setAttribute("maxLength", 2); - cell2.appendChild(inp); - - var button2 = document.createElement("input"); - button2.setAttribute("type", "button"); - button2.setAttribute("id", "plus_" + data.code); - button2.setAttribute("onclick", "counter(this.parentElement, 1)"); - button2.setAttribute("value", "+"); - cell2.appendChild(button2); + cell1.innerHTML = `${name} `; + targetCell = row.insertCell(1); + targetCell.style.width = ColWidth; + targetCell.classList.add("field"); + } + + // 3. Create the Horizontal Button Container + const buttonGroup = document.createElement("div"); + Object.assign(buttonGroup.style, { + display: "flex", + flexDirection: "row", + alignItems: "center", + gap: "4px" // Space between buttons + }); + targetCell.appendChild(buttonGroup); + + // 4. Helper function to create inputs + const createInp = (type, id, value, onclickVal) => { + const el = document.createElement("input"); + el.type = type; + if (id) el.id = id; + if (value !== undefined) el.value = value; + if (onclickVal !== undefined) { + el.setAttribute("onclick", `counter(this.parentElement.parentElement, ${onclickVal})`); + } + return el; + }; - if (data.hasOwnProperty('plusInc2')) { - var buttonInc2p = document.createElement("input"); - buttonInc2p.setAttribute("type", "button"); - buttonInc2p.setAttribute("id", "plusInc2_" + data.code); - buttonInc2p.setAttribute("onclick", "counter(this.parentElement, " + data.plusInc2 + ")"); - buttonInc2p.setAttribute("value", "+" + data.plusInc2); - cell2.appendChild(buttonInc2p); - } + // 5. Build Button Group (Negatives -> Input -> Positives) + if (data.plusInc1) buttonGroup.appendChild(createInp("button", `minusInc1_${data.code}`, -data.plusInc1, -data.plusInc1)); + if (data.plusInc2) buttonGroup.appendChild(createInp("button", `minusInc2_${data.code}`, -data.plusInc2, -data.plusInc2)); + + buttonGroup.appendChild(createInp("button", `minus_${data.code}`, "-", -1)); + + const mainInp = createInp("text", `input_${data.code}`, 0); + mainInp.classList.add("counter"); + mainInp.name = (enableGoogleSheets && data.gsCol) ? data.gsCol : data.code; + Object.assign(mainInp.style, { + backgroundColor: "black", + color: "white", + border: "none", + textAlign: "center" + }); + mainInp.disabled = true; + mainInp.size = 2; + mainInp.maxLength = 2; + buttonGroup.appendChild(mainInp); - if (data.hasOwnProperty('plusInc1')) { - var buttonInc1p = document.createElement("input"); - buttonInc1p.setAttribute("type", "button"); - buttonInc1p.setAttribute("id", "plusInc1_" + data.code); - buttonInc1p.setAttribute("onclick", "counter(this.parentElement, " + data.plusInc1 + ")"); - buttonInc1p.setAttribute("value", "+" + data.plusInc1); - cell2.appendChild(buttonInc1p); - } + buttonGroup.appendChild(createInp("button", `plus_${data.code}`, "+", 1)); + + if (data.plusInc2) buttonGroup.appendChild(createInp("button", `plusInc2_${data.code}`, `+${data.plusInc2}`, data.plusInc2)); + if (data.plusInc1) buttonGroup.appendChild(createInp("button", `plusInc1_${data.code}`, `+${data.plusInc1}`, data.plusInc1)); - if (data.hasOwnProperty('cycleTimer')) { - if (data.cycleTimer != "") { - inp = document.createElement('input'); - inp.setAttribute("hidden", ""); - inp.setAttribute("id", "cycleTimer_" + data.code); - inp.setAttribute("value", data.cycleTimer); - cell.appendChild(inp); - } + // 6. Metadata / Hidden Fields + if (data.cycleTimer) { + const timer = createInp("hidden", `cycleTimer_${data.code}`, data.cycleTimer); + targetCell.appendChild(timer); } if (data.hasOwnProperty('defaultValue')) { - var def = document.createElement("input"); - def.setAttribute("id", "default_" + data.code) - def.setAttribute("type", "hidden"); - def.setAttribute("value", data.defaultValue); - cell2.appendChild(def); - } + const def = createInp("hidden", `default_${data.code}`, data.defaultValue); + targetCell.appendChild(def); + } + // if (data.hasOwnProperty('cycleTimer')) { + // if (data.cycleTimer != "") { + // inp = document.createElement('input'); + // inp.setAttribute("hidden", ""); + // inp.setAttribute("id", "cycleTimer_" + data.code); + // inp.setAttribute("value", data.cycleTimer); + // cell.appendChild(inp); + // } + // } + + // if (data.hasOwnProperty('defaultValue')) { + // var def = document.createElement("input"); + // def.setAttribute("id", "default_" + data.code) + // def.setAttribute("type", "hidden"); + // def.setAttribute("value", data.defaultValue); + // cell2.appendChild(def); + // } return idx + 1; } @@ -1489,3 +1492,4 @@ window.onload = function () { + From 01022343ad1a454ef19ac3a971ed793563aa939f Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 14:33:32 -0600 Subject: [PATCH 15/33] Fix centering issue --- resources/js/scoutingPASS.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 6ddef26d9..c31fc00ec 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -172,9 +172,11 @@ function addCounter(table, idx, name, data) { cell1.setAttribute("colspan", 2); // Apply Vertical Stack to the merged cell Object.assign(cell1.style, { - display: "flex", + display: "flex", flexDirection: "column", alignItems: "center", + justifyContent: "center", + width: "100%", gap: "8px" }); @@ -1493,3 +1495,4 @@ window.onload = function () { + From 8260ef44588211764f80e67c2f495c41bacd3cf3 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 14:48:58 -0600 Subject: [PATCH 16/33] Fix UI bug --- resources/js/scoutingPASS.js | 46 ++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index c31fc00ec..0de3b1428 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -159,25 +159,26 @@ function addCounter(table, idx, name, data) { errorCell.innerHTML = `Error: No code specified for ${name}`; return idx + 1; } - -// 2. Cell Configuration + const cell1 = row.insertCell(0); - let targetCell; // Where the buttons will actually go + let targetCell; - cell1.style.width = ColWidth; cell1.classList.add("title"); if (data.hasOwnProperty('tooltip')) cell1.setAttribute("title", data.tooltip); if (hasExtraInc) { cell1.setAttribute("colspan", 2); - // Apply Vertical Stack to the merged cell + + // THE FIX: Ensure the flex container fills the entire TD width Object.assign(cell1.style, { - display: "flex", + display: "flex", flexDirection: "column", - alignItems: "center", - justifyContent: "center", - width: "100%", - gap: "8px" + alignItems: "center", // Centers items horizontally in a column + justifyContent: "center", // Centers items vertically if there's extra height + width: "100%", // Forces flexbox to span the whole cell + boxSizing: "border-box", + gap: "8px", + textAlign: "center" // Fallback for non-flex browsers }); const label = document.createElement("div"); @@ -186,35 +187,41 @@ function addCounter(table, idx, name, data) { targetCell = cell1; } else { + cell1.style.width = ColWidth; cell1.innerHTML = `${name} `; targetCell = row.insertCell(1); targetCell.style.width = ColWidth; targetCell.classList.add("field"); + // Also center the second cell in standard mode + targetCell.style.textAlign = "center"; } - // 3. Create the Horizontal Button Container + // 3. Button Container Alignment const buttonGroup = document.createElement("div"); Object.assign(buttonGroup.style, { display: "flex", flexDirection: "row", alignItems: "center", - gap: "4px" // Space between buttons + justifyContent: "center", // Ensures buttons stay centered in their row + gap: "4px", + width: "100%" }); targetCell.appendChild(buttonGroup); - // 4. Helper function to create inputs + // 4. Helper function const createInp = (type, id, value, onclickVal) => { const el = document.createElement("input"); el.type = type; if (id) el.id = id; if (value !== undefined) el.value = value; if (onclickVal !== undefined) { + // Logic: button -> buttonGroup -> cell el.setAttribute("onclick", `counter(this.parentElement.parentElement, ${onclickVal})`); } return el; }; - // 5. Build Button Group (Negatives -> Input -> Positives) + // 5. Build Button Group if (data.plusInc1) buttonGroup.appendChild(createInp("button", `minusInc1_${data.code}`, -data.plusInc1, -data.plusInc1)); if (data.plusInc2) buttonGroup.appendChild(createInp("button", `minusInc2_${data.code}`, -data.plusInc2, -data.plusInc2)); @@ -223,12 +230,7 @@ function addCounter(table, idx, name, data) { const mainInp = createInp("text", `input_${data.code}`, 0); mainInp.classList.add("counter"); mainInp.name = (enableGoogleSheets && data.gsCol) ? data.gsCol : data.code; - Object.assign(mainInp.style, { - backgroundColor: "black", - color: "white", - border: "none", - textAlign: "center" - }); + Object.assign(mainInp.style, { backgroundColor: "black", color: "white", border: "none", textAlign: "center" }); mainInp.disabled = true; mainInp.size = 2; mainInp.maxLength = 2; @@ -239,7 +241,7 @@ function addCounter(table, idx, name, data) { if (data.plusInc2) buttonGroup.appendChild(createInp("button", `plusInc2_${data.code}`, `+${data.plusInc2}`, data.plusInc2)); if (data.plusInc1) buttonGroup.appendChild(createInp("button", `plusInc1_${data.code}`, `+${data.plusInc1}`, data.plusInc1)); - // 6. Metadata / Hidden Fields + // 6. Metadata if (data.cycleTimer) { const timer = createInp("hidden", `cycleTimer_${data.code}`, data.cycleTimer); targetCell.appendChild(timer); @@ -249,6 +251,7 @@ function addCounter(table, idx, name, data) { const def = createInp("hidden", `default_${data.code}`, data.defaultValue); targetCell.appendChild(def); } + // if (data.hasOwnProperty('cycleTimer')) { // if (data.cycleTimer != "") { // inp = document.createElement('input'); @@ -1496,3 +1499,4 @@ window.onload = function () { + From 57184420c7ffeed956c55c9473df48017dd458f6 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 15:10:52 -0600 Subject: [PATCH 17/33] Fix UI bug --- resources/js/scoutingPASS.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 0de3b1428..ade128c04 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -177,7 +177,8 @@ function addCounter(table, idx, name, data) { justifyContent: "center", // Centers items vertically if there's extra height width: "100%", // Forces flexbox to span the whole cell boxSizing: "border-box", - gap: "8px", + margin: "0 auto", + gap: "8px", textAlign: "center" // Fallback for non-flex browsers }); @@ -1500,3 +1501,4 @@ window.onload = function () { + From cd4be7a4cb9ef528a2269594c03d3ab07e11ca1b Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 15:18:38 -0600 Subject: [PATCH 18/33] Fix UI Bug --- resources/js/scoutingPASS.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index ade128c04..8b50a04cd 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -169,17 +169,17 @@ function addCounter(table, idx, name, data) { if (hasExtraInc) { cell1.setAttribute("colspan", 2); - // THE FIX: Ensure the flex container fills the entire TD width + cell1.style.width = "auto"; + cell1.style.textAlign = "center"; + Object.assign(cell1.style, { - display: "flex", - flexDirection: "column", - alignItems: "center", // Centers items horizontally in a column - justifyContent: "center", // Centers items vertically if there's extra height - width: "100%", // Forces flexbox to span the whole cell + display: "inline-flex", + flexDirection: "column", + alignItems: "center", + justifyContent: "center", + width: "100%", boxSizing: "border-box", - margin: "0 auto", - gap: "8px", - textAlign: "center" // Fallback for non-flex browsers + gap: "8px" }); const label = document.createElement("div"); @@ -1502,3 +1502,4 @@ window.onload = function () { + From d7b40d02c984deb54b22864b7f6df2c40d464800 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 15:31:03 -0600 Subject: [PATCH 19/33] Fix UI bug --- resources/js/scoutingPASS.js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 8b50a04cd..02a4dc012 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -197,19 +197,20 @@ function addCounter(table, idx, name, data) { targetCell.style.textAlign = "center"; } - // 3. Button Container Alignment + targetCell.style.textAlign = "center"; + + // Button Container Alignment const buttonGroup = document.createElement("div"); Object.assign(buttonGroup.style, { - display: "flex", + display: "inline-flex", flexDirection: "row", alignItems: "center", justifyContent: "center", // Ensures buttons stay centered in their row - gap: "4px", - width: "100%" + gap: "4px" }); targetCell.appendChild(buttonGroup); - // 4. Helper function + // Helper function const createInp = (type, id, value, onclickVal) => { const el = document.createElement("input"); el.type = type; @@ -222,7 +223,7 @@ function addCounter(table, idx, name, data) { return el; }; - // 5. Build Button Group + // Build Button Group if (data.plusInc1) buttonGroup.appendChild(createInp("button", `minusInc1_${data.code}`, -data.plusInc1, -data.plusInc1)); if (data.plusInc2) buttonGroup.appendChild(createInp("button", `minusInc2_${data.code}`, -data.plusInc2, -data.plusInc2)); @@ -231,10 +232,15 @@ function addCounter(table, idx, name, data) { const mainInp = createInp("text", `input_${data.code}`, 0); mainInp.classList.add("counter"); mainInp.name = (enableGoogleSheets && data.gsCol) ? data.gsCol : data.code; - Object.assign(mainInp.style, { backgroundColor: "black", color: "white", border: "none", textAlign: "center" }); + Object.assign(mainInp.style, { + backgroundColor: "black", + color: "white", + border: "none", + textAlign: "center", + width: "3ch", + }); mainInp.disabled = true; - mainInp.size = 2; - mainInp.maxLength = 2; + mainInp.maxLength = 4; buttonGroup.appendChild(mainInp); buttonGroup.appendChild(createInp("button", `plus_${data.code}`, "+", 1)); @@ -242,7 +248,7 @@ function addCounter(table, idx, name, data) { if (data.plusInc2) buttonGroup.appendChild(createInp("button", `plusInc2_${data.code}`, `+${data.plusInc2}`, data.plusInc2)); if (data.plusInc1) buttonGroup.appendChild(createInp("button", `plusInc1_${data.code}`, `+${data.plusInc1}`, data.plusInc1)); - // 6. Metadata + // Metadata if (data.cycleTimer) { const timer = createInp("hidden", `cycleTimer_${data.code}`, data.cycleTimer); targetCell.appendChild(timer); @@ -1503,3 +1509,4 @@ window.onload = function () { + From 49b4f826977a60cfa6b8bfaf8471c4543c0a98e2 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 15:40:20 -0600 Subject: [PATCH 20/33] Fix UI bug --- resources/js/scoutingPASS.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 02a4dc012..d72c9f336 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -169,16 +169,13 @@ function addCounter(table, idx, name, data) { if (hasExtraInc) { cell1.setAttribute("colspan", 2); - cell1.style.width = "auto"; cell1.style.textAlign = "center"; Object.assign(cell1.style, { - display: "inline-flex", + display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", - width: "100%", - boxSizing: "border-box", gap: "8px" }); @@ -1510,3 +1507,4 @@ window.onload = function () { + From 45f4ef95bee41dc607f01f90d2c6212a273ddb8a Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 19:48:37 -0600 Subject: [PATCH 21/33] Fix UI bug --- resources/js/scoutingPASS.js | 304 ++++++++++++++++++++++++----------- 1 file changed, 212 insertions(+), 92 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index d72c9f336..bc76dc03e 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -148,6 +148,135 @@ function addTimer(table, idx, name, data) { return idx + 1; } +// function addCounter(table, idx, name, data) { +// const row = table.insertRow(idx); +// const hasExtraInc = data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2'); + +// // Error Handling +// if (!data.hasOwnProperty('code')) { +// const errorCell = row.insertCell(0); +// errorCell.classList.add("title"); +// errorCell.innerHTML = `Error: No code specified for ${name}`; +// return idx + 1; +// } + +// const cell1 = row.insertCell(0); +// let targetCell; + +// cell1.classList.add("title"); +// if (data.hasOwnProperty('tooltip')) cell1.setAttribute("title", data.tooltip); + +// if (hasExtraInc) { +// cell1.setAttribute("colspan", 2); + +// cell1.style.textAlign = "center"; + +// Object.assign(cell1.style, { +// display: "flex", +// flexDirection: "column", +// alignItems: "center", +// justifyContent: "center", +// gap: "8px" +// }); + +// const label = document.createElement("div"); +// label.textContent = name; +// cell1.appendChild(label); + +// targetCell = cell1; +// } else { +// cell1.style.width = ColWidth; +// cell1.innerHTML = `${name} `; +// targetCell = row.insertCell(1); +// targetCell.style.width = ColWidth; +// targetCell.classList.add("field"); +// // Also center the second cell in standard mode +// targetCell.style.textAlign = "center"; +// } + +// targetCell.style.textAlign = "center"; + +// // Button Container Alignment +// const buttonGroup = document.createElement("div"); +// Object.assign(buttonGroup.style, { +// display: "inline-flex", +// flexDirection: "row", +// alignItems: "center", +// justifyContent: "center", // Ensures buttons stay centered in their row +// gap: "4px" +// }); +// targetCell.appendChild(buttonGroup); + +// // Helper function +// const createInp = (type, id, value, onclickVal) => { +// const el = document.createElement("input"); +// el.type = type; +// if (id) el.id = id; +// if (value !== undefined) el.value = value; +// if (onclickVal !== undefined) { +// // Logic: button -> buttonGroup -> cell +// el.setAttribute("onclick", `counter(this.parentElement.parentElement, ${onclickVal})`); +// } +// return el; +// }; + +// // Build Button Group +// if (data.plusInc1) buttonGroup.appendChild(createInp("button", `minusInc1_${data.code}`, -data.plusInc1, -data.plusInc1)); +// if (data.plusInc2) buttonGroup.appendChild(createInp("button", `minusInc2_${data.code}`, -data.plusInc2, -data.plusInc2)); + +// buttonGroup.appendChild(createInp("button", `minus_${data.code}`, "-", -1)); + +// const mainInp = createInp("text", `input_${data.code}`, 0); +// mainInp.classList.add("counter"); +// mainInp.name = (enableGoogleSheets && data.gsCol) ? data.gsCol : data.code; +// Object.assign(mainInp.style, { +// backgroundColor: "black", +// color: "white", +// border: "none", +// textAlign: "center", +// width: "3ch", +// }); +// mainInp.disabled = true; +// mainInp.maxLength = 4; +// buttonGroup.appendChild(mainInp); + +// buttonGroup.appendChild(createInp("button", `plus_${data.code}`, "+", 1)); + +// if (data.plusInc2) buttonGroup.appendChild(createInp("button", `plusInc2_${data.code}`, `+${data.plusInc2}`, data.plusInc2)); +// if (data.plusInc1) buttonGroup.appendChild(createInp("button", `plusInc1_${data.code}`, `+${data.plusInc1}`, data.plusInc1)); + +// // Metadata +// if (data.cycleTimer) { +// const timer = createInp("hidden", `cycleTimer_${data.code}`, data.cycleTimer); +// targetCell.appendChild(timer); +// } + +// if (data.hasOwnProperty('defaultValue')) { +// const def = createInp("hidden", `default_${data.code}`, data.defaultValue); +// targetCell.appendChild(def); +// } + +// // if (data.hasOwnProperty('cycleTimer')) { +// // if (data.cycleTimer != "") { +// // inp = document.createElement('input'); +// // inp.setAttribute("hidden", ""); +// // inp.setAttribute("id", "cycleTimer_" + data.code); +// // inp.setAttribute("value", data.cycleTimer); +// // cell.appendChild(inp); +// // } +// // } + +// // if (data.hasOwnProperty('defaultValue')) { +// // var def = document.createElement("input"); +// // def.setAttribute("id", "default_" + data.code) +// // def.setAttribute("type", "hidden"); +// // def.setAttribute("value", data.defaultValue); +// // cell2.appendChild(def); +// // } + +// return idx + 1; +// } + function addCounter(table, idx, name, data) { const row = table.insertRow(idx); const hasExtraInc = data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2'); @@ -158,121 +287,111 @@ function addCounter(table, idx, name, data) { errorCell.classList.add("title"); errorCell.innerHTML = `Error: No code specified for ${name}`; return idx + 1; - } + } - const cell1 = row.insertCell(0); - let targetCell; + // Create title cell + const titleCell = row.insertCell(0); + titleCell.classList.add("title"); + if (data.hasOwnProperty('tooltip')) { + titleCell.setAttribute("title", data.tooltip); + } - cell1.classList.add("title"); - if (data.hasOwnProperty('tooltip')) cell1.setAttribute("title", data.tooltip); + let controlCell; if (hasExtraInc) { - cell1.setAttribute("colspan", 2); + // When extra increments exist, use a single cell with colspan + titleCell.setAttribute("colspan", 2); + titleCell.style.cssText = 'text-align: center; vertical-align: middle;'; - cell1.style.textAlign = "center"; - - Object.assign(cell1.style, { - display: "flex", - flexDirection: "column", - alignItems: "center", - justifyContent: "center", - gap: "8px" - }); + // Create wrapper div for flex layout + const wrapper = document.createElement("div"); + wrapper.style.cssText = 'display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%;'; + // Create label const label = document.createElement("div"); label.textContent = name; - cell1.appendChild(label); + label.style.cssText = 'margin-bottom: 8px;'; + wrapper.appendChild(label); - targetCell = cell1; + titleCell.appendChild(wrapper); + controlCell = wrapper; } else { - cell1.style.width = ColWidth; - cell1.innerHTML = `${name} `; - targetCell = row.insertCell(1); - targetCell.style.width = ColWidth; - targetCell.classList.add("field"); - // Also center the second cell in standard mode - targetCell.style.textAlign = "center"; + // Standard two-cell layout + titleCell.style.width = ColWidth; + titleCell.innerHTML = `${name} `; + + controlCell = row.insertCell(1); + controlCell.style.width = ColWidth; + controlCell.classList.add("field"); + controlCell.style.cssText = 'text-align: center !important; vertical-align: middle;'; } - targetCell.style.textAlign = "center"; - - // Button Container Alignment + // Create centered container for buttons + const centerContainer = document.createElement("div"); + centerContainer.style.cssText = 'display: flex; justify-content: center; align-items: center; width: 100%;'; + + // Create button group const buttonGroup = document.createElement("div"); - Object.assign(buttonGroup.style, { - display: "inline-flex", - flexDirection: "row", - alignItems: "center", - justifyContent: "center", // Ensures buttons stay centered in their row - gap: "4px" - }); - targetCell.appendChild(buttonGroup); - - // Helper function - const createInp = (type, id, value, onclickVal) => { - const el = document.createElement("input"); - el.type = type; - if (id) el.id = id; - if (value !== undefined) el.value = value; - if (onclickVal !== undefined) { - // Logic: button -> buttonGroup -> cell - el.setAttribute("onclick", `counter(this.parentElement.parentElement, ${onclickVal})`); + buttonGroup.style.cssText = 'display: inline-flex; align-items: center; gap: 4px;'; + + // Helper to create input elements + const createInput = (type, id, value, incrementValue) => { + const input = document.createElement("input"); + input.type = type; + if (id) input.id = id; + if (value !== undefined) input.value = value; + if (incrementValue !== undefined) { + input.onclick = function() { + counter(this.parentElement.parentElement.parentElement, incrementValue); + }; } - return el; + return input; }; - // Build Button Group - if (data.plusInc1) buttonGroup.appendChild(createInp("button", `minusInc1_${data.code}`, -data.plusInc1, -data.plusInc1)); - if (data.plusInc2) buttonGroup.appendChild(createInp("button", `minusInc2_${data.code}`, -data.plusInc2, -data.plusInc2)); + // Build buttons from left to right + if (data.plusInc1) { + buttonGroup.appendChild(createInput("button", `minusInc1_${data.code}`, -data.plusInc1, -data.plusInc1)); + } - buttonGroup.appendChild(createInp("button", `minus_${data.code}`, "-", -1)); - - const mainInp = createInp("text", `input_${data.code}`, 0); - mainInp.classList.add("counter"); - mainInp.name = (enableGoogleSheets && data.gsCol) ? data.gsCol : data.code; - Object.assign(mainInp.style, { - backgroundColor: "black", - color: "white", - border: "none", - textAlign: "center", - width: "3ch", - }); - mainInp.disabled = true; - mainInp.maxLength = 4; - buttonGroup.appendChild(mainInp); - - buttonGroup.appendChild(createInp("button", `plus_${data.code}`, "+", 1)); + if (data.plusInc2) { + buttonGroup.appendChild(createInput("button", `minusInc2_${data.code}`, -data.plusInc2, -data.plusInc2)); + } - if (data.plusInc2) buttonGroup.appendChild(createInp("button", `plusInc2_${data.code}`, `+${data.plusInc2}`, data.plusInc2)); - if (data.plusInc1) buttonGroup.appendChild(createInp("button", `plusInc1_${data.code}`, `+${data.plusInc1}`, data.plusInc1)); + buttonGroup.appendChild(createInput("button", `minus_${data.code}`, "-", -1)); + + // Create main counter input + const counterInput = createInput("text", `input_${data.code}`, 0); + counterInput.classList.add("counter"); + counterInput.name = (enableGoogleSheets && data.gsCol) ? data.gsCol : data.code; + counterInput.disabled = true; + counterInput.maxLength = 4; + counterInput.style.cssText = 'background-color: black; color: white; border: none; text-align: center; width: 3ch;'; + buttonGroup.appendChild(counterInput); + + buttonGroup.appendChild(createInput("button", `plus_${data.code}`, "+", 1)); + + if (data.plusInc2) { + buttonGroup.appendChild(createInput("button", `plusInc2_${data.code}`, `+${data.plusInc2}`, data.plusInc2)); + } + + if (data.plusInc1) { + buttonGroup.appendChild(createInput("button", `plusInc1_${data.code}`, `+${data.plusInc1}`, data.plusInc1)); + } - // Metadata + // Nest: centerContainer -> buttonGroup + centerContainer.appendChild(buttonGroup); + controlCell.appendChild(centerContainer); + + // Add hidden metadata fields directly to controlCell if (data.cycleTimer) { - const timer = createInp("hidden", `cycleTimer_${data.code}`, data.cycleTimer); - targetCell.appendChild(timer); + const timerInput = createInput("hidden", `cycleTimer_${data.code}`, data.cycleTimer); + controlCell.appendChild(timerInput); } if (data.hasOwnProperty('defaultValue')) { - const def = createInp("hidden", `default_${data.code}`, data.defaultValue); - targetCell.appendChild(def); - } - - // if (data.hasOwnProperty('cycleTimer')) { - // if (data.cycleTimer != "") { - // inp = document.createElement('input'); - // inp.setAttribute("hidden", ""); - // inp.setAttribute("id", "cycleTimer_" + data.code); - // inp.setAttribute("value", data.cycleTimer); - // cell.appendChild(inp); - // } - // } - - // if (data.hasOwnProperty('defaultValue')) { - // var def = document.createElement("input"); - // def.setAttribute("id", "default_" + data.code) - // def.setAttribute("type", "hidden"); - // def.setAttribute("value", data.defaultValue); - // cell2.appendChild(def); - // } + const defaultInput = createInput("hidden", `default_${data.code}`, data.defaultValue); + controlCell.appendChild(defaultInput); + } return idx + 1; } @@ -1508,3 +1627,4 @@ window.onload = function () { + From 09b889c4d03d48225265635c2e5c01c9729d1278 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 19:53:37 -0600 Subject: [PATCH 22/33] Update button spacing --- resources/js/scoutingPASS.js | 132 +---------------------------------- 1 file changed, 2 insertions(+), 130 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index bc76dc03e..f663cabf7 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -148,135 +148,6 @@ function addTimer(table, idx, name, data) { return idx + 1; } -// function addCounter(table, idx, name, data) { -// const row = table.insertRow(idx); -// const hasExtraInc = data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2'); - -// // Error Handling -// if (!data.hasOwnProperty('code')) { -// const errorCell = row.insertCell(0); -// errorCell.classList.add("title"); -// errorCell.innerHTML = `Error: No code specified for ${name}`; -// return idx + 1; -// } - -// const cell1 = row.insertCell(0); -// let targetCell; - -// cell1.classList.add("title"); -// if (data.hasOwnProperty('tooltip')) cell1.setAttribute("title", data.tooltip); - -// if (hasExtraInc) { -// cell1.setAttribute("colspan", 2); - -// cell1.style.textAlign = "center"; - -// Object.assign(cell1.style, { -// display: "flex", -// flexDirection: "column", -// alignItems: "center", -// justifyContent: "center", -// gap: "8px" -// }); - -// const label = document.createElement("div"); -// label.textContent = name; -// cell1.appendChild(label); - -// targetCell = cell1; -// } else { -// cell1.style.width = ColWidth; -// cell1.innerHTML = `${name} `; -// targetCell = row.insertCell(1); -// targetCell.style.width = ColWidth; -// targetCell.classList.add("field"); -// // Also center the second cell in standard mode -// targetCell.style.textAlign = "center"; -// } - -// targetCell.style.textAlign = "center"; - -// // Button Container Alignment -// const buttonGroup = document.createElement("div"); -// Object.assign(buttonGroup.style, { -// display: "inline-flex", -// flexDirection: "row", -// alignItems: "center", -// justifyContent: "center", // Ensures buttons stay centered in their row -// gap: "4px" -// }); -// targetCell.appendChild(buttonGroup); - -// // Helper function -// const createInp = (type, id, value, onclickVal) => { -// const el = document.createElement("input"); -// el.type = type; -// if (id) el.id = id; -// if (value !== undefined) el.value = value; -// if (onclickVal !== undefined) { -// // Logic: button -> buttonGroup -> cell -// el.setAttribute("onclick", `counter(this.parentElement.parentElement, ${onclickVal})`); -// } -// return el; -// }; - -// // Build Button Group -// if (data.plusInc1) buttonGroup.appendChild(createInp("button", `minusInc1_${data.code}`, -data.plusInc1, -data.plusInc1)); -// if (data.plusInc2) buttonGroup.appendChild(createInp("button", `minusInc2_${data.code}`, -data.plusInc2, -data.plusInc2)); - -// buttonGroup.appendChild(createInp("button", `minus_${data.code}`, "-", -1)); - -// const mainInp = createInp("text", `input_${data.code}`, 0); -// mainInp.classList.add("counter"); -// mainInp.name = (enableGoogleSheets && data.gsCol) ? data.gsCol : data.code; -// Object.assign(mainInp.style, { -// backgroundColor: "black", -// color: "white", -// border: "none", -// textAlign: "center", -// width: "3ch", -// }); -// mainInp.disabled = true; -// mainInp.maxLength = 4; -// buttonGroup.appendChild(mainInp); - -// buttonGroup.appendChild(createInp("button", `plus_${data.code}`, "+", 1)); - -// if (data.plusInc2) buttonGroup.appendChild(createInp("button", `plusInc2_${data.code}`, `+${data.plusInc2}`, data.plusInc2)); -// if (data.plusInc1) buttonGroup.appendChild(createInp("button", `plusInc1_${data.code}`, `+${data.plusInc1}`, data.plusInc1)); - -// // Metadata -// if (data.cycleTimer) { -// const timer = createInp("hidden", `cycleTimer_${data.code}`, data.cycleTimer); -// targetCell.appendChild(timer); -// } - -// if (data.hasOwnProperty('defaultValue')) { -// const def = createInp("hidden", `default_${data.code}`, data.defaultValue); -// targetCell.appendChild(def); -// } - -// // if (data.hasOwnProperty('cycleTimer')) { -// // if (data.cycleTimer != "") { -// // inp = document.createElement('input'); -// // inp.setAttribute("hidden", ""); -// // inp.setAttribute("id", "cycleTimer_" + data.code); -// // inp.setAttribute("value", data.cycleTimer); -// // cell.appendChild(inp); -// // } -// // } - -// // if (data.hasOwnProperty('defaultValue')) { -// // var def = document.createElement("input"); -// // def.setAttribute("id", "default_" + data.code) -// // def.setAttribute("type", "hidden"); -// // def.setAttribute("value", data.defaultValue); -// // cell2.appendChild(def); -// // } - -// return idx + 1; -// } - function addCounter(table, idx, name, data) { const row = table.insertRow(idx); const hasExtraInc = data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2'); @@ -310,7 +181,7 @@ function addCounter(table, idx, name, data) { // Create label const label = document.createElement("div"); label.textContent = name; - label.style.cssText = 'margin-bottom: 8px;'; + label.style.cssText = 'margin-bottom: 12px;'; wrapper.appendChild(label); titleCell.appendChild(wrapper); @@ -1628,3 +1499,4 @@ window.onload = function () { + From d05e5fb6b704a6e96693e59832e46400abb1907d Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 19:58:27 -0600 Subject: [PATCH 23/33] Update button spacing --- resources/js/scoutingPASS.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index f663cabf7..fc7937845 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -181,7 +181,7 @@ function addCounter(table, idx, name, data) { // Create label const label = document.createElement("div"); label.textContent = name; - label.style.cssText = 'margin-bottom: 12px;'; + label.style.cssText = 'margin-bottom: 20px;'; wrapper.appendChild(label); titleCell.appendChild(wrapper); @@ -1500,3 +1500,4 @@ window.onload = function () { + From e3e82fe9c4935436124357fe86f5ada4454ba315 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 20:09:29 -0600 Subject: [PATCH 24/33] Disable double-click zoom when clicking buttons --- resources/js/scoutingPASS.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index fc7937845..eb649b588 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -215,6 +215,10 @@ function addCounter(table, idx, name, data) { input.onclick = function() { counter(this.parentElement.parentElement.parentElement, incrementValue); }; + } + // Prevent double-tap zoom on buttons + if (type === "button") { + input.style.touchAction = 'manipulation'; } return input; }; @@ -1501,3 +1505,4 @@ window.onload = function () { + From fb3000807cd3ea9a546ed61b92dbdeef9f4216a7 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 21:35:27 -0600 Subject: [PATCH 25/33] Update button spacing --- resources/js/scoutingPASS.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index eb649b588..76a81c995 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -181,7 +181,7 @@ function addCounter(table, idx, name, data) { // Create label const label = document.createElement("div"); label.textContent = name; - label.style.cssText = 'margin-bottom: 20px;'; + label.style.cssText = 'margin-bottom: 4px;'; wrapper.appendChild(label); titleCell.appendChild(wrapper); @@ -203,7 +203,7 @@ function addCounter(table, idx, name, data) { // Create button group const buttonGroup = document.createElement("div"); - buttonGroup.style.cssText = 'display: inline-flex; align-items: center; gap: 4px;'; + buttonGroup.style.cssText = 'display: inline-flex; align-items: center; gap: 10px;'; // Helper to create input elements const createInput = (type, id, value, incrementValue) => { @@ -1506,3 +1506,4 @@ window.onload = function () { + From 923586430e848cc6f4b820be7a8cf53a9e8ca003 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 22:14:21 -0600 Subject: [PATCH 26/33] Rename alternative increment buttons --- resources/js/scoutingPASS.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/resources/js/scoutingPASS.js b/resources/js/scoutingPASS.js index 76a81c995..ca83ba4bd 100644 --- a/resources/js/scoutingPASS.js +++ b/resources/js/scoutingPASS.js @@ -150,7 +150,7 @@ function addTimer(table, idx, name, data) { function addCounter(table, idx, name, data) { const row = table.insertRow(idx); - const hasExtraInc = data.hasOwnProperty('plusInc1') || data.hasOwnProperty('plusInc2'); + const hasExtraInc = data.hasOwnProperty('altInc1') || data.hasOwnProperty('altInc2'); // Error Handling if (!data.hasOwnProperty('code')) { @@ -224,12 +224,12 @@ function addCounter(table, idx, name, data) { }; // Build buttons from left to right - if (data.plusInc1) { - buttonGroup.appendChild(createInput("button", `minusInc1_${data.code}`, -data.plusInc1, -data.plusInc1)); + if (data.altInc1) { + buttonGroup.appendChild(createInput("button", `minusInc1_${data.code}`, -data.altInc1, -data.altInc1)); } - if (data.plusInc2) { - buttonGroup.appendChild(createInput("button", `minusInc2_${data.code}`, -data.plusInc2, -data.plusInc2)); + if (data.altInc2) { + buttonGroup.appendChild(createInput("button", `minusInc2_${data.code}`, -data.altInc2, -data.altInc2)); } buttonGroup.appendChild(createInput("button", `minus_${data.code}`, "-", -1)); @@ -245,12 +245,12 @@ function addCounter(table, idx, name, data) { buttonGroup.appendChild(createInput("button", `plus_${data.code}`, "+", 1)); - if (data.plusInc2) { - buttonGroup.appendChild(createInput("button", `plusInc2_${data.code}`, `+${data.plusInc2}`, data.plusInc2)); + if (data.altInc2) { + buttonGroup.appendChild(createInput("button", `plusInc2_${data.code}`, `+${data.altInc2}`, data.altInc2)); } - if (data.plusInc1) { - buttonGroup.appendChild(createInput("button", `plusInc1_${data.code}`, `+${data.plusInc1}`, data.plusInc1)); + if (data.altInc1) { + buttonGroup.appendChild(createInput("button", `plusInc1_${data.code}`, `+${data.altInc1}`, data.altInc1)); } // Nest: centerContainer -> buttonGroup @@ -1506,4 +1506,5 @@ window.onload = function () { + From a78aee37b6329ca8ea4ea6ac44f2a21223cd1237 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 22:16:29 -0600 Subject: [PATCH 27/33] Rename alternative increment buttons --- 2026/rebuilt_config.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/2026/rebuilt_config.js b/2026/rebuilt_config.js index 1fc8c846e..35dd7bdd7 100644 --- a/2026/rebuilt_config.js +++ b/2026/rebuilt_config.js @@ -78,15 +78,15 @@ var config_data = ` { "name": "Fuel Scored", "code": "afs", "expectedMax": 32, - "plusInc1": 10, - "plusInc2": 5, + "altInc1": 10, + "altInc2": 5, "type": "counter" }, { "name": "Pass from Neutral Zone", "code": "apn", "expectedMax": 60, - "plusInc1": 10, - "plusInc2": 5, + "altInc1": 10, + "altInc2": 5, "type": "counter" }, { "name": "Climb (L1)", @@ -125,22 +125,22 @@ var config_data = ` { "name": "Fuel Scored", "code": "tfs", "expectedMax": 150, - "plusInc1": 10, - "plusInc2": 5, + "altInc1": 10, + "altInc2": 5, "type": "counter" }, { "name": "Pass from Neutral Zone", "code": "pnz", "expectedMax": 250, - "plusInc1": 10, - "plusInc2": 5, + "altInc1": 10, + "altInc2": 5, "type": "counter" }, { "name": "Pass from Opp
Alliance Zone", "code": "poa", "expectedMax": 250, - "plusInc1": 10, - "plusInc2": 5, + "altInc1": 10, + "altInc2": 5, "type": "counter" }, { "name": "Pickup from Depot", From 8b62da424d201628b4b3ab49b7c0afa21e00a9ca Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 23:05:50 -0600 Subject: [PATCH 28/33] Update docs with new features --- docs/Configuration.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/Configuration.md b/docs/Configuration.md index 660377a60..b2a0e763e 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -207,6 +207,9 @@ Special sub-elements of text are "match" and "team". These sub-types will updat "code": "mc", "type": "counter", "defaultValue": 0, + "altInc1": 10, + "altInc2": 5, + "expectedMax": 99, "tooltip": "Put help or more descriptive text here" } ``` @@ -214,6 +217,9 @@ The counter is displayed with two buttons labeled "-" and "+" to increase or dec Specific attributes of counter are: * defaultValue (optional) - set the field to start at a certain value +* altInc1 (optional) - Add an additional button to increment/decrement the counter by the specified amount +* altInc2 (optional) - Add a 2nd additional button to increment/decrement the counter by the specified amount +* expectedMax (optional) - used by the data generation program to generate reasonable expected values The counter element will be set back to the defaultValue value when the Clear Form button is pressed. If there is no defaultValue it will be reset to zero. @@ -304,6 +310,7 @@ There are no specific attributes to this element. "showFlip": "false", "showUndo": "false", "shape": "circle 12 black red true", + "expectedMax": 20, "cycleTimer": "tct" } ``` @@ -326,6 +333,7 @@ Specific attributes of Cycle Timer are: * fillColor - color to fill in the shape (Default value: none) * fill - if true, fill in the shape with the fillColor, otherwise do not fill in the shape * Note: Use predefined [HTML color names](https://www.w3schools.com/colors/colors_names.asp) only +* expectedMax (optional) - used by the data generation program to generate reasonable expected values * cycleTimer (optional) - tie clicks into a cycle timer to start new cycles every time the image is clicked. The element field_image has been deprecated in favor of the new more flexible clickable_image. It is currently still supported but may be removed from future releases. From 7fda1e6b23004834ecebe815cc97169b911baef9 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 23:23:36 -0600 Subject: [PATCH 29/33] Update README for 2026 changes --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7f29d3067..f236d325a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Scouting P.A.S.S. -#### A scouting system for FIRST FRC competitions developed by [PWNAGE - Team #2451](https://pwnagerobotics.org). +#### A scouting system for FIRST FRC competitions developed by [PWNAGE - Team #2451](https://pwnagerobotics.org) Live Demo . Pit Scouting . Getting Started . FAQ @@ -77,7 +77,7 @@ User defined fields can be of several different types: * Cycle Timer - Start the timer and with 1 click track cycle times of robots. * Field Image - Using an image of the field, select positions on the field. (Use to record starting point or shooting locations) -These should cover most of your scouting team's data collection needs. PWNAGE's 2020 Infinite Recharge configuration file is included as an example. The import of the configuration file is in index.html and would need to be updated to import a different configuration file. Only import one configuration file. +These should cover most of your scouting team's data collection needs. The REBUIT (2026) configuration file is included as an example. The import of the configuration file is in index.html and would need to be updated to import a different configuration file. Only import one configuration file. Since this is an HTML/JavaScript web page, scouters can use almost any device that has a web browser. If the device has a touchscreen the screen can be used to swipe back and forth between pages and interact with the data elements. The webpage only needs to be loaded once. Once loaded the functionality and data is stored locally in the webpage and doesn't need to be reloaded. The QR code generation and clear button only resets the form and does not cause the page to reload. This means that a cellular or WiFi connection is not needed at the competition as long as the webpage is loaded before the event. @@ -108,7 +108,7 @@ Note: For this to work, the schedule has to be posted to The Blue Alliance. Tha ## Pit Scouting: -ScountingPASS now supports Pit Scouting +ScoutingPASS now supports Pit Scouting To access the pit scouting page, add '/pit.html' to the end of your URL. (i.e. http://pwnagerobotics.github.io/ScoutingPASS/pit.html) @@ -218,6 +218,7 @@ Distributed under the GNU GPL v3.0 License. See `LICENSE` for more information. 2026 Season Updates
  • New configurations added for match and pit scouting as well as the new field image
  • +
  • Add alternate increment/decrement configurations for the counter element
From 5b398161bf88611914e5258fd38f12867abefe4c Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 23:29:24 -0600 Subject: [PATCH 30/33] Update headers --- index.html | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index a0b2c321a..5c616e206 100644 --- a/index.html +++ b/index.html @@ -17,7 +17,7 @@
-

PWNAGE
Scouting 2026

+

PWNAGE
Scouting PASS

pre-match

@@ -27,7 +27,7 @@

pre-match

-

PWnAGE
Scouting 2026

+

PWnAGE
Scouting PASS

Auton

@@ -37,7 +37,7 @@

Auton

-

PWnAGE
Scouting 2026

+

PWnAGE
Scouting PASS

Teleop

@@ -47,7 +47,7 @@

Teleop

-

PWnAGE
Scouting 2026

+

PWnAGE
Scouting PASS

Endgame

@@ -57,7 +57,7 @@

Endgame

-

PWnAGE
Scouting 2026

+

PWnAGE
Scouting PASS

Miscellaneous

@@ -106,3 +106,4 @@

Generate QR Code

+ From 769ff2eb0f999bc9395eb5452e065d3a712aa190 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 23:30:05 -0600 Subject: [PATCH 31/33] Update headers --- pit.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pit.html b/pit.html index d2ec33f4f..11afb3a97 100644 --- a/pit.html +++ b/pit.html @@ -17,7 +17,7 @@
-

PWNAGE
Scouting 2020

+

PWNAGE
Scouting PASS

Pit Scouting

@@ -27,7 +27,7 @@

Pit Scouting

-

PWnAGE
Scouting 2020

+

PWnAGE
Scouting PASS

Generate QR Code

@@ -60,3 +60,4 @@

Generate QR Code

+ From 5bfc5ff0c9ba278d6971ada24d4fc75dcdfa6bb8 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 23:31:16 -0600 Subject: [PATCH 32/33] Fix typos in TBAInterface.js comments --- resources/js/TBAInterface.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/js/TBAInterface.js b/resources/js/TBAInterface.js index 8887e1e4b..178528c12 100644 --- a/resources/js/TBAInterface.js +++ b/resources/js/TBAInterface.js @@ -1,4 +1,4 @@ -// TBAInterface funcitons to pull data from TheBlueAlliance.com +// TBAInterface functions to pull data from TheBlueAlliance.com var teams = null; var schedule = null; var authKey = "uTHeEfPigDp9huQCpLNkWK7FBQIb01Qrzvt4MAjh9z2WQDkrsvNE77ch6bOPvPb6"; @@ -25,7 +25,7 @@ function getTeams(eventCode) { } /** - * Get schefule for event + * Get schedule for event * * @param {eventCode} eventCode the event code (i.e. 2020caln) to pull the team list */ From 402c27c93e8259236c25f61a02790f4b37f684c0 Mon Sep 17 00:00:00 2001 From: fuddster Date: Mon, 19 Jan 2026 23:35:52 -0600 Subject: [PATCH 33/33] Change Level 2 to Level 3 in radio choices --- 2026/rebuilt_config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/2026/rebuilt_config.js b/2026/rebuilt_config.js index 35dd7bdd7..ee20a3521 100644 --- a/2026/rebuilt_config.js +++ b/2026/rebuilt_config.js @@ -163,7 +163,7 @@ var config_data = ` "choices": { "1": "Level 1
", "2": "Level 2
", - "3": "Level 2
", + "3": "Level 3
", "a": "Attempted
", "x": "Not Attempted" },