Ask who the signup is for as a three-way choice
CI / Tests (PHP 8.2) (pull_request) Successful in 50s
CI / PHPStan (pull_request) Successful in 2m53s
CI / Coding Standards (pull_request) Successful in 2m57s
CI / Tests (PHP 8.1) (pull_request) Successful in 45s
CI / No Debug Code (pull_request) Successful in 2s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m40s
CI / Build Plugin Zip (pull_request) Skipped
CI / Tests (PHP 8.2) (pull_request) Successful in 50s
CI / PHPStan (pull_request) Successful in 2m53s
CI / Coding Standards (pull_request) Successful in 2m57s
CI / Tests (PHP 8.1) (pull_request) Successful in 45s
CI / No Debug Code (pull_request) Successful in 2s
CI / Tests (PHP 8.3) (pull_request) Successful in 2m40s
CI / Build Plugin Zip (pull_request) Skipped
Replaces the single "I'm registering as a parent or guardian" tick with "Just myself" / "On behalf of one or more students" / "Both". Radios, not checkboxes as the feedback put it: the three answers are mutually exclusive, and "both" only means anything as a third choice alongside the other two. The tick could only ever say whether there were children to add. It could not say whether the account holder was a student, so bookableStudents() always offered them their own name and any guardian could book themselves a lesson nobody meant to sell. "On behalf of" now records us_guardian_only and leaves them out of the picker. That flag is stored as the negative on purpose. Every account predating this choice is a bookable student, and absence has to keep meaning exactly that, or the picker would quietly stop offering people themselves on upgrade. setGuardianOnly() clears the key rather than writing 0, so "not set" stays the single spelling of "yes, a student". A guardian-only account with nobody linked to it is still offered itself — an empty picker is no way to book at all, and they can put the account right from the profile page. An unrecognised or absent value reads as "just myself": the choice that collects the least and grants the least. A missing radio must never be taken as "register these children". Bumps to 1.4.0. The account holder's own questions stay out of play whenever students are being added, "both" included — asking them there is #146. Verified the form in a headless browser across all three choices: which blocks show, which fields carry `required`, whether the account holder's question panel is disabled, which submit is offered, and that switching back to "just myself" leaves no hidden required field blocking submit. Closes #145 Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
+36
-16
@@ -9,11 +9,12 @@
|
||||
* the questions) inside a form marked `data-steps="1"`. Step two is hidden
|
||||
* behind a "Next" button that only advances once step one passes native
|
||||
* validation.
|
||||
* 2. **Parent/guardian.** The children section is hidden until the
|
||||
* parent/guardian box is ticked, and "Add another child" clones the child
|
||||
* block. Ticking the box also takes the guardian's *own* question panel out
|
||||
* of play — in guardian mode the questions are asked per child, so the
|
||||
* server ignores those answers and the browser must not demand them.
|
||||
* 2. **Who are you registering?** The student section is hidden until the
|
||||
* choice is "on behalf of students" or "both", and "Add another student"
|
||||
* clones the student block. Either of those choices also takes the account
|
||||
* holder's *own* question panel out of play — the questions are then asked
|
||||
* per student, so the server ignores those answers and the browser must not
|
||||
* demand them.
|
||||
* 3. **Password strength.** The password is scored with zxcvbn (via WordPress's
|
||||
* own `wp.passwordStrength`) and a weak one is refused. The server applies
|
||||
* its own, coarser rule regardless — see `Auth\PasswordPolicy`.
|
||||
@@ -198,21 +199,38 @@
|
||||
}
|
||||
|
||||
function enhanceGuardian(form, steps) {
|
||||
var toggle = form.querySelector('#us-is-guardian');
|
||||
var choices = form.querySelectorAll('.us-registering-for');
|
||||
var children = form.querySelector('#us-children');
|
||||
|
||||
if (!toggle || !children) {
|
||||
if (!choices.length || !children) {
|
||||
return;
|
||||
}
|
||||
|
||||
var addButton = children.querySelector('.us-add-child');
|
||||
var nextIndex = 1;
|
||||
|
||||
// The guardian's own question panel is only meaningful when they are
|
||||
// registering for themselves. Disabling it (rather than hiding it) is what
|
||||
// stops a `required` question the server will ignore from blocking submit.
|
||||
/** The selected "who are you registering?" value; 'self' if somehow none is. */
|
||||
function mode() {
|
||||
for (var i = 0; i < choices.length; i++) {
|
||||
if (choices[i].checked) return choices[i].value;
|
||||
}
|
||||
return 'self';
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep the form in step with the choice.
|
||||
*
|
||||
* Student blocks appear for "students" and "both". The account holder's
|
||||
* own question panel is the mirror image: the studio's questions describe
|
||||
* a student, so whenever students are being added they are asked per
|
||||
* student instead, and the account holder's copy goes out of play.
|
||||
* Disabling it rather than hiding it is what stops a `required` question
|
||||
* the server will ignore from blocking submit.
|
||||
*/
|
||||
function sync() {
|
||||
children.hidden = !toggle.checked;
|
||||
var wantsStudents = mode() !== 'self';
|
||||
|
||||
children.hidden = !wantsStudents;
|
||||
|
||||
// Each student's name and birth year are required, but only once the
|
||||
// block is in play: a `required` field inside a hidden container makes
|
||||
@@ -221,7 +239,7 @@
|
||||
// enforces the same rule either way.
|
||||
var required = children.querySelectorAll('[data-us-child-required]');
|
||||
for (var r = 0; r < required.length; r++) {
|
||||
required[r].required = toggle.checked;
|
||||
required[r].required = wantsStudents;
|
||||
}
|
||||
|
||||
if (!steps) {
|
||||
@@ -230,19 +248,21 @@
|
||||
|
||||
var fields = steps.step2.querySelectorAll('input, select, textarea');
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
fields[i].disabled = toggle.checked;
|
||||
fields[i].disabled = wantsStudents;
|
||||
}
|
||||
|
||||
// With the questions out of play there is no second step to advance to,
|
||||
// so "Next" would be a dead end — swap it for the submit.
|
||||
steps.next.hidden = toggle.checked;
|
||||
steps.next.hidden = wantsStudents;
|
||||
|
||||
if (steps.earlySubmit) {
|
||||
steps.earlySubmit.hidden = !toggle.checked;
|
||||
steps.earlySubmit.hidden = !wantsStudents;
|
||||
}
|
||||
}
|
||||
|
||||
toggle.addEventListener('change', sync);
|
||||
for (var c = 0; c < choices.length; c++) {
|
||||
choices[c].addEventListener('change', sync);
|
||||
}
|
||||
sync();
|
||||
|
||||
if (addButton) {
|
||||
|
||||
Reference in New Issue
Block a user