Conditional Logic to Replace Elfsight Form Submit Button

Hi,

I was wondering if it is possible to replace the default submit button in a Form Builder widget on my Squarespace website with different text and a link that takes them to another page on my website if they select “No” to the first question in my form?

Currently, regardless of whether the potential customer clicks Yes or No to the first question, it allows them to click “Get Your Free Quote” which effectively submits the form. If they select “No” I’d like the link to change to “Join Our Waiting List” and redirect them to: https://k9poopertroopers.com.au/waiting-list.

If required, a link to the form in question is here: https://k9poopertroopers.com.au/get-your-free-quote. Password is “K9PT”.

Thank you for any time and effort you spend on this—it is much appreciated.

Michael

2 Likes

Hi there, @Michael_Surnak :waving_hand:

I guess this customization is possible. Your request is with our devs now, and I’ll update you as soon as I have their response :slightly_smiling_face:

2 Likes

Thank you max, that would be very much appreciated.

2 Likes

Thank you for waiting!

Please add this script to the Custom JS field on the Settings tab of your widget’s settings and let me know how it worked:

const widgetSelector =
	'#eapps-form-builder-63498d7a-5c3d-4102-be49-ddfa279c560b';
const targetLabel =
	'Is your service address located within our current service area?';

const newButtonText = 'Join Our Waiting List';
const newButtonLink = 'https://k9poopertroopers.com.au/waiting-list';

const waitForElement = (selector, root = document) =>
	new Promise((res) => {
		const obs = new MutationObserver(() => {
			const el = root.querySelector(selector);
			if (el) {
				res(el);
				obs.disconnect();
			}
		});
		obs.observe(root, { childList: true, subtree: true });
	});

waitForElement(widgetSelector).then((container) => {
	let originalButtonText = null;

	function applyLogic() {
		const field = [
			...container.querySelectorAll('[class*="FormFieldLayout__Container-sc"]'),
		].find((f) => {
			const labelEl = f.querySelector('[class*="FormFieldLayout__Label-sc"]');
			if (!labelEl) return false;

			const labelText = labelEl.textContent?.trim().toLowerCase();
			return labelText?.startsWith(targetLabel.trim().toLowerCase());
		});

		if (!field) return;

		if (field.dataset.pooperInit === '1') return;
		field.dataset.pooperInit = '1';

		const buttonEl = container.querySelector('button[aria-label="Next"]');
		if (!buttonEl) return;

		const buttonLabel = buttonEl.querySelector(
			'[class*="ButtonBase__Ellipsis-sc"]'
		);
		if (!buttonLabel) return;

		if (!originalButtonText) originalButtonText = buttonLabel.textContent;

		const noInput = field.querySelector('input[value="No"]');
		const yesInput = field.querySelector('input[value="Yes"]');

		function updateButtonState() {
			if (noInput.checked) {
				buttonLabel.textContent = newButtonText;
				buttonEl.onclick = (e) => {
					e.preventDefault();
					e.stopPropagation();
					window.open(newButtonLink, '_blank');
				};
			} else {
				buttonLabel.textContent = originalButtonText;
				buttonEl.onclick = null;
			}
		}

		noInput.addEventListener('change', updateButtonState);
		yesInput?.addEventListener('change', updateButtonState);

		updateButtonState();
	}

	applyLogic();

	const obs = new MutationObserver(() => applyLogic());
	obs.observe(container, { childList: true, subtree: true });
});

Note: Custom JS doesn’t function in the preview mode, so you can check the result right on your website :slightly_smiling_face:

1 Like

Hi Max, I’ve added the code into the Custom JS field, validated it, and then published the form. I checked it on the website, and unfortunately nothing appears to have happened to the button, and the button also still submits the form as before and does not link to the Join Our Waiting List page.

I’ve left the custom JS in the form in case it assists the devs in troubleshooting.

Please let me know if there’s anything else I can do from my end.

2 Likes

I am so sorry about that!

Our devs will double-check the code. I’ll report back once I have their response :slightly_smiling_face:

2 Likes

Hi Max,

Logged on this morning and discovered that it’s working perfectly! Thank you to you and the dev team. Did the dev team do something in the background to make it work?

Looks like the JS code in the form is differen’t from the original that you sent through:

const widgetSelector =
#eapps-form-builder-63498d7a-5c3d-4102-be49-ddfa279c560b’;
const targetLabel =
‘Is your service address located within our current service area?’;

const newButtonText = ‘Join Our Waiting List’;
const newButtonLink = ‘https://k9poopertroopers.com.au/waiting-list’;

const originalTextMap = new WeakMap();
const patchedInputs = new WeakSet();
let buttonGlobalBound = false;

function patchStep(container) {
const field = […container.querySelectorAll(‘[class*=“FormFieldLayout__Container-sc”]’)]
.find(f => {
const labelEl = f.querySelector(‘[class*=“FormFieldLayout__Label-sc”]’);
return labelEl && labelEl.textContent.trim().toLowerCase()
.startsWith(targetLabel.toLowerCase());
});

if (!field) return;

const buttonEl = container.querySelector(‘button[aria-label=“Get Your Free Quote”]’);
if (!buttonEl) return;

const buttonLabel = buttonEl.querySelector(‘[class*=“ButtonBase__Ellipsis-sc”]’);
if (!buttonLabel) return;

if (!originalTextMap.has(buttonEl)) {
originalTextMap.set(buttonEl, buttonLabel.textContent);
}

const noInput = field.querySelector(‘input[value=“No”]’);
const yesInput = field.querySelector(‘input[value=“Yes”]’);
if (!noInput || !yesInput) return;

function updateButtonState() {
const shouldShowAlt = noInput.checked || (!noInput.checked && !yesInput.checked);

const getNewText = () => {
  if (shouldShowAlt) return newButtonText;
  if (buttonEl.hasAttribute('aria-label', 'Next')) return 'Next';
  return originalTextMap.get(buttonEl);
};

buttonLabel.textContent = getNewText();
buttonEl.dataset._waitingActive = shouldShowAlt ? "1" : "0";

}

[noInput, yesInput].forEach(input => {
if (!patchedInputs.has(input)) {
patchedInputs.add(input);
input.addEventListener(‘click’, () => setTimeout(updateButtonState, 0));
}
});

if (!buttonGlobalBound) {
buttonGlobalBound = true;
buttonEl.addEventListener(‘click’, (e) => {
if (buttonEl.dataset._waitingActive === “1”) {
e.preventDefault();
e.stopPropagation();
window.open(newButtonLink, ‘_blank’);
}
}, true);
}

updateButtonState();
}

const waitForWidget = setInterval(() => {
const container = document.querySelector(widgetSelector);
if (container) {
patchStep(container);
setInterval(() => patchStep(container), 300);
clearInterval(waitForWidget);
}
}, 300);

1 Like

Just an update for anyone following and for my own future reference:

I noticed the “Join Our Waiting List” button was already showing before any selection was made.

I’ve managed to fix this (with the assistance of ChatGPT) by changing this line:

const shouldShowAlt = noInput.checked || (!noInput.checked && !yesInput.checked);

to be:

const shouldShowAlt = noInput.checked;

3 Likes

Yep, as you’ve correctly noticed, devs adjusted the code, and I am happy to know it worked for you.

If anything else comes up, we’re always here to help :slightly_smiling_face:

2 Likes