feat(bf): Server Location selector beside the deal Buy, carried into both buy forms

Move the homepage's Server Location lockup (label + select) out of section#pricing
and into the HOST27 deal card's CTA row, next to the Buy button. There is still
exactly ONE element with id pricingServerLocation on the page, so buyNow() — which
resolves the selector by id — and every pricing button keep working untouched.
The pricing block keeps only the Odoo Version selector and reads the same global
location selection.

- markup: new .bf-cta-row in the deal form (selector left, brass Buy right);
  location lockup removed from .pricing-server-row
- CSS (page-scoped): .bf-cta-row / .bf-cta-location, and the light-on-ivory twin
  of .pricing-server-select (style.css carries neither; the homepage styles it
  inline for its dark section). Wraps at 375px with no horizontal overflow; the
  Buy stays the one dominant action.
- static/black-friday.js: on submit of the native post_basket forms, write the
  chosen city + version into the basket line's `info`, exactly as buyNow() does.
  Additive only — with JavaScript off the POST is unchanged (no info) and the
  selector is empty because its options are built here (pre-existing behaviour).

Untouched: the hidden redirect=/coupon/HOST27, the single plausible-event-name=Buy
mark, the price, the countdown, #trialForm, the booking link and the consent gate.

Verified: verify-html.py PROBLEMS 0; competitor QC exit 0 on the page (74
pre-existing site-wide, 0 added); node --check OK; impeccable detect 35 findings,
identical set to HEAD (0 introduced); live browser: fastest server auto-selected,
wire body basket=[{"product_id":4,"qty":1,"info":"boston|20.0"}] and it tracks the
selectors on repeat submits; 375px no overflow.
This commit is contained in:
webmaster committed 2026-11-02 09:42:01 +00:00
1 parent 0f8ae45e59
commit 9e38e05aad
2 files changed
+93 -3

No files matched your search

+30
View File
@@ -307,6 +307,36 @@
document.body.removeChild(form);
};
/* ---- Carry the chosen Server Location + Odoo version into the native buy forms ----
* The Black Friday buy buttons are plain form POSTs to /shop/post_basket, so they work with
* JavaScript off. buyNow() builds `info` for the JS buttons; this does exactly the same for
* the native forms, on submit, from the one global selector pair (#pricingServerLocation +
* #pricingOdooVersion). Additive only: with JavaScript off the basket posts exactly as before
* (no info) and the selector is empty anyway because its options are built here. The POST is
* untouched — only the form's own hidden `basket` input is rewritten. */
(function () {
var forms = document.querySelectorAll('form[action*="/shop/post_basket"]');
forms.forEach(function (form) {
form.addEventListener('submit', function () {
var basket = form.querySelector('input[name="basket"]');
if (!basket) return;
var locSelect = document.getElementById('pricingServerLocation');
var verSelect = document.getElementById('pricingOdooVersion');
var location = locSelect ? locSelect.value : '';
var version = verSelect ? verSelect.value : '';
var info = location ? location.replace('.odoo4projects.com', '') : '';
if (version) { info += (info ? '|' : '') + version; }
if (!info) return;
try {
var items = JSON.parse(basket.value);
if (!Array.isArray(items)) return;
items.forEach(function (it) { if (it) { it.info = info; } });
basket.value = JSON.stringify(items);
} catch (e) { /* leave the basket untouched rather than break the purchase */ }
});
});
})();
/* ---- Buy buttons + Custom Quote modal ---- */
(function () {
document.querySelectorAll('.btn-buy').forEach(function (btn) {