Migration
This is my new public git source viewer. Source coming soon. Please contact with concerns/bugs.
Contact me
static/js/admin.js
8d1bb5bfdd2cba82488775b46308efed740132a8
· 2.0 KB · 60 lines
raw
| 1 | // Progressive enhancement for the notices admin form. |
| 2 | // |
| 3 | // Without JavaScript the server-rendered checkbox removes a row and the |
| 4 | // single blank row is how you add one. This script only makes those two |
| 5 | // actions interactive: it turns the checkbox into a Remove button and |
| 6 | // clones the blank row for an Add button. It never changes what the form |
| 7 | // submits, so a JS-on submit and a JS-off submit build the same document. |
| 8 | (function () { |
| 9 | 'use strict'; |
| 10 | |
| 11 | var form = document.querySelector('form.admin-form'); |
| 12 | if (!form) return; |
| 13 | document.body.classList.add('has-js'); |
| 14 | |
| 15 | var tbody = form.querySelector('tbody'); |
| 16 | if (!tbody) return; |
| 17 | |
| 18 | // Capture the server-rendered blank "add" row before anyone types in it, |
| 19 | // and use its markup as the template for rows the Add button creates. |
| 20 | var seed = tbody.lastElementChild; |
| 21 | if (!seed) return; |
| 22 | var seedHTML = seed.outerHTML; |
| 23 | |
| 24 | function enhance(row) { |
| 25 | var cell = row.querySelector('.admin-del'); |
| 26 | if (!cell || cell.dataset.enhanced) return; |
| 27 | cell.dataset.enhanced = '1'; |
| 28 | |
| 29 | // The checkbox stays in the DOM (hidden) so a form that is somehow |
| 30 | // submitted without JS still means what it did before. |
| 31 | var box = cell.querySelector('input[type=checkbox]'); |
| 32 | if (box) box.hidden = true; |
| 33 | |
| 34 | var btn = document.createElement('button'); |
| 35 | btn.type = 'button'; |
| 36 | btn.className = 'chip row-remove'; |
| 37 | btn.textContent = 'Remove'; |
| 38 | btn.addEventListener('click', function () { |
| 39 | row.parentNode.removeChild(row); |
| 40 | }); |
| 41 | cell.appendChild(btn); |
| 42 | } |
| 43 | |
| 44 | function addRow() { |
| 45 | var wrap = document.createElement('tbody'); |
| 46 | wrap.innerHTML = seedHTML; |
| 47 | var row = wrap.firstElementChild; |
| 48 | row.querySelectorAll('input, textarea').forEach(function (el) { |
| 49 | if (el.type === 'checkbox') el.checked = false; |
| 50 | else el.value = ''; |
| 51 | }); |
| 52 | tbody.appendChild(row); |
| 53 | enhance(row); |
| 54 | } |
| 55 | |
| 56 | Array.prototype.forEach.call(tbody.querySelectorAll('tr'), enhance); |
| 57 | |
| 58 | var add = document.getElementById('add-notice'); |
| 59 | if (add) add.addEventListener('click', addRow); |
| 60 | })(); |