Add the buttons on the store locator side on the left

I will like to see at least 2 or 3 buttons without having to click on the actual location. it will save extra clicks

1 Like

Hi there and welcome to the Community, @GRAND_HACIENDA :waving_hand:

You’d like to add the CTA buttons to the location list and keep them in the location popup, am I right?

If this is the case, could you please specify whether you’re going to use badge for your locations? I’ll be happy to check with the devs if there is a custom solution :slightly_smiling_face:

I wont be using a badge. I just need to add CTA Buttons on the Preview Card and the location pop up!

Hi @Max Do you think we are able to do this? thank you

1 Like

Hi @GRAND_HACIENDA :waving_hand:

Apologies for the delayed response! Here is a custom solution from the devs:

// Script to add buttons to location preview cards
const WIDGET_ID = '4f210dac-7b71-458d-90c7-9a056d6d1f99';
const BUTTONS = {
	'St. Pete Beach': [
		{
			text: 'Book on OpenTable',
			link: 'https://www.opentable.com/restref/client/?restref=1218115&lang=en-US&ot_source=Restaurant%20website&corrid=04d94a88-0351-4987-a605-b1ac2aea2539',
		},
		{
			text: 'View Menu',
			link: 'https://grandhaciendarestaurant.com/menu/lunch/',
		},
		{
			text: 'Get Directions',
			address: '4393 Gulf Blvd, St Pete Beach, FL 33706, USA',
		},
		{
			text: 'Order Now',
			link: '',
		},
	],
	'4th Street St. Pete': [
		{
			text: 'Book on OpenTable',
			link: 'https://www.opentable.com/restref/client/?restref=1215949&lang=en-US&ot_source=Restaurant%20website&corrid=2f7626b2-3659-4980-a3f4-cb04e1f6f59a',
		},
		{
			text: 'View Menu',
			link: '#',
		},
		{
			text: 'Get Directions',
			address: '399 11th Ave N, St. Petersburg, FL 33701, USA',
		},
		{
			text: 'Order Now',
			link: '',
		},
	],
	'Tyrone Square Mall': [
		{
			text: 'Book on OpenTable',
			link: '',
		},
		{
			text: 'View Menu',
			link: '#',
		},
		{
			text: 'Get Directions',
			address: '2424 Tyrone Blvd N, St. Petersburg, FL 33710, USA',
		},
		{
			text: 'Order Now',
			link: '',
		},
	],
	'West Chase Tampa': [
		{
			text: 'Book on OpenTable',
			link: 'https://www.opentable.com/restref/client/?restref=1218124&lang=en-US&ot_source=Restaurant%20website&corrid=f3362c85-c467-4731-844d-1836ac6a3848',
		},
		{
			text: 'View Menu',
			link: '',
		},
		{
			text: 'Get Directions',
			address: '11955 Sheldon Rd, Tampa, FL 33626, USA',
		},
		{
			text: 'Order Now',
			link: '',
		},
	],
	'Feather Sound': [
		{
			text: 'Book on OpenTable',
			link: 'https://www.opentable.co.uk/restref/client/?restref=1308904&lang=en-GB&ot_source=Restaurant%20website&corrid=6619c9c0-e552-42ba-805d-52974bcfe8bb',
		},
		{
			text: 'View Menu',
			link: '',
		},
		{
			text: 'Get Directions',
			address: '2325 Ulmerton Rd #3, Clearwater, FL 33762, USA',
		},
		{
			text: 'Order Now',
			link: '',
		},
	],
	Carrollwood: [
		{
			text: 'Reserve a table',
			link: 'https://www.opentable.com/r/grand-hacienda-carrollwood-tampa?corrid=68346461-e50d-41ba-9ecc-373057393220&avt=eyJ2IjoyLCJtIjowLCJwIjowLCJzIjowLCJuIjowfQ&p=2&sd=2024-05-20T19%3A00%3A00',
		},
		{
			text: 'Buy Gift Card',
			link: '',
		},
		{
			text: 'Catering Menu',
			link: '',
		},
		{
			text: 'Order Now',
			link: '',
		},
	],
};

const waitForElem = (selector) =>
	new Promise((resolve) => {
		if (document.querySelector(selector)) {
			return resolve(document.querySelector(selector));
		}
		const observer = new MutationObserver(() => {
			if (document.querySelector(selector)) {
				observer.disconnect();
				resolve(document.querySelector(selector));
			}
		});
		observer.observe(document.body, {
			childList: true,
			subtree: true,
		});
	});

const DEFAULT_BUTTONS = {
	book: {
		icon: 'https://static.elfsight.com/icons/opentable.svg',
		color: 'rgb(218, 47, 54)',
	},
	menu: { icon: 'https://static.elfsight.com/icons/menu-book.svg' },
	directions: { icon: 'https://static.elfsight.com/icons/directions.svg' },
	order: { icon: 'https://static.elfsight.com/icons/shopping-bag-2.svg' },
	giftCard: {
		icon: 'https://static.elfsight.com/icons/price-tag-outlined.svg',
	},
};

const locationListSelector = '[class*="directory-locations-list__List-sc"]';
const formatStr = (str) => str.trim().toLowerCase();

const getButtonDefaults = (label) => {
	if (label === 'book on opentable' || label === 'reserve a table') {
		return DEFAULT_BUTTONS.book;
	}
	if (label.includes('menu')) return DEFAULT_BUTTONS.menu;
	if (label.includes('directions')) return DEFAULT_BUTTONS.directions;
	if (label.includes('order')) return DEFAULT_BUTTONS.order;
	if (label.includes('gift card')) return DEFAULT_BUTTONS.giftCard;
	return {};
};

const getDirectionsLink = (address) =>
	'https://www.google.com/maps/dir/Your+Location/' +
	encodeURIComponent(address);

const createButton = (data) => {
	const defults = getButtonDefaults(formatStr(data.text));

	const btn = document.createElement('div');
	btn.textContent = data.text;
	btn.style.cssText = `
    display: flex;
    gap: 5px;
    align-items: center;
    padding: 4px 9px;
    border-radius: 5px;
    font-size: 13px;
    font-weight: 700;
    color: #fff;
    background: ${defults.color ? defults.color : 'black'};
  `;

	if (defults.icon) {
		const icon = document.createElement('img');
		icon.src = defults.icon;
		icon.style.cssText = 'width: 12px; height: 12px; filter: invert(1);';
		btn.prepend(icon);
	}

	const link = data.address ? getDirectionsLink(data.address) : data.link;
	if (link) {
		btn.addEventListener('click', (e) => {
			e.stopPropagation();
			window.open(link, '_blank');
		});
	}

	return btn;
};

const findLocation = (locationName, list) =>
	[...list.children].find((card) => {
		const titleEl = card.querySelector('.es-location-preview-title');
		return formatStr(titleEl?.textContent) === formatStr(locationName);
	});

const addBtnsToLocation = (locationName, buttonsData, list) => {
	const location = findLocation(locationName, list);
	const container = document.createElement('div');
	container.style.cssText = 'display:flex; flex-wrap:wrap; gap: 8px';
	buttonsData.forEach((btn) => {
		const button = createButton(btn);
		container.append(button);
	});
	location
		?.querySelector('[class*="location-preview-image-layout__Content-sc"]')
		?.append(container);
};

const addButtons = (locationList) => {
	Object.entries(BUTTONS).forEach(([locationName, buttonsData]) =>
		addBtnsToLocation(locationName, buttonsData, locationList)
	);
};

waitForElem(`[class*="${WIDGET_ID}"] ${locationListSelector}`).then(
	(locations) => {
		addButtons(locations);

		const widgetContainer = locations.closest('.es-embed-root');
		const floatingButton = widgetContainer?.querySelector(
			'[class*="FloatingButton__FloatingButtonContainer"] button'
		);
		if (!floatingButton) return;
		floatingButton.addEventListener('click', () =>
			setTimeout(() => {
				const locations = widgetContainer.querySelector(locationListSelector);
				if (!locations) return;
				addButtons(locations);
			})
		);
	}
);

This code should be added to the Custom JS field on the Settings tab of your widget’s settings

At the beginning of the script, there is a BUTTONS array that specifies data for each location in the following format:

Where:
'St. Pete Beach' - the name of the location

For each location, there is also button info: text specifies the button text, link specifies the URL. For the “Get Directions” button, no link needs to be specified, but an address is required.

Currently, some buttons do not have links added. If you want to add them, you will need to include them in the code.

Please try it out and let me know if it helped :slightly_smiling_face: