@@ -194,9 +194,7 @@ function option(string $value, string $desc, $attributes = []): string
194
194
<?= array_key_exists ('source ' , $ options ) && $ options ['source ' ] === 'Y ' ? 'checked ' : '' ?> />
195
195
</label>
196
196
197
- <noscript>
198
197
<button type="submit" class="button">Update Instructions</button>
199
- </noscript>
200
198
</form>
201
199
202
200
<div class="tip">
@@ -254,13 +252,77 @@ function option(string $value, string $desc, $attributes = []): string
254
252
<?php endif ; ?>
255
253
256
254
<script>
257
- window.onload = function () {
258
- let form = document.getElementById("instructions-form")
255
+ let currentController = null;
256
+
257
+ function loadInstructions(url) {
258
+ const form = document.querySelector('#instructions-form')
259
+ const instructions = document.getElementById('instructions')
260
+
261
+ if (currentController) {
262
+ currentController.abort()
263
+ }
264
+ currentController = new AbortController()
265
+
266
+ fetch(url, {signal: currentController.signal})
267
+ .then(response => {
268
+ if (!response.ok) {
269
+ instructions.innerHTML = `<p class="error">Error ${response.status}: Unable to load data.</p>`
270
+ throw new Error(`HTTP ${response.status} ${response.statusText}`)
271
+ }
272
+ return response.text()
273
+ })
274
+ .then(html => {
275
+ const parser = new DOMParser();
276
+ const doc = parser.parseFromString(html, 'text/html')
277
+
278
+ const newForm = doc.querySelector('#instructions-form')
279
+ const newInstructions = doc.querySelector('#instructions')
280
+
281
+ if (newForm && form) form.innerHTML = newForm.innerHTML
282
+ if (newInstructions && instructions) instructions.innerHTML = newInstructions.innerHTML
283
+
284
+ removeUpdateInstructionsButton()
285
+
286
+ if (window.Prism && typeof Prism.highlightAll === 'function') {
287
+ Prism.highlightAll()
288
+ }
289
+ })
290
+ .catch(err => {
291
+ if (err.name === 'AbortError') return;
292
+ console.error('Request failed:', err)
293
+ if (!instructions.querySelector('.error')) {
294
+ instructions.innerHTML = `<p class="error">An unexpected error occurred.</p>`
295
+ }
296
+ });
297
+ }
259
298
260
- form.addEventListener('change', function () {
261
- form.submit();
262
- });
299
+ function removeUpdateInstructionsButton() {
300
+ const btn = document.querySelector('#instructions-form button[type="submit"]')
301
+ if (btn && window.fetch && window.AbortController) {
302
+ btn.remove()
303
+ }
263
304
}
305
+
306
+ document.addEventListener('DOMContentLoaded', function () {
307
+ removeUpdateInstructionsButton()
308
+ })
309
+
310
+ document.addEventListener('change', function (e) {
311
+ if (e.target.closest('#instructions-form')) {
312
+ const form = e.target.closest('#instructions-form')
313
+ const params = new URLSearchParams(new FormData(form)).toString()
314
+ const newUrl = form.action.split('?')[0] + '?' + params
315
+
316
+ history.pushState({url: newUrl}, '', newUrl)
317
+ loadInstructions(newUrl)
318
+ }
319
+ })
320
+
321
+ window.addEventListener('popstate', function (e) {
322
+ if (e.state && e.state.url) {
323
+ loadInstructions(e.state.url)
324
+ }
325
+ })
264
326
</script>
265
327
266
328
<?php
0 commit comments