From 4416bed7b40d875eef4abaf6e8e290d26b374889 Mon Sep 17 00:00:00 2001 From: Johannes Schmidt <89488492+johannesparty@users.noreply.github.com> Date: Sun, 19 Jul 2026 10:38:43 -0700 Subject: [PATCH 1/4] docs: update deployment workflow (staging now deploys from staging branch) Replace the outdated path-config model and 'staging branch unused' note with the verified per-site GitHub Integration settings (Include/Delete toggles), the main->prod / staging->staging branch mapping, a hard warning never to enable the 'Delete files not in repository' toggles (repo only contains bd4d), the mu-plugins-not-deployed caveat, and the feature->staging->main workflow. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 106 +++++++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 4daa7c2..0a702a5 100644 --- a/README.md +++ b/README.md @@ -176,8 +176,8 @@ The plugin sends a confirmation email after successful form submission. The emai | Environment | URL | Branch | Deploy Method | |-------------|-----|--------|---------------| -| **Production** | bd4d.org | `main` | Auto-deploy on push to `main` | -| **Staging** | bd4d-staging.mystagingwebsite.com | `main` | Unknown (may be auto or manual) | +| **Production** | bd4d.org | `main` | Auto-deploy on push/merge to `main` (confirmed 2026-07-18) | +| **Staging** | bd4d-staging.mystagingwebsite.com | `staging` | Auto-deploy on push to `staging` (configured 2026-07-19) | | **Sandbox** | bd4dsandbox.mystagingwebsite.com | N/A | Static clone from staging (Oct 2025) | ### How Deployment Works @@ -189,45 +189,48 @@ was updated, and the deployed files were verified byte-identical to `main`. These notes are not specific to this plugin and could still change based on Pressable-side configuration unrelated to this repo, so re-verify if a deploy ever behaves unexpectedly. -Pressable has **GitHub Integration** configured: - -1. **Source:** UI shows `wp-content` folder in repo -2. **Destination:** UI shows `htdocs/wp-content` on Pressable server -3. **Trigger:** Production auto-deploys on push/merge to `main` branch (confirmed 2026-07-18) -4. **Result:** Only `wp-content/plugins/bd4d` is updated on the server +Each Pressable site (production and staging) has its own **GitHub Integration** pointing at this +repo. A push/merge to a site's configured branch auto-deploys within a couple of minutes. ``` -GitHub (main branch) Pressable -───────────────────── ──────────────────── -wp-content/plugins/bd4d ──────► htdocs/wp-content/plugins/bd4d +GitHub Pressable +────────────────── ───────────────────────────────────────── +main branch ─────► production (bd4d.org) +staging branch ─────► staging (bd4d-staging.mystagingwebsite.com) + +wp-content/plugins/bd4d ─────► htdocs/wp-content/plugins/bd4d (both sites) ``` -### Deployment Behavior (Observed Jan 2026) +### GitHub Integration Settings (per site) -**Observations:** Despite the Pressable UI showing `wp-content` → `htdocs/wp-content`, we observed that only `bd4d/` plugin files were updated during deployments. Other plugins, themes, and uploads were not deleted. +Each site's integration (Pressable dashboard → site → GitHub Integration) uses per-directory +**Include** and **Delete** toggles. Verified configuration for both sites: -This was verified by: -- Comparing Pressable daily backups before/after deployments -- Checking server file timestamps (`find /srv/htdocs -newermt ...`) -- Confirming only `bd4d/` files changed +| Setting | Production | Staging | +|---------|------------|---------| +| Branch | `main` | `staging` | +| Include **plugins** directory | Yes | Yes | +| Include **themes** directory | No | No | +| Include **MU Plugins** directory | No | No | +| Delete plugin files not in repo | **No** | **No** | +| Delete theme files not in repo | **No** | **No** | +| Delete MU plugin files not in repo | **No** | **No** | -**Why this happens is unclear.** Possible explanations: -- Pressable may implicitly only sync directories that exist in the repo -- There may be hidden settings from when staging was cloned to production -- The behavior could change if the GitHub integration is deleted and recreated +With "Include plugins: Yes" and the "Delete" toggles off, a deploy only **adds/updates** the +`bd4d` plugin and never removes or touches anything else. Note: selecting a branch in the dropdown +does nothing until you click **Set and Deploy** to commit it. -**We cannot confirm the exact behavior without deleting and recreating the integration**, which carries risk. +#### ⚠️ NEVER enable a "Delete … files not in repository" toggle -### ⚠️ Recommended: Correct Path Configuration +This repo contains **only** `wp-content/plugins/bd4d`. The server runs ~14 plugins (Divi Pixel, +Jetpack, Autoptimize, WordPress SEO, etc.) that are **not** in this repo. Enabling "Delete plugin +files not in repository" would delete **all of them** on the next deploy. Keep all three red +"Delete …" toggles **off, permanently**. -The Pressable UI shows broader paths than intended. The **recommended** settings are: +#### mu-plugins are NOT deployed -``` -Repository Directory to Deploy From: wp-content/plugins/bd4d -Deployment Path: htdocs/wp-content/plugins/bd4d -``` - -**Note:** The Pressable UI may show different values and changes may revert when navigating away. The "Set and Deploy" button is only needed to save/change the deploy *path* settings (which also triggers a deploy). A routine code change does **not** require it — a push/merge to `main` auto-deploys on its own (confirmed 2026-07-18). +"Include MU Plugins" is off, so files under `wp-content/mu-plugins/` must be copied to the server +manually (SFTP/rsync). Routine plugin deploys never touch them. **Server architecture:** - `htdocs/` - Your site files (wp-content, wp-config.php) - GitHub deploys here @@ -235,18 +238,24 @@ Deployment Path: htdocs/wp-content/plugins/bd4d ### Deployment Workflow -Production auto-deploys when you push to `main`: +Test on staging first, then promote to production: ``` -GitHub main ──► production (auto-deploy) +feature branch ──► staging branch ──► staging site (test) + │ + ▼ (open PR, merge) + main branch ──► production (live) ``` -1. Make changes locally +1. Make changes locally on a feature branch 2. Run `npx grunt` to build assets (CSS/JS) -3. Commit changes (including built assets in `wp-content/plugins/bd4d/assets/`) -4. Push to `main` branch -5. Production auto-deploys within minutes -6. Verify changes on production +3. Commit (including built assets in `wp-content/plugins/bd4d/assets/`) +4. **Staging:** push the work to the `staging` branch → staging site auto-deploys → test. + (Staging is gated by HTTP Basic Auth — log in with any WP admin credential — and it writes to + the **production** Airtable base, so test submissions land in prod data. Delete them after.) +5. **Production:** open a PR to `main`, merge (squash/rebase — linear history is enforced on + `main`) → production auto-deploys within minutes +6. Verify on production **Recommended: Always backup before deploying** (see `backup.sh` in repo root) @@ -271,20 +280,19 @@ Best for: When staging and production should be identical mirrors (content, sett **Note:** Form submissions go to Airtable, not WordPress, so no form data is lost either way. -### Note on GitHub `staging` Branch - -The `staging` branch in the GitHub repo is **not used** and is stale: - -| Branch | Last Commit | Date | -|--------|-------------|------| -| `main` | 64aee4e | Jan 6, 2026 | -| `staging` | a8bcbbe "fix: fix submit button handling" | Mar 27, 2025 | +### The GitHub `staging` Branch -**204 commits behind main:** -- 202 are Dependabot dependency updates -- 2 are actual code changes (`fix: disable mobile logo fix`, `build: update dependencies`) +As of 2026-07-19 the `staging` branch is the **deploy source for the staging site** (it was +previously stale and unused). It was fast-forwarded to `main`, and the staging site's GitHub +Integration was pointed at it (Selected Branch: `staging`). Push feature work to `staging` to +deploy it to the staging site for testing; it doesn't need to stay perfectly in sync with `main` +between tests. -The staging workflow happens at the **Pressable level** (deploy to staging site first, then production), not via git branches. The `staging` branch could be deleted or kept for historical reference. +> First-push note: the staging integration was (re)configured on 2026-07-19 after previously +> pointing at a deleted branch. The auto-deploy-on-push behavior is expected to work like +> production but should be confirmed on the first real push to `staging` (check the deployed +> file timestamps on the server). If it doesn't fire, deploy manually via **Set and Deploy** or +> rsync, and re-check the integration. ### GitHub Actions (CI only, not deployment) From 190b630d42ca2bcd9b934578b8423a17a7a95518 Mon Sep 17 00:00:00 2001 From: Johannes Schmidt <89488492+johannesparty@users.noreply.github.com> Date: Sun, 19 Jul 2026 12:18:24 -0700 Subject: [PATCH 2/4] docs: add auto-reply email cases reference Snapshot of the current auto-reply copy per case (pre-Endorser) as a reference doc. Co-Authored-By: Claude Opus 4.8 (1M context) --- EMAILCASES.md | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 EMAILCASES.md diff --git a/EMAILCASES.md b/EMAILCASES.md new file mode 100644 index 0000000..8497bad --- /dev/null +++ b/EMAILCASES.md @@ -0,0 +1,108 @@ +# Auto-Reply Email Cases - Full Text + +## Case A: Newsletter only +Newsletter: ✓ | Supporter: ✗ | Adoption: ✗ + +``` +Hello, and thank you for joining the Better Deal for Data community! + +We're excited to welcome you to the movement to unlock the full potential of data to serve society. + +This message is to confirm that you have subscribed to our email updates via our website. If you wish to unsubscribe from our email updates, please reply to this email with the word "Unsubscribe." + +We'd love to hear your feedback, questions, or stories about data! You can reach us at info@bd4d.org. + +All the best, +Celine + +– +M Celine Takatsuno +Better Deal for Data, a Tech Matters initiative. +Tech Matters is a nonprofit tech organization. +``` + +--- + +## Case B: Supporter only +Newsletter: ✗ | Supporter: ✓ | Adoption: ✗ + +``` +Hello, and thank you for joining the Better Deal for Data community! + +We're excited to welcome you to the movement to unlock the full potential of data to serve society, and add your name to our growing list of public supporters as part of our Coalition of the Willing. + +This message is to confirm that we have your permission to display your name and affiliation on our website. If you choose to sign up for email updates in the future, or if you have feedback, questions, or a data story to share, please send us a message at info@bd4d.org. We'd love to hear from you! + +All the best, +Celine + +– +M Celine Takatsuno +Better Deal for Data, a Tech Matters initiative. +Tech Matters is a nonprofit tech organization. +``` + +--- + +## Case C: Newsletter + Supporter +Newsletter: ✓ | Supporter: ✓ | Adoption: ✗ + +``` +Hello, and thank you for joining the Better Deal for Data community! + +We're excited to welcome you to the movement to unlock the full potential of data to serve society, and add your name to our growing list of public supporters as part of our Coalition of the Willing. + +This message is to confirm: +• that we have your permission to display your name and affiliation on our website; and +• that you have subscribed to our email updates via our website. If you wish to unsubscribe from our email updates, please reply to this email with the word "Unsubscribe." + +We'd love to hear your feedback, questions, or stories about data! You can reach us at info@bd4d.org. + +All the best, +Celine + +– +M Celine Takatsuno +Better Deal for Data, a Tech Matters initiative. +Tech Matters is a nonprofit tech organization. +``` + +--- + +## Case D: Adoption (takes priority over other checkboxes) +Newsletter: any | Supporter: any | Adoption: ✓ + +``` +Hello, and welcome to the Better Deal for Data community! + +We're excited to learn more about how your organization works with data for good, and answer any questions you have about adopting the BD4D Standard. We will contact you personally within the next two business days. + +In the meantime, please don't hesitate to contact us at info@bd4d.org. + +Many thanks, +Celine + +– +M Celine Takatsuno +Better Deal for Data, a Tech Matters initiative. +Tech Matters is a nonprofit tech organization. +``` + +--- + +## Case E: No checkboxes selected +Newsletter: ✗ | Supporter: ✗ | Adoption: ✗ + +``` +Hello, and thank you for joining the Better Deal for Data community! + +We're excited to welcome you to the movement to unlock the full potential of data to serve society. + +All the best, +Celine + +– +M Celine Takatsuno +Better Deal for Data, a Tech Matters initiative. +Tech Matters is a nonprofit tech organization. +``` From 6d85182c9956369c92fe7856cc779dad262bf897 Mon Sep 17 00:00:00 2001 From: Johannes Schmidt <89488492+johannesparty@users.noreply.github.com> Date: Sun, 19 Jul 2026 12:18:24 -0700 Subject: [PATCH 3/4] feat: replace Supporter checkbox with Endorser field (v1.0.6) - Form: Supporter checkbox -> new Endorser checkbox, mapped to the new Airtable field 'Endorser?'. The Supporter field ('CotW-Opted In?') is no longer written but retained in Airtable for historical opt-ins. - Auto-reply email: refreshed copy for all cases (endorser welcome + confirmations, updated Adoption copy) and new subject 'Welcome to a Better Deal for Data'. - On-page success message: '...the BD4D Standard, and the movement...'. - Require an email when any opt-in checkbox is ticked, surfaced via the browser's native validation popup on the email field (matching the required first/last name fields); checkboxes are no longer disabled. - Bump version to 1.0.6. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 3 +- wp-content/plugins/bd4d/assets/js/main.min.js | 2 +- wp-content/plugins/bd4d/assets/js/main.src.js | 34 +++++++++---------- .../plugins/bd4d/assets/js/main.src.js.map | 2 +- wp-content/plugins/bd4d/assets/js/src/main.js | 34 +++++++++---------- wp-content/plugins/bd4d/bd4d.php | 4 +-- .../plugins/bd4d/includes/class-bd4d.php | 18 +++++----- .../bd4d/template-parts/auto-reply.php | 24 +++++++------ .../bd4d/template-parts/form-email.php | 8 ++--- 9 files changed, 64 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 0a702a5..58fbac8 100644 --- a/README.md +++ b/README.md @@ -84,8 +84,9 @@ The plugin writes form submissions to Airtable via the REST API (`https://api.ai | `Affiliation` | Affiliation input | Text | No | | `Form Comments` | Message textarea | Text | No | | `Email-Opted In?` | Newsletter checkbox | Boolean | Always sent | -| `CotW-Opted In?` | Supporter checkbox | Boolean | Always sent | +| `Endorser?` | Endorser checkbox | Boolean | Always sent | | `Adoption?` | Adoption checkbox | Boolean | Always sent | +| `CotW-Opted In?` | _Supporter checkbox — removed from form (v1.0.6); field retained for historical opt-ins_ | Boolean | No longer sent | **Note:** At least one of `Email Address` or `Form Comments` must be provided for submission. diff --git a/wp-content/plugins/bd4d/assets/js/main.min.js b/wp-content/plugins/bd4d/assets/js/main.min.js index fded3ff..c7084fc 100644 --- a/wp-content/plugins/bd4d/assets/js/main.min.js +++ b/wp-content/plugins/bd4d/assets/js/main.min.js @@ -1 +1 @@ -window.bd4d={getRecaptchaToken:function(){return new Promise(function(e){window.grecaptcha&&localize.sitekey?grecaptcha.ready(function(){grecaptcha.execute(localize.sitekey,{action:"validate_captcha"}).then(e).catch(function(){e("")})}):e("")})},processSubscription:function(i){let a=document.querySelector('input[type="submit"]'),d=a.value,t=(a.value="Sending...",a.classList.add("is-loading"),a.setAttribute("disabled","disabled"),i.preventDefault(),{_ajax_nonce:localize._ajax_nonce,action:"send_message"});var e=i.target.querySelector('input[name="first_name"]').value.trim(),r=i.target.querySelector('input[name="last_name"]').value.trim();let s=i.target.querySelector('input[name="email"]').value.trim();var o=i.target.querySelector('input[name="affiliation"]').value.trim(),n=i.target.querySelector('textarea[name="message"]').value.trim(),l=i.target.querySelector('input[name="newsletter"]'),c=i.target.querySelector('input[name="supporter"]'),u=i.target.querySelector('input[name="adoption"]');s&&(t.email=s),e&&(t.first_name=e),r&&(t.last_name=r),o&&(t.affiliation=o),n&&(t.message=n),l.checked&&(t.newsletter=l.value),c.checked&&(t.supporter=c.value),u.checked&&(t.adoption=u.value),(c.checked||l.checked)&!s?(i.target.querySelectorAll("#inline-subscribe-email").forEach(e=>e.classList.add("has-error")),i.target.querySelector(".error-message").textContent=localize.error_codes[10],window.bd4d.resetButton(a,d)):s||n?window.bd4d.getRecaptchaToken().then(e=>{t.token=e,jQuery.ajax({type:"POST",url:localize._ajax_url,data:t,timeout:3e4,success:t=>{if(!0===t.success)i.target.querySelector(".error-message").textContent="",jQuery(i.target.querySelector(".form-fields")).slideUp(),document.querySelectorAll("#joinbd4dnet .et_pb_text_inner,#joinbd4dnet .form-fields").forEach(e=>e.classList.add("hidden")),i.target.querySelector(".message").classList.remove("hidden"),s?i.target.querySelectorAll(".message .yes-email").forEach(e=>e.classList.remove("hidden")):i.target.querySelectorAll(".message .no-email").forEach(e=>e.classList.remove("hidden"));else{let e=localize.error_codes[t?.data?.error_code];4===t?.data?.error_code&&(e+=` (${t?.data?.error_message})`),window.bd4d.showError(a,d,i.target,e)}},error:(e,t)=>{let r=localize.error_codes[3];"timeout"===t?r="The request timed out. Please try again.":403===e?.status&&(r="Your session expired. Please refresh the page and try again."),window.bd4d.showError(a,d,i.target,r)}})}):(i.target.querySelectorAll("#inline-subscribe-email,#inline-subscribe-message").forEach(e=>e.classList.add("has-error")),i.target.querySelector(".error-message").textContent=localize.error_codes[6],window.bd4d.resetButton(a,d))},emailFieldHandler:function(e){e.target.value.trim()?(window.bd4d.emailCheckbox.removeAttribute("disabled"),window.bd4d.supporterCheckbox.removeAttribute("disabled"),window.bd4d.emailField.classList.remove("has-error")):(window.bd4d.emailCheckbox.removeAttribute("checked"),window.bd4d.emailCheckbox.setAttribute("disabled","disabled"),window.bd4d.supporterCheckbox.removeAttribute("checked"),window.bd4d.supporterCheckbox.setAttribute("disabled","disabled"))},messageFieldHandler:function(e){e.target.value.trim()&&window.bd4d.messageField.classList.remove("has-error")},resetButton:function(e,t){e.value=t,e.classList.remove("is-loading"),e.removeAttribute("disabled")},showError:function(e,t,r,i){r=r.querySelector(".error-message");e.value="Failed!",e.classList.remove("is-loading"),e.classList.add("is-error"),r.textContent=i,r.classList.add("is-visible"),setTimeout(function(){e.value=t,e.classList.remove("is-error"),e.removeAttribute("disabled")},2e3)},setup:function(){var e=document.getElementById("inline-subscribe");e&&(window.bd4d.emailField=document.getElementById("inline-subscribe-email"),window.bd4d.messageField=document.getElementById("inline-subscribe-message"),window.bd4d.emailCheckbox=document.getElementById("inline-subscribe-newsletter"),window.bd4d.supporterCheckbox=document.getElementById("inline-subscribe-supporter"),window.bd4d.emailField.addEventListener("input",window.bd4d.emailFieldHandler),window.bd4d.messageField.addEventListener("input",window.bd4d.messageFieldHandler),e.addEventListener("submit",window.bd4d.processSubscription))}},document.addEventListener("DOMContentLoaded",window.bd4d.setup); \ No newline at end of file +window.bd4d={getRecaptchaToken:function(){return new Promise(function(e){window.grecaptcha&&localize.sitekey?grecaptcha.ready(function(){grecaptcha.execute(localize.sitekey,{action:"validate_captcha"}).then(e).catch(function(){e("")})}):e("")})},processSubscription:function(a){let i=document.querySelector('input[type="submit"]'),s=i.value,t=(i.value="Sending...",i.classList.add("is-loading"),i.setAttribute("disabled","disabled"),a.preventDefault(),{_ajax_nonce:localize._ajax_nonce,action:"send_message"});var e=a.target.querySelector('input[name="first_name"]').value.trim(),r=a.target.querySelector('input[name="last_name"]').value.trim();let n=a.target.querySelector('input[name="email"]').value.trim();var o=a.target.querySelector('input[name="affiliation"]').value.trim(),d=a.target.querySelector('textarea[name="message"]').value.trim(),l=a.target.querySelector('input[name="newsletter"]'),c=a.target.querySelector('input[name="endorser"]'),u=a.target.querySelector('input[name="adoption"]');n&&(t.email=n),e&&(t.first_name=e),r&&(t.last_name=r),o&&(t.affiliation=o),d&&(t.message=d),l.checked&&(t.newsletter=l.value),c.checked&&(t.endorser=c.value),u.checked&&(t.adoption=u.value),(l.checked||c.checked||u.checked)&&!n?((e=a.target.querySelector('input[name="email"]')).setCustomValidity(localize.error_codes[10]),e.reportValidity(),window.bd4d.resetButton(i,s)):n||d?window.bd4d.getRecaptchaToken().then(e=>{t.token=e,jQuery.ajax({type:"POST",url:localize._ajax_url,data:t,timeout:3e4,success:t=>{if(!0===t.success)a.target.querySelector(".error-message").textContent="",jQuery(a.target.querySelector(".form-fields")).slideUp(),document.querySelectorAll("#joinbd4dnet .et_pb_text_inner,#joinbd4dnet .form-fields").forEach(e=>e.classList.add("hidden")),a.target.querySelector(".message").classList.remove("hidden"),n?a.target.querySelectorAll(".message .yes-email").forEach(e=>e.classList.remove("hidden")):a.target.querySelectorAll(".message .no-email").forEach(e=>e.classList.remove("hidden"));else{let e=localize.error_codes[t?.data?.error_code];4===t?.data?.error_code&&(e+=` (${t?.data?.error_message})`),window.bd4d.showError(i,s,a.target,e)}},error:(e,t)=>{let r=localize.error_codes[3];"timeout"===t?r="The request timed out. Please try again.":403===e?.status&&(r="Your session expired. Please refresh the page and try again."),window.bd4d.showError(i,s,a.target,r)}})}):(a.target.querySelectorAll("#inline-subscribe-email,#inline-subscribe-message").forEach(e=>e.classList.add("has-error")),a.target.querySelector(".error-message").textContent=localize.error_codes[6],window.bd4d.resetButton(i,s))},emailFieldHandler:function(e){e.target.setCustomValidity(""),e.target.classList.remove("has-error")},messageFieldHandler:function(e){e.target.value.trim()&&window.bd4d.messageField.classList.remove("has-error")},resetButton:function(e,t){e.value=t,e.classList.remove("is-loading"),e.removeAttribute("disabled")},showError:function(e,t,r,a){r=r.querySelector(".error-message");e.value="Failed!",e.classList.remove("is-loading"),e.classList.add("is-error"),r.textContent=a,r.classList.add("is-visible"),setTimeout(function(){e.value=t,e.classList.remove("is-error"),e.removeAttribute("disabled")},2e3)},setup:function(){var e=document.getElementById("inline-subscribe");e&&(window.bd4d.emailField=document.getElementById("inline-subscribe-email"),window.bd4d.messageField=document.getElementById("inline-subscribe-message"),window.bd4d.emailField.addEventListener("input",window.bd4d.emailFieldHandler),window.bd4d.messageField.addEventListener("input",window.bd4d.messageFieldHandler),e.addEventListener("submit",window.bd4d.processSubscription))}},document.addEventListener("DOMContentLoaded",window.bd4d.setup); \ No newline at end of file diff --git a/wp-content/plugins/bd4d/assets/js/main.src.js b/wp-content/plugins/bd4d/assets/js/main.src.js index d1f6f56..4e0337f 100644 --- a/wp-content/plugins/bd4d/assets/js/main.src.js +++ b/wp-content/plugins/bd4d/assets/js/main.src.js @@ -42,7 +42,7 @@ window.bd4d = { const affiliation = event.target.querySelector( 'input[name="affiliation"]' ).value.trim(); const message = event.target.querySelector( 'textarea[name="message"]' ).value.trim(); const newsletter = event.target.querySelector( 'input[name="newsletter"]' ); - const supporter = event.target.querySelector( 'input[name="supporter"]' ); + const endorser = event.target.querySelector( 'input[name="endorser"]' ); const adoption = event.target.querySelector( 'input[name="adoption"]' ); if ( emailAddress ) { @@ -69,17 +69,22 @@ window.bd4d = { data.newsletter = newsletter.value; } - if ( supporter.checked ) { - data.supporter = supporter.value; + if ( endorser.checked ) { + data.endorser = endorser.value; } if ( adoption.checked ) { data.adoption = adoption.value; } - if ( ( supporter.checked || newsletter.checked ) & ! emailAddress ) { - event.target.querySelectorAll( '#inline-subscribe-email' ).forEach( ( item ) => item.classList.add( 'has-error' ) ); - event.target.querySelector( '.error-message' ).textContent = localize.error_codes[10]; + if ( ( newsletter.checked || endorser.checked || adoption.checked ) && ! emailAddress ) { + + // An opt-in checkbox requires an email. Surface it via the browser's + // native validation popup on the email field — the same UX as the + // required first/last name fields — rather than the message below. + const emailInput = event.target.querySelector( 'input[name="email"]' ); + emailInput.setCustomValidity( localize.error_codes[10] ); + emailInput.reportValidity(); window.bd4d.resetButton( submitButton, originalButtonText ); return; } @@ -151,16 +156,11 @@ window.bd4d = { }, emailFieldHandler: function( event ) { - if ( event.target.value.trim() ) { - window.bd4d.emailCheckbox.removeAttribute( 'disabled' ); - window.bd4d.supporterCheckbox.removeAttribute( 'disabled' ); - window.bd4d.emailField.classList.remove( 'has-error' ); - } else { - window.bd4d.emailCheckbox.removeAttribute( 'checked' ); - window.bd4d.emailCheckbox.setAttribute( 'disabled', 'disabled' ); - window.bd4d.supporterCheckbox.removeAttribute( 'checked' ); - window.bd4d.supporterCheckbox.setAttribute( 'disabled', 'disabled' ); - } + + // Clear the email field's validation state as the user types, so a prior + // "email required" popup or error styling doesn't persist. + event.target.setCustomValidity( '' ); + event.target.classList.remove( 'has-error' ); }, messageFieldHandler: function( event ) { @@ -201,8 +201,6 @@ window.bd4d = { if ( subscribeForm ) { window.bd4d.emailField = document.getElementById( 'inline-subscribe-email' ); window.bd4d.messageField = document.getElementById( 'inline-subscribe-message' ); - window.bd4d.emailCheckbox = document.getElementById( 'inline-subscribe-newsletter' ); - window.bd4d.supporterCheckbox = document.getElementById( 'inline-subscribe-supporter' ); window.bd4d.emailField.addEventListener( 'input', window.bd4d.emailFieldHandler ); window.bd4d.messageField.addEventListener( 'input', window.bd4d.messageFieldHandler ); diff --git a/wp-content/plugins/bd4d/assets/js/main.src.js.map b/wp-content/plugins/bd4d/assets/js/main.src.js.map index e0174ff..187afe2 100644 --- a/wp-content/plugins/bd4d/assets/js/main.src.js.map +++ b/wp-content/plugins/bd4d/assets/js/main.src.js.map @@ -1 +1 @@ -{"version":3,"sources":["src/main.js"],"names":[],"mappings":"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","file":"main.src.js","sourcesContent":["window.bd4d = {\n\tgetRecaptchaToken: function() {\n\n\t\t// reCAPTCHA v3 tokens expire ~2 minutes after they are generated, so we\n\t\t// must mint a fresh one at submit time rather than once at page load.\n\t\t// Resolves to an empty string if reCAPTCHA is unavailable (adblock,\n\t\t// script load failure) so the request still goes through and the server\n\t\t// decides how to handle a missing token.\n\t\treturn new Promise( function( resolve ) {\n\t\t\tif ( ! window.grecaptcha || ! localize.sitekey ) {\n\t\t\t\tresolve( '' );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tgrecaptcha.ready( function() {\n\t\t\t\tgrecaptcha\n\t\t\t\t\t.execute( localize.sitekey, { action: 'validate_captcha' } )\n\t\t\t\t\t.then( resolve )\n\t\t\t\t\t.catch( function() {\n\t\t\t\t\t\tresolve( '' );\n\t\t\t\t\t} );\n\t\t\t} );\n\t\t} );\n\t},\n\n\tprocessSubscription: function( event ) {\n\t\tconst submitButton = document.querySelector( 'input[type=\"submit\"]' );\n\t\tconst originalButtonText = submitButton.value;\n\t\tsubmitButton.value = 'Sending...';\n\t\tsubmitButton.classList.add( 'is-loading' );\n\t\tsubmitButton.setAttribute( 'disabled', 'disabled' );\n\n\t\tevent.preventDefault();\n\n\t\tlet data = {\n\t\t\t_ajax_nonce: localize._ajax_nonce,\n\t\t\taction: 'send_message'\n\t\t};\n\n\t\tconst firstName = event.target.querySelector( 'input[name=\"first_name\"]' ).value.trim();\n\t\tconst lastName = event.target.querySelector( 'input[name=\"last_name\"]' ).value.trim();\n\t\tconst emailAddress = event.target.querySelector( 'input[name=\"email\"]' ).value.trim();\n\t\tconst affiliation = event.target.querySelector( 'input[name=\"affiliation\"]' ).value.trim();\n\t\tconst message = event.target.querySelector( 'textarea[name=\"message\"]' ).value.trim();\n\t\tconst newsletter = event.target.querySelector( 'input[name=\"newsletter\"]' );\n\t\tconst supporter = event.target.querySelector( 'input[name=\"supporter\"]' );\n\t\tconst adoption = event.target.querySelector( 'input[name=\"adoption\"]' );\n\n\t\tif ( emailAddress ) {\n\t\t\tdata.email = emailAddress;\n\t\t}\n\n\t\tif ( firstName ) {\n\t\t\tdata.first_name = firstName;\n\t\t}\n\n\t\tif ( lastName ) {\n\t\t\tdata.last_name = lastName;\n\t\t}\n\n\t\tif ( affiliation ) {\n\t\t\tdata.affiliation = affiliation;\n\t\t}\n\n\t\tif ( message ) {\n\t\t\tdata.message = message;\n\t\t}\n\n\t\tif ( newsletter.checked ) {\n\t\t\tdata.newsletter = newsletter.value;\n\t\t}\n\n\t\tif ( supporter.checked ) {\n\t\t\tdata.supporter = supporter.value;\n\t\t}\n\n\t\tif ( adoption.checked ) {\n\t\t\tdata.adoption = adoption.value;\n\t\t}\n\n\t\tif ( ( supporter.checked || newsletter.checked ) & ! emailAddress ) {\n\t\t\tevent.target.querySelectorAll( '#inline-subscribe-email' ).forEach( ( item ) => item.classList.add( 'has-error' ) );\n\t\t\tevent.target.querySelector( '.error-message' ).textContent = localize.error_codes[10];\n\t\t\twindow.bd4d.resetButton( submitButton, originalButtonText );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( ! emailAddress && ! message ) {\n\t\t\tevent.target\n\t\t\t\t.querySelectorAll( '#inline-subscribe-email,#inline-subscribe-message' )\n\t\t\t\t.forEach( ( item ) => item.classList.add( 'has-error' ) );\n\t\t\tevent.target.querySelector( '.error-message' ).textContent = localize.error_codes[6];\n\t\t\twindow.bd4d.resetButton( submitButton, originalButtonText );\n\t\t\treturn;\n\t\t}\n\n\t\t// Fetch a fresh reCAPTCHA token, then send. Doing this at submit time\n\t\t// (rather than at page load) avoids expired-token failures for people\n\t\t// who spend more than ~2 minutes filling out the form.\n\t\twindow.bd4d.getRecaptchaToken().then( ( token ) => {\n\t\t\tdata.token = token;\n\n\t\t\tjQuery.ajax( {\n\t\t\t\ttype: 'POST',\n\t\t\t\turl: localize._ajax_url,\n\t\t\t\tdata: data,\n\t\t\t\ttimeout: 30000,\n\t\t\t\tsuccess: ( res ) => {\n\t\t\t\t\tif ( true === res.success ) {\n\t\t\t\t\t\tevent.target.querySelector( '.error-message' ).textContent = '';\n\n\t\t\t\t\t\tjQuery( event.target.querySelector( '.form-fields' ) ).slideUp();\n\t\t\t\t\t\tdocument\n\t\t\t\t\t\t\t.querySelectorAll( '#joinbd4dnet .et_pb_text_inner,#joinbd4dnet .form-fields' )\n\t\t\t\t\t\t\t.forEach( ( item ) => item.classList.add( 'hidden' ) );\n\t\t\t\t\t\tevent.target.querySelector( '.message' ).classList.remove( 'hidden' );\n\t\t\t\t\t\tif ( emailAddress ) {\n\t\t\t\t\t\t\tevent.target\n\t\t\t\t\t\t\t\t.querySelectorAll( '.message .yes-email' )\n\t\t\t\t\t\t\t\t.forEach( ( item ) => item.classList.remove( 'hidden' ) );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tevent.target\n\t\t\t\t\t\t\t\t.querySelectorAll( '.message .no-email' )\n\t\t\t\t\t\t\t\t.forEach( ( item ) => item.classList.remove( 'hidden' ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlet errorMessage = localize.error_codes[res?.data?.error_code];\n\t\t\t\t\t\tif ( 4 === res?.data?.error_code ) {\n\n\t\t\t\t\t\t\t// 4 is a JSON parsing error.\n\t\t\t\t\t\t\terrorMessage += ` (${res?.data?.error_message})`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\twindow.bd4d.showError( submitButton, originalButtonText, event.target, errorMessage );\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\terror: ( jqXHR, textStatus ) => {\n\n\t\t\t\t\t// Any transport-level failure (HTTP 4xx/5xx, timeout, network drop)\n\t\t\t\t\t// lands here. Without this handler the button hangs on \"Sending...\".\n\t\t\t\t\tlet errorMessage = localize.error_codes[3]; // SEND_ERROR: 'Unable to send message'.\n\t\t\t\t\tif ( 'timeout' === textStatus ) {\n\t\t\t\t\t\terrorMessage = 'The request timed out. Please try again.';\n\t\t\t\t\t} else if ( 403 === jqXHR?.status ) {\n\n\t\t\t\t\t\t// Usually a stale/expired security token — a fresh page load fixes it.\n\t\t\t\t\t\terrorMessage = 'Your session expired. Please refresh the page and try again.';\n\t\t\t\t\t}\n\t\t\t\t\twindow.bd4d.showError( submitButton, originalButtonText, event.target, errorMessage );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t},\n\n\temailFieldHandler: function( event ) {\n\t\tif ( event.target.value.trim() ) {\n\t\t\twindow.bd4d.emailCheckbox.removeAttribute( 'disabled' );\n\t\t\twindow.bd4d.supporterCheckbox.removeAttribute( 'disabled' );\n\t\t\twindow.bd4d.emailField.classList.remove( 'has-error' );\n\t\t} else {\n\t\t\twindow.bd4d.emailCheckbox.removeAttribute( 'checked' );\n\t\t\twindow.bd4d.emailCheckbox.setAttribute( 'disabled', 'disabled' );\n\t\t\twindow.bd4d.supporterCheckbox.removeAttribute( 'checked' );\n\t\t\twindow.bd4d.supporterCheckbox.setAttribute( 'disabled', 'disabled' );\n\t\t}\n\t},\n\n\tmessageFieldHandler: function( event ) {\n\t\tif ( event.target.value.trim() ) {\n\t\t\twindow.bd4d.messageField.classList.remove( 'has-error' );\n\t\t}\n\t},\n\n\tresetButton: function( button, originalText ) {\n\t\tbutton.value = originalText;\n\t\tbutton.classList.remove( 'is-loading' );\n\t\tbutton.removeAttribute( 'disabled' );\n\t},\n\n\tshowError: function( button, originalText, form, errorMessage ) {\n\t\tconst errorDiv = form.querySelector( '.error-message' );\n\n\t\t// Show \"Failed!\" on button briefly.\n\t\tbutton.value = 'Failed!';\n\t\tbutton.classList.remove( 'is-loading' );\n\t\tbutton.classList.add( 'is-error' );\n\n\t\t// Show and highlight error message.\n\t\terrorDiv.textContent = errorMessage;\n\t\terrorDiv.classList.add( 'is-visible' );\n\n\t\t// After 2 seconds, restore button to normal state.\n\t\tsetTimeout( function() {\n\t\t\tbutton.value = originalText;\n\t\t\tbutton.classList.remove( 'is-error' );\n\t\t\tbutton.removeAttribute( 'disabled' );\n\t\t}, 2000 );\n\t},\n\n\tsetup: function() {\n\t\tconst subscribeForm = document.getElementById( 'inline-subscribe' );\n\n\t\tif ( subscribeForm ) {\n\t\t\twindow.bd4d.emailField = document.getElementById( 'inline-subscribe-email' );\n\t\t\twindow.bd4d.messageField = document.getElementById( 'inline-subscribe-message' );\n\t\t\twindow.bd4d.emailCheckbox = document.getElementById( 'inline-subscribe-newsletter' );\n\t\t\twindow.bd4d.supporterCheckbox = document.getElementById( 'inline-subscribe-supporter' );\n\t\t\twindow.bd4d.emailField.addEventListener( 'input', window.bd4d.emailFieldHandler );\n\t\t\twindow.bd4d.messageField.addEventListener( 'input', window.bd4d.messageFieldHandler );\n\n\t\t\tsubscribeForm.addEventListener( 'submit', window.bd4d.processSubscription );\n\t\t}\n\t}\n};\n\ndocument.addEventListener( 'DOMContentLoaded', window.bd4d.setup );\n"]} \ No newline at end of file +{"version":3,"sources":["src/main.js"],"names":[],"mappings":"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","file":"main.src.js","sourcesContent":["window.bd4d = {\n\tgetRecaptchaToken: function() {\n\n\t\t// reCAPTCHA v3 tokens expire ~2 minutes after they are generated, so we\n\t\t// must mint a fresh one at submit time rather than once at page load.\n\t\t// Resolves to an empty string if reCAPTCHA is unavailable (adblock,\n\t\t// script load failure) so the request still goes through and the server\n\t\t// decides how to handle a missing token.\n\t\treturn new Promise( function( resolve ) {\n\t\t\tif ( ! window.grecaptcha || ! localize.sitekey ) {\n\t\t\t\tresolve( '' );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tgrecaptcha.ready( function() {\n\t\t\t\tgrecaptcha\n\t\t\t\t\t.execute( localize.sitekey, { action: 'validate_captcha' } )\n\t\t\t\t\t.then( resolve )\n\t\t\t\t\t.catch( function() {\n\t\t\t\t\t\tresolve( '' );\n\t\t\t\t\t} );\n\t\t\t} );\n\t\t} );\n\t},\n\n\tprocessSubscription: function( event ) {\n\t\tconst submitButton = document.querySelector( 'input[type=\"submit\"]' );\n\t\tconst originalButtonText = submitButton.value;\n\t\tsubmitButton.value = 'Sending...';\n\t\tsubmitButton.classList.add( 'is-loading' );\n\t\tsubmitButton.setAttribute( 'disabled', 'disabled' );\n\n\t\tevent.preventDefault();\n\n\t\tlet data = {\n\t\t\t_ajax_nonce: localize._ajax_nonce,\n\t\t\taction: 'send_message'\n\t\t};\n\n\t\tconst firstName = event.target.querySelector( 'input[name=\"first_name\"]' ).value.trim();\n\t\tconst lastName = event.target.querySelector( 'input[name=\"last_name\"]' ).value.trim();\n\t\tconst emailAddress = event.target.querySelector( 'input[name=\"email\"]' ).value.trim();\n\t\tconst affiliation = event.target.querySelector( 'input[name=\"affiliation\"]' ).value.trim();\n\t\tconst message = event.target.querySelector( 'textarea[name=\"message\"]' ).value.trim();\n\t\tconst newsletter = event.target.querySelector( 'input[name=\"newsletter\"]' );\n\t\tconst endorser = event.target.querySelector( 'input[name=\"endorser\"]' );\n\t\tconst adoption = event.target.querySelector( 'input[name=\"adoption\"]' );\n\n\t\tif ( emailAddress ) {\n\t\t\tdata.email = emailAddress;\n\t\t}\n\n\t\tif ( firstName ) {\n\t\t\tdata.first_name = firstName;\n\t\t}\n\n\t\tif ( lastName ) {\n\t\t\tdata.last_name = lastName;\n\t\t}\n\n\t\tif ( affiliation ) {\n\t\t\tdata.affiliation = affiliation;\n\t\t}\n\n\t\tif ( message ) {\n\t\t\tdata.message = message;\n\t\t}\n\n\t\tif ( newsletter.checked ) {\n\t\t\tdata.newsletter = newsletter.value;\n\t\t}\n\n\t\tif ( endorser.checked ) {\n\t\t\tdata.endorser = endorser.value;\n\t\t}\n\n\t\tif ( adoption.checked ) {\n\t\t\tdata.adoption = adoption.value;\n\t\t}\n\n\t\tif ( ( newsletter.checked || endorser.checked || adoption.checked ) && ! emailAddress ) {\n\n\t\t\t// An opt-in checkbox requires an email. Surface it via the browser's\n\t\t\t// native validation popup on the email field — the same UX as the\n\t\t\t// required first/last name fields — rather than the message below.\n\t\t\tconst emailInput = event.target.querySelector( 'input[name=\"email\"]' );\n\t\t\temailInput.setCustomValidity( localize.error_codes[10] );\n\t\t\temailInput.reportValidity();\n\t\t\twindow.bd4d.resetButton( submitButton, originalButtonText );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( ! emailAddress && ! message ) {\n\t\t\tevent.target\n\t\t\t\t.querySelectorAll( '#inline-subscribe-email,#inline-subscribe-message' )\n\t\t\t\t.forEach( ( item ) => item.classList.add( 'has-error' ) );\n\t\t\tevent.target.querySelector( '.error-message' ).textContent = localize.error_codes[6];\n\t\t\twindow.bd4d.resetButton( submitButton, originalButtonText );\n\t\t\treturn;\n\t\t}\n\n\t\t// Fetch a fresh reCAPTCHA token, then send. Doing this at submit time\n\t\t// (rather than at page load) avoids expired-token failures for people\n\t\t// who spend more than ~2 minutes filling out the form.\n\t\twindow.bd4d.getRecaptchaToken().then( ( token ) => {\n\t\t\tdata.token = token;\n\n\t\t\tjQuery.ajax( {\n\t\t\t\ttype: 'POST',\n\t\t\t\turl: localize._ajax_url,\n\t\t\t\tdata: data,\n\t\t\t\ttimeout: 30000,\n\t\t\t\tsuccess: ( res ) => {\n\t\t\t\t\tif ( true === res.success ) {\n\t\t\t\t\t\tevent.target.querySelector( '.error-message' ).textContent = '';\n\n\t\t\t\t\t\tjQuery( event.target.querySelector( '.form-fields' ) ).slideUp();\n\t\t\t\t\t\tdocument\n\t\t\t\t\t\t\t.querySelectorAll( '#joinbd4dnet .et_pb_text_inner,#joinbd4dnet .form-fields' )\n\t\t\t\t\t\t\t.forEach( ( item ) => item.classList.add( 'hidden' ) );\n\t\t\t\t\t\tevent.target.querySelector( '.message' ).classList.remove( 'hidden' );\n\t\t\t\t\t\tif ( emailAddress ) {\n\t\t\t\t\t\t\tevent.target\n\t\t\t\t\t\t\t\t.querySelectorAll( '.message .yes-email' )\n\t\t\t\t\t\t\t\t.forEach( ( item ) => item.classList.remove( 'hidden' ) );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tevent.target\n\t\t\t\t\t\t\t\t.querySelectorAll( '.message .no-email' )\n\t\t\t\t\t\t\t\t.forEach( ( item ) => item.classList.remove( 'hidden' ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlet errorMessage = localize.error_codes[res?.data?.error_code];\n\t\t\t\t\t\tif ( 4 === res?.data?.error_code ) {\n\n\t\t\t\t\t\t\t// 4 is a JSON parsing error.\n\t\t\t\t\t\t\terrorMessage += ` (${res?.data?.error_message})`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\twindow.bd4d.showError( submitButton, originalButtonText, event.target, errorMessage );\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\terror: ( jqXHR, textStatus ) => {\n\n\t\t\t\t\t// Any transport-level failure (HTTP 4xx/5xx, timeout, network drop)\n\t\t\t\t\t// lands here. Without this handler the button hangs on \"Sending...\".\n\t\t\t\t\tlet errorMessage = localize.error_codes[3]; // SEND_ERROR: 'Unable to send message'.\n\t\t\t\t\tif ( 'timeout' === textStatus ) {\n\t\t\t\t\t\terrorMessage = 'The request timed out. Please try again.';\n\t\t\t\t\t} else if ( 403 === jqXHR?.status ) {\n\n\t\t\t\t\t\t// Usually a stale/expired security token — a fresh page load fixes it.\n\t\t\t\t\t\terrorMessage = 'Your session expired. Please refresh the page and try again.';\n\t\t\t\t\t}\n\t\t\t\t\twindow.bd4d.showError( submitButton, originalButtonText, event.target, errorMessage );\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t},\n\n\temailFieldHandler: function( event ) {\n\n\t\t// Clear the email field's validation state as the user types, so a prior\n\t\t// \"email required\" popup or error styling doesn't persist.\n\t\tevent.target.setCustomValidity( '' );\n\t\tevent.target.classList.remove( 'has-error' );\n\t},\n\n\tmessageFieldHandler: function( event ) {\n\t\tif ( event.target.value.trim() ) {\n\t\t\twindow.bd4d.messageField.classList.remove( 'has-error' );\n\t\t}\n\t},\n\n\tresetButton: function( button, originalText ) {\n\t\tbutton.value = originalText;\n\t\tbutton.classList.remove( 'is-loading' );\n\t\tbutton.removeAttribute( 'disabled' );\n\t},\n\n\tshowError: function( button, originalText, form, errorMessage ) {\n\t\tconst errorDiv = form.querySelector( '.error-message' );\n\n\t\t// Show \"Failed!\" on button briefly.\n\t\tbutton.value = 'Failed!';\n\t\tbutton.classList.remove( 'is-loading' );\n\t\tbutton.classList.add( 'is-error' );\n\n\t\t// Show and highlight error message.\n\t\terrorDiv.textContent = errorMessage;\n\t\terrorDiv.classList.add( 'is-visible' );\n\n\t\t// After 2 seconds, restore button to normal state.\n\t\tsetTimeout( function() {\n\t\t\tbutton.value = originalText;\n\t\t\tbutton.classList.remove( 'is-error' );\n\t\t\tbutton.removeAttribute( 'disabled' );\n\t\t}, 2000 );\n\t},\n\n\tsetup: function() {\n\t\tconst subscribeForm = document.getElementById( 'inline-subscribe' );\n\n\t\tif ( subscribeForm ) {\n\t\t\twindow.bd4d.emailField = document.getElementById( 'inline-subscribe-email' );\n\t\t\twindow.bd4d.messageField = document.getElementById( 'inline-subscribe-message' );\n\t\t\twindow.bd4d.emailField.addEventListener( 'input', window.bd4d.emailFieldHandler );\n\t\t\twindow.bd4d.messageField.addEventListener( 'input', window.bd4d.messageFieldHandler );\n\n\t\t\tsubscribeForm.addEventListener( 'submit', window.bd4d.processSubscription );\n\t\t}\n\t}\n};\n\ndocument.addEventListener( 'DOMContentLoaded', window.bd4d.setup );\n"]} \ No newline at end of file diff --git a/wp-content/plugins/bd4d/assets/js/src/main.js b/wp-content/plugins/bd4d/assets/js/src/main.js index 09714d7..aa63f58 100644 --- a/wp-content/plugins/bd4d/assets/js/src/main.js +++ b/wp-content/plugins/bd4d/assets/js/src/main.js @@ -42,7 +42,7 @@ window.bd4d = { const affiliation = event.target.querySelector( 'input[name="affiliation"]' ).value.trim(); const message = event.target.querySelector( 'textarea[name="message"]' ).value.trim(); const newsletter = event.target.querySelector( 'input[name="newsletter"]' ); - const supporter = event.target.querySelector( 'input[name="supporter"]' ); + const endorser = event.target.querySelector( 'input[name="endorser"]' ); const adoption = event.target.querySelector( 'input[name="adoption"]' ); if ( emailAddress ) { @@ -69,17 +69,22 @@ window.bd4d = { data.newsletter = newsletter.value; } - if ( supporter.checked ) { - data.supporter = supporter.value; + if ( endorser.checked ) { + data.endorser = endorser.value; } if ( adoption.checked ) { data.adoption = adoption.value; } - if ( ( supporter.checked || newsletter.checked ) & ! emailAddress ) { - event.target.querySelectorAll( '#inline-subscribe-email' ).forEach( ( item ) => item.classList.add( 'has-error' ) ); - event.target.querySelector( '.error-message' ).textContent = localize.error_codes[10]; + if ( ( newsletter.checked || endorser.checked || adoption.checked ) && ! emailAddress ) { + + // An opt-in checkbox requires an email. Surface it via the browser's + // native validation popup on the email field — the same UX as the + // required first/last name fields — rather than the message below. + const emailInput = event.target.querySelector( 'input[name="email"]' ); + emailInput.setCustomValidity( localize.error_codes[10] ); + emailInput.reportValidity(); window.bd4d.resetButton( submitButton, originalButtonText ); return; } @@ -151,16 +156,11 @@ window.bd4d = { }, emailFieldHandler: function( event ) { - if ( event.target.value.trim() ) { - window.bd4d.emailCheckbox.removeAttribute( 'disabled' ); - window.bd4d.supporterCheckbox.removeAttribute( 'disabled' ); - window.bd4d.emailField.classList.remove( 'has-error' ); - } else { - window.bd4d.emailCheckbox.removeAttribute( 'checked' ); - window.bd4d.emailCheckbox.setAttribute( 'disabled', 'disabled' ); - window.bd4d.supporterCheckbox.removeAttribute( 'checked' ); - window.bd4d.supporterCheckbox.setAttribute( 'disabled', 'disabled' ); - } + + // Clear the email field's validation state as the user types, so a prior + // "email required" popup or error styling doesn't persist. + event.target.setCustomValidity( '' ); + event.target.classList.remove( 'has-error' ); }, messageFieldHandler: function( event ) { @@ -201,8 +201,6 @@ window.bd4d = { if ( subscribeForm ) { window.bd4d.emailField = document.getElementById( 'inline-subscribe-email' ); window.bd4d.messageField = document.getElementById( 'inline-subscribe-message' ); - window.bd4d.emailCheckbox = document.getElementById( 'inline-subscribe-newsletter' ); - window.bd4d.supporterCheckbox = document.getElementById( 'inline-subscribe-supporter' ); window.bd4d.emailField.addEventListener( 'input', window.bd4d.emailFieldHandler ); window.bd4d.messageField.addEventListener( 'input', window.bd4d.messageFieldHandler ); diff --git a/wp-content/plugins/bd4d/bd4d.php b/wp-content/plugins/bd4d/bd4d.php index 9fabe68..0868d0c 100644 --- a/wp-content/plugins/bd4d/bd4d.php +++ b/wp-content/plugins/bd4d/bd4d.php @@ -12,14 +12,14 @@ * Author: Tech Matters * Text Domain: bd4d * Domain Path: /languages - * Version: 1.0.5 + * Version: 1.0.6 * Requires at least: 6.2 * * @package BD4D */ defined( 'ABSPATH' ) || exit; -define( 'BD4D_VERSION', '1.0.5' ); +define( 'BD4D_VERSION', '1.0.6' ); require_once __DIR__ . '/includes/class-bd4d.php'; require_once __DIR__ . '/includes/settings/class-settings.php'; diff --git a/wp-content/plugins/bd4d/includes/class-bd4d.php b/wp-content/plugins/bd4d/includes/class-bd4d.php index e923a17..b307512 100644 --- a/wp-content/plugins/bd4d/includes/class-bd4d.php +++ b/wp-content/plugins/bd4d/includes/class-bd4d.php @@ -148,10 +148,10 @@ public static function is_configured( &$errors ) { * @param string $affiliation User's company or organization. * @param string $message User's message. * @param boolean $newsletter Whether or not to subscribe to the newsletter. - * @param boolean $supporter Whether or not to identify the user as a supporter. + * @param boolean $endorser Whether or not to identify the user as a BD4D Endorser. * @param boolean $adoption Whether or not the user wants to learn about adopting BD4D. */ - public static function add( $email, $first_name = false, $last_name = false, $affiliation = false, $message = false, $newsletter = false, $supporter = false, $adoption = false ) { + public static function add( $email, $first_name = false, $last_name = false, $affiliation = false, $message = false, $newsletter = false, $endorser = false, $adoption = false ) { $data = [ 'fields' => [ 'Email Address' => $email ] ]; if ( $first_name ) { $data['fields']['First Name'] = $first_name; @@ -167,7 +167,7 @@ public static function add( $email, $first_name = false, $last_name = false, $af } $data['fields']['Email-Opted In?'] = $newsletter; - $data['fields']['CotW-Opted In?'] = $supporter; + $data['fields']['Endorser?'] = $endorser; $data['fields']['Adoption?'] = $adoption; $start_time = microtime( true ); @@ -244,14 +244,14 @@ public static function send_message() { $message = empty( $_POST['message'] ) ? '' : trim( sanitize_text_field( wp_unslash( $_POST['message'] ) ) ); $newsletter = ! empty( $_POST['newsletter'] ); - $supporter = ! empty( $_POST['supporter'] ); + $endorser = ! empty( $_POST['endorser'] ); $adoption = ! empty( $_POST['adoption'] ); - $subject = 'Welcome to the Better Deal for Data Community!'; + $subject = 'Welcome to a Better Deal for Data'; - $result = self::add( $email, $first_name, $last_name, $affiliation, $message, $newsletter, $supporter, $adoption ); + $result = self::add( $email, $first_name, $last_name, $affiliation, $message, $newsletter, $endorser, $adoption ); if ( $email ) { - $body = self::message_body( $message, $newsletter, $supporter, $adoption ); + $body = self::message_body( $message, $newsletter, $endorser, $adoption ); if ( self::SEND_SUCCESS === $result ) { $email_sent = self::send_confirmation_message( $email, $subject, $body ); if ( ! $email_sent ) { @@ -293,10 +293,10 @@ public static function send_confirmation_message( $recipient, $subject, $body ) * * @param string $comment User's comment. * @param boolean $newsletter User opted in to newsletter. - * @param boolean $supporter User opted in as supporter. + * @param boolean $endorser User opted in as a BD4D Endorser. * @param boolean $adoption User wants to learn about adopting BD4D. */ - public static function message_body( $comment, $newsletter, $supporter, $adoption ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed + public static function message_body( $comment, $newsletter, $endorser, $adoption ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed ob_start(); include dirname( __DIR__ ) . '/template-parts/auto-reply.php'; return trim( ob_get_clean() ); diff --git a/wp-content/plugins/bd4d/template-parts/auto-reply.php b/wp-content/plugins/bd4d/template-parts/auto-reply.php index 5a4bd78..1d3c8e1 100644 --- a/wp-content/plugins/bd4d/template-parts/auto-reply.php +++ b/wp-content/plugins/bd4d/template-parts/auto-reply.php @@ -8,32 +8,34 @@ ?> -Hello, and welcome to the Better Deal for Data community! +Hello, and welcome to the Better Deal for Data community–we're excited to support your organization in adopting the BD4D Standard! -We’re excited to learn more about how your organization works with data for good, and answer any questions you have about adopting the BD4D Standard. We will contact you personally within the next two business days. +We'd love to learn more about how you work with data for good, and answer any questions you have about the BD4D Commitments, BD4D Playbook, or implementation. We will contact you personally within the next two business days. -In the meantime, please don’t hesitate to contact us at info@bd4d.org. +In the meantime, please don't hesitate to contact us at info@bd4d.org to share any feedback or ideas. Many thanks, Hello, and thank you for joining the Better Deal for Data community! - -We're excited to welcome you to the movement to unlock the full potential of data to serve society, and add your name to our growing list of public supporters as part of our Coalition of the Willing. + +We're grateful for your endorsement of the BD4D Standard, and excited to welcome you to this movement to unlock the full potential of data to serve society. We're excited to welcome you to the movement to unlock the full potential of data to serve society. - + This message is to confirm that you have subscribed to our email updates via our website. If you wish to unsubscribe from our email updates, please reply to this email with the word "Unsubscribe." We'd love to hear your feedback, questions, or stories about data! You can reach us at info@bd4d.org. - -This message is to confirm that we have your permission to display your name and affiliation on our website. If you choose to sign up for email updates in the future, or if you have feedback, questions, or a data story to share, please send us a message at info@bd4d.org. We'd love to hear from you! - + +This message is to confirm that we have your permission to display your name and affiliation as a BD4D Endorser on our website. We will contact you if we have additional questions regarding your endorsement. + +If you would like to sign up for our email newsletter in the future, or if you have feedback, questions, or a data story to share, please do send us a message at info@bd4d.org. We'd love to hear from you! + This message is to confirm: -• that we have your permission to display your name and affiliation on our website; and -• that you have subscribed to our email updates via our website. If you wish to unsubscribe from our email updates, please reply to this email with the word "Unsubscribe." +• We have permission to display your name and affiliation as a BD4D Endorser on our website; and +• You have subscribed to our email updates via our website. If you wish to unsubscribe from our email updates, please reply to this email with the word "Unsubscribe." We'd love to hear your feedback, questions, or stories about data! You can reach us at info@bd4d.org. diff --git a/wp-content/plugins/bd4d/template-parts/form-email.php b/wp-content/plugins/bd4d/template-parts/form-email.php index 58e623c..6aa4b14 100644 --- a/wp-content/plugins/bd4d/template-parts/form-email.php +++ b/wp-content/plugins/bd4d/template-parts/form-email.php @@ -32,9 +32,9 @@