docs: tailor donor-discount snippet for FluentForms conditional pricing
Hidden donor_tier field (regular/donor/member) driven by the email lookup; payment options shown via FF conditional logic. Uses the native value setter + input/change dispatch so FF's Vue model registers the programmatic change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
fb2fdcb6b8
commit
ba5cb8a9fb
1 changed files with 54 additions and 30 deletions
|
|
@ -23,69 +23,89 @@ GET https://scan.beartariacampgrounds.com/api/public/donor-eligibility?key=<SECR
|
||||||
> radius is small. Rotate the secret by changing `PUBLIC_LOOKUP_SECRET` and
|
> radius is small. Rotate the secret by changing `PUBLIC_LOOKUP_SECRET` and
|
||||||
> redeploying.
|
> redeploying.
|
||||||
|
|
||||||
## Form setup
|
## Form setup (conditional pricing)
|
||||||
|
|
||||||
1. On the ticket form add a **Custom HTML** element (or use FluentForms Pro's
|
The idea: a **hidden field** `donor_tier` holds `regular` / `donor` / `member`.
|
||||||
custom JS). Give your email field a known name (default FF `email`).
|
The JS sets it from the email lookup, and your payment options are shown/hidden
|
||||||
2. Decide the discount mechanism. Two common options:
|
by FluentForms conditional logic based on its value.
|
||||||
- **Coupon:** configure a coupon in the form's payment settings; the JS
|
|
||||||
auto-fills + applies it for eligible emails.
|
1. **Hidden field.** Add a *Hidden Field*, name it exactly `donor_tier`, default
|
||||||
- **Conditional price:** add a hidden field (e.g. `donor_tier`) and use
|
value `regular`.
|
||||||
FluentForms conditional logic to show a discounted payment option when it
|
2. **Email field.** Note its name (default `email`).
|
||||||
equals `member`/`donor`.
|
3. **Payment options.** Set up two payment items (or two options of a
|
||||||
3. Paste the snippet below into the Custom HTML element, editing the marked
|
multiple-choice payment field) — a regular price and a discounted price — and
|
||||||
constants and the `applyDiscount()` body to match your form.
|
give each **conditional logic**:
|
||||||
|
- **Regular price:** show when `donor_tier` **is** `regular`
|
||||||
|
- **Donor price:** show when `donor_tier` **is** `donor` **OR** `donor_tier`
|
||||||
|
**is** `member` (add both rules with "match any").
|
||||||
|
4. **Custom HTML.** Add a *Custom HTML* element and paste the snippet below,
|
||||||
|
setting `KEY` to your `PUBLIC_LOOKUP_SECRET` (and `EMAIL_SELECTOR` if your
|
||||||
|
email field isn't named `email`).
|
||||||
|
|
||||||
|
> FluentForms is Vue-driven, so a plain `input.value = …` won't update its
|
||||||
|
> model and conditional logic won't fire. The snippet uses the native value
|
||||||
|
> setter + dispatches `input`/`change`, which is the reliable way to make FF
|
||||||
|
> notice a programmatic change. Test on your form; if conditional logic still
|
||||||
|
> doesn't react, tell me your FF version and I'll adapt.
|
||||||
|
|
||||||
## Snippet
|
## Snippet
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<div id="donor-status" style="margin:6px 0;font-size:14px;"></div>
|
<div id="donor-status" style="margin:6px 0;font-size:14px;font-weight:600;"></div>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
var API = "https://scan.beartariacampgrounds.com/api/public/donor-eligibility";
|
var API = "https://scan.beartariacampgrounds.com/api/public/donor-eligibility";
|
||||||
var KEY = "REPLACE_WITH_PUBLIC_LOOKUP_SECRET";
|
var KEY = "REPLACE_WITH_PUBLIC_LOOKUP_SECRET";
|
||||||
var EMAIL_SELECTOR = 'input[name="email"]'; // adjust to your field
|
var EMAIL_SELECTOR = 'input[name="email"]'; // adjust if needed
|
||||||
|
var TIER_SELECTOR = 'input[name="donor_tier"]'; // the hidden field
|
||||||
var statusEl = document.getElementById("donor-status");
|
var statusEl = document.getElementById("donor-status");
|
||||||
var lastChecked = "";
|
var lastChecked = "";
|
||||||
|
|
||||||
function applyDiscount(tier) {
|
// Set a framework-bound input's value so Vue/React actually notice it.
|
||||||
// ── EDIT THIS to your form's discount mechanism ──────────────────
|
function setNativeValue(el, value) {
|
||||||
// Option A — set a hidden field that conditional logic keys off:
|
var proto = Object.getPrototypeOf(el);
|
||||||
var hidden = document.querySelector('input[name="donor_tier"]');
|
var protoSetter = Object.getOwnPropertyDescriptor(proto, "value");
|
||||||
if (hidden) { hidden.value = tier; hidden.dispatchEvent(new Event("change", {bubbles:true})); }
|
var ownSetter = Object.getOwnPropertyDescriptor(el, "value");
|
||||||
// Option B — auto-apply a coupon (uncomment + set the code):
|
if (ownSetter && protoSetter && ownSetter.set !== protoSetter.set) {
|
||||||
// var coupon = document.querySelector('.ff_coupon_wrapper input[type="text"]');
|
protoSetter.set.call(el, value);
|
||||||
// if (coupon) { coupon.value = "DONOR"; coupon.dispatchEvent(new Event("input",{bubbles:true}));
|
} else if (protoSetter) {
|
||||||
// var btn = document.querySelector('.ff_coupon_wrapper button'); if (btn) btn.click(); }
|
protoSetter.set.call(el, value);
|
||||||
// ─────────────────────────────────────────────────────────────────
|
} else {
|
||||||
|
el.value = value;
|
||||||
|
}
|
||||||
|
el.dispatchEvent(new Event("input", { bubbles: true }));
|
||||||
|
el.dispatchEvent(new Event("change", { bubbles: true }));
|
||||||
}
|
}
|
||||||
function clearDiscount() {
|
|
||||||
var hidden = document.querySelector('input[name="donor_tier"]');
|
function setTier(tier) {
|
||||||
if (hidden) { hidden.value = ""; hidden.dispatchEvent(new Event("change", {bubbles:true})); }
|
var el = document.querySelector(TIER_SELECTOR);
|
||||||
|
if (el) setNativeValue(el, tier); // "regular" | "donor" | "member"
|
||||||
}
|
}
|
||||||
|
|
||||||
function check(email) {
|
function check(email) {
|
||||||
if (!email || email === lastChecked) return;
|
if (!email || email === lastChecked) return;
|
||||||
lastChecked = email;
|
lastChecked = email;
|
||||||
statusEl.textContent = "Checking donor status…";
|
statusEl.textContent = "Checking donor status…";
|
||||||
|
statusEl.style.color = "#888";
|
||||||
fetch(API + "?key=" + encodeURIComponent(KEY) + "&email=" + encodeURIComponent(email))
|
fetch(API + "?key=" + encodeURIComponent(KEY) + "&email=" + encodeURIComponent(email))
|
||||||
.then(function (r) { return r.json(); })
|
.then(function (r) { return r.json(); })
|
||||||
.then(function (d) {
|
.then(function (d) {
|
||||||
if (d && d.eligible) {
|
if (d && d.eligible) {
|
||||||
statusEl.textContent = (d.tier === "member" ? "🐻 Member" : "⭐ Donor") + " discount applied!";
|
setTier(d.tier); // "member" or "donor"
|
||||||
|
statusEl.textContent = (d.tier === "member" ? "🐻 Member" : "⭐ Donor") + " pricing unlocked!";
|
||||||
statusEl.style.color = "#1b7f3b";
|
statusEl.style.color = "#1b7f3b";
|
||||||
applyDiscount(d.tier);
|
|
||||||
} else {
|
} else {
|
||||||
|
setTier("regular");
|
||||||
statusEl.textContent = "";
|
statusEl.textContent = "";
|
||||||
clearDiscount();
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function () { statusEl.textContent = ""; });
|
.catch(function () { setTier("regular"); statusEl.textContent = ""; });
|
||||||
}
|
}
|
||||||
|
|
||||||
function bind() {
|
function bind() {
|
||||||
var el = document.querySelector(EMAIL_SELECTOR);
|
var el = document.querySelector(EMAIL_SELECTOR);
|
||||||
if (!el) { return setTimeout(bind, 500); } // form may render late
|
if (!el) { return setTimeout(bind, 500); } // form may render late
|
||||||
|
setTier("regular"); // start at regular price
|
||||||
el.addEventListener("blur", function () { check(el.value.trim().toLowerCase()); });
|
el.addEventListener("blur", function () { check(el.value.trim().toLowerCase()); });
|
||||||
}
|
}
|
||||||
bind();
|
bind();
|
||||||
|
|
@ -99,3 +119,7 @@ GET https://scan.beartariacampgrounds.com/api/public/donor-eligibility?key=<SECR
|
||||||
curl "https://scan.beartariacampgrounds.com/api/public/donor-eligibility?key=<SECRET>&email=adam21stevens@gmail.com"
|
curl "https://scan.beartariacampgrounds.com/api/public/donor-eligibility?key=<SECRET>&email=adam21stevens@gmail.com"
|
||||||
# -> {"eligible":true,"tier":"member"}
|
# -> {"eligible":true,"tier":"member"}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If member and donor get the **same** discounted price, simplify: set the donor
|
||||||
|
price to show when `donor_tier` **is not** `regular`, and you can ignore the
|
||||||
|
member/donor distinction.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue