PageSourceSearch

https://bluebird-city.co.uk/wp-content/plugins/evolv-enquiry-forms/assets/js/init.js?debug=1790697187

js bluebird-city.co.uk collected 2026-09-29 21:50:18 UTC 7,226 bytes, 212 lines download raw bytes

1document.addEventListener('DOMContentLoaded', function () {
2	// Init datepickers
3	const datepickers = document.querySelectorAll('.dd-enquiry-form__datepicker');
4	datepickers.forEach(input => {
5		input.type = 'date';
6		input.addEventListener('change', function () {
7			const date = new Date(this.value);
8			if (!isNaN(date.getTime())) {
9				const day = date.getDate();
10				const month = date.toLocaleDateString('en-GB', { month: 'short' });
11				const year = date.getFullYear().toString().slice(-2);
12				const formattedDate = `${day} ${month}, ${year}`;
13				this.setAttribute('data-formatted', formattedDate);
14			}
15		});
16	});
17
18	// Function to handle venue selection change
19	function handleVenueChange(selectElement) {
20		// Don't process if no value is selected
21		if (!selectElement.value || selectElement.value === '') {
22			return;
23		}
24
25		const [subvenueVal = '', venueVal = ''] = selectElement.value.split(':');
26		const form = selectElement.closest('form') || document;
27		const subvenueInput = form.querySelector('input[name="subvenue"]');
28		const venueInput = form.querySelector('input[name="venue"]');
29		const eventTypeSelect = form.querySelector('select[name="type_of_event"]');
30
31		if (subvenueInput) {
32			subvenueInput.value = subvenueVal;
33		}
34		if (venueInput) {
35			venueInput.value = venueVal;
36		}
37
38		// Update event types dropdown based on selected venue
39		if (eventTypeSelect && typeof evolvEnquiryForms !== 'undefined' && evolvEnquiryForms.venues) {
40			// Try exact match first, then trimmed match
41			let selectedVenue = evolvEnquiryForms.venues.find(venue => venue.value === selectElement.value);
42			if (!selectedVenue) {
43				// Try with trimmed values
44				selectedVenue = evolvEnquiryForms.venues.find(
45					venue => venue.value.trim() === selectElement.value.trim(),
46				);
47			}
48
49			if (selectedVenue && selectedVenue.event_types && selectedVenue.event_types.length > 0) {
50				// Store current selection if it exists
51				const currentValue = eventTypeSelect.value;
52
53				// Clear existing options
54				eventTypeSelect.innerHTML = '';
55
56				// Add default option
57				const defaultOption = document.createElement('option');
58				defaultOption.value = '';
59				defaultOption.textContent = 'Please select';
60				defaultOption.disabled = true;
61				defaultOption.selected = !currentValue || currentValue === '';
62				eventTypeSelect.appendChild(defaultOption);
63
64				// Add event type options
65				selectedVenue.event_types.forEach(eventType => {
66					const option = document.createElement('option');
67					option.value = eventType;
68					option.textContent = eventType;
69					// Preserve selection if it matches
70					if (currentValue === eventType) {
71						option.selected = true;
72						defaultOption.selected = false;
73					}
74					eventTypeSelect.appendChild(option);
75				});
76			}
77		}
78	}
79
80	// Handle original venue select (blog ID 31)
81	const venueSelects = document.querySelectorAll('.js-venue-select');
82	venueSelects.forEach(select => {
83		select.addEventListener('change', function () {
84			handleVenueChange(this);
85		});
86
87		// Trigger change on page load if a venue is already selected
88		if (select.value) {
89			handleVenueChange(select);
90		}
91	});
92
93	// Handle additional venue select
94	const additionalVenueSelects = document.querySelectorAll('.js-additional-venue-select');
95	additionalVenueSelects.forEach(select => {
96		select.addEventListener('change', function () {
97			handleVenueChange(this);
98		});
99
100		// Trigger change on page load if a venue is already selected
101		if (select.value && select.value !== '') {
102			handleVenueChange(select);
103		}
104	});
105
106	// Attach to all buttons with class dd-enquiry-form__submit
107	const submitButtons = document.querySelectorAll('.dd-enquiry-form__submit');
108
109	submitButtons.forEach(button => {
110		// Prevent duplicate event listeners
111		if (button.dataset.listenerAttached === 'true') return;
112		button.dataset.listenerAttached = 'true';
113
114		button.addEventListener('click', e => {
115			e.preventDefault();
116
117			const form = button.closest('.dd-enquiry-form');
118			if (!form) return;
119
120			// Prevent multiple submissions
121			if (button.disabled || button.dataset.submitting === 'true') return;
122			button.dataset.submitting = 'true';
123			button.disabled = true;
124
125			// Reset messages just for this form
126			form.querySelectorAll('.dd-enquiry-form__message').forEach(msg => msg.remove());
127
128			if (!form.checkValidity()) {
129				// Find the first invalid field
130				const firstInvalid = form.querySelector(':invalid');
131
132				// Create an accessible error message
133				let msg = firstInvalid.nextElementSibling;
134				if (!msg || !msg.classList.contains('dd-enquiry-form__message')) {
135					msg = document.createElement('span');
136					msg.style.color = 'red';
137					msg.style.fontSize = '12px';
138					msg.classList.add('dd-enquiry-form__message', 'f__paragraph-regular');
139					msg.setAttribute('role', 'alert'); // screen readers will announce this
140					firstInvalid.after(msg);
141				}
142
143				// Set a descriptive message
144				if (firstInvalid.validity.valueMissing) {
145					msg.textContent = `Please enter your ${firstInvalid.name.replace('_', ' ')}.`;
146				} else if (firstInvalid.validity.typeMismatch) {
147					msg.textContent = `Please enter a valid ${firstInvalid.type}.`;
148				} else {
149					msg.textContent = `Please correct this field.`;
150				}
151
152				// Focus the first invalid field
153				firstInvalid.focus();
154
155				// Re-enable the button since validation failed
156				button.disabled = false;
157				button.dataset.submitting = 'false';
158				return;
159			}
160
161			const formData = new FormData(form);
162
163			// Debug log
164			for (const pair of formData.entries()) {
165				console.log(`${pair[0]}, ${pair[1]}`);
166			}
167
168			// GA event tracking
169			const eventTypeElem = form.querySelector('select[name="type_of_event"]');
170			if (eventTypeElem) {
171				const eventType = eventTypeElem.value;
172				const eventTypeGaName = `enquiry_${eventType.replace(/ /g, '_').toLowerCase()}`;
173
174				window.dataLayer = window.dataLayer || [];
175				window.dataLayer.push({ event: eventTypeGaName });
176				console.log('Event pushed to dataLayer:', eventTypeGaName);
177			}
178
179			// Send via fetch
180			fetch(evolvEnquiryForms.ajaxUrl, {
181				method: 'POST',
182				body: formData,
183			})
184				.then(response => response.text())
185				.then(data => {
186					if (data.indexOf('Your request has been queued') !== -1) {
187						form.style.display = 'none';
188						const p = document.createElement('p');
189						p.classList.add('dd-enquiry-form__message', 'f__paragraph-regular', 'text-center');
190						p.innerHTML = 'Thank you for your enquiry. A member of the team will be in touch soon.';
191						form.after(p);
192						// Keep button disabled on success
193					} else {
194						const p = document.createElement('p');
195						p.classList.add('dd-enquiry-form__message', 'f__paragraph-regular', 'text-center');
196						p.innerHTML =
197							'Sorry, there was a problem sending your enquiry. Please get in touch via the contact page or try again later.';
198						form.after(p);
199						// Re-enable button on error so user can retry
200						button.disabled = false;
201						button.dataset.submitting = 'false';
202					}
203				})
204				.catch(error => {
205					console.error(error);
206					// Re-enable button on error so user can retry
207					button.disabled = false;
208					button.dataset.submitting = 'false';
209				});
210		});
211	});
212});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.