class EnquiryComponent {
constructor(requiredKeys = [], title = null, fieldsPerRow = 2) {
this.title = title || this.getDefaultTitle();
this.fieldsPerRow = fieldsPerRow;
this.packageData = null;
this.selectedPackageKey = null;
this.requiredKeys = requiredKeys;
this.form = null;
}
getDefaultTitle() {
return 'To make your enquiry online, fill in the form below and click submit.'; // Default title
}
// Format a date to UK format (dd/mm/yyyy)
formatDate(date, format = 'uk') {
if (date instanceof Date) {
const day = String(date.getDate()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, '0');
const year = date.getFullYear();
if (format === 'uk') {
return `${day}/${month}/${year}`; // UK format
} else {
return `${year}-${month}-${day}`; // ISO format
}
} else {
date = date.toString();
const year = date.slice(0, 4);
const month = date.slice(4, 6);
const day = date.slice(6, 8);
if (format === 'uk') {
return `${day}/${month}/${year}`; // UK format
} else {
return `${year}-${month}-${day}`; // ISO format
}
}
}
getCurrentUrl() {
return window.location.href;
}
// Initialize the component and fetch package data
async init(targetSelector) {
try {
this.packageData = await this.fetchPackageData();
const requiredKeysLower = this.requiredKeys.map(key => key.toLowerCase());
const validPackages = Object.keys(this.packageData)
.filter(key => requiredKeysLower.includes(key.toLowerCase()))
.reduce((obj, key) => {
obj[key] = this.packageData[key];
return obj;
}, {});
// Check if validPackages is not empty
if (Object.keys(validPackages).length > 0) {
// Use the first valid package from the filtered data
this.packageData = validPackages;
this.selectedPackageKey = Object.keys(this.packageData)[0]; // Select the first valid package
this.renderForm(targetSelector); // Render the form for the selected package
} else {
console.warn("No valid packages found. Skipping form render.");
}
this.applySelect2();
jQuery("#packageDropdown").on("change", (event) => {
this.selectedPackageKey = event.target.value;
const selectedPackage = this.packageData[this.selectedPackageKey];
if (selectedPackage) {
var form = this.form;
// Remove elements with the class "packagefields"
const packageFields = form.querySelectorAll('.packagefields');
packageFields.forEach(field => field.remove());
const packageHiddenFields = form.querySelectorAll('.d-none');
packageHiddenFields.forEach(field => field.remove());
const newFields = this.packageFields(this.packageData[this.selectedPackageKey]);
this.addFieldsToRow(form, newFields, "packagefields");
const rowMt3 = form.querySelector('.row.mt-3');
if (rowMt3) {
form.appendChild(rowMt3);
}
this.applySelect2();
}
});
} catch (error) {
console.error('Error fetching package data:', error);
}
}
applySelect2() {
jQuery(".custom-select").select2({
placeholder: 'Select an option', // Optional: Set a placeholder
allowClear: true,
width: "100%"
});
}
getOrigin() {
return window.location.origin;
}
getJsonUrls() {
return [
this.getOrigin()+"/enquirydetails/packages.phtml",
this.getOrigin()+"/enquirydetails/explorations.phtml"
];
}
async fetchPackageData() {
try {
const urls = this.getJsonUrls(); // Get both URLs dynamically
const responses = await Promise.all(urls.map(url => fetch(url)));
// Check if all responses are OK
for (const response of responses) {
if (!response.ok) {
throw new Error(`Failed to fetch JSON from ${response.url}, Status: ${response.status}`);
}
}
// Convert all responses to JSON
const data = await Promise.all(responses.map(response => response.json()));
// Concatenate the results
const mergedData = Object.assign({}, ...data);
return mergedData;
} catch (error) {
console.error("Error fetching package data:", error);
return null; // Return null to indicate failure
}
}
renderForm(targetSelector) {
const spinnerOverlay = document.createElement('div');
spinnerOverlay.id = "spinnerOverlay";
const spinner = document.createElement('i');
spinner.classList.add('icon-ship');
spinnerOverlay.append(spinner);
const section = document.createElement('section');
section.classList.add('panel', 'panel--white');
const titleParagraph = document.createElement('p');
titleParagraph.textContent = this.title;
const innerDiv = document.createElement('div');
innerDiv.classList.add('inner', 'inner--thin');
const formCont = document.createElement('div');
formCont.id = "ccuk-enquiry";
formCont.classList.add('form');
formCont.appendChild(spinnerOverlay);
const form = document.createElement('form');
form.noValidate = true;
this.form = form;
// If more than one package, create a dropdown for selection
if (Object.keys(this.packageData).length > 1) {
const dropdownRow = document.createElement('div');
dropdownRow.classList.add('row');
const dropdownCol = document.createElement('div');
dropdownCol.classList.add('col-md-12');
const dropdownWrapper = document.createElement('div');
dropdownWrapper.classList.add('form-group');
const dropdownLabel = document.createElement('label');
dropdownLabel.textContent = 'Select Package';
dropdownLabel.setAttribute('for', 'packageDropdown');
const dropdown = document.createElement('select');
dropdown.id = 'packageDropdown';
dropdown.classList.add('form-control', 'custom-select');
Object.keys(this.packageData).forEach(key => {
const option = document.createElement('option');
option.value = key;
option.textContent = this.packageData[key].title;
dropdown.appendChild(option);
});
// dropdown.addEventListener('change', (event) => {
// this.selectedPackageKey = event.target.value;
// //this.updatePackageFields(form, this.packageData[this.selectedPackageKey]);
// });
dropdownWrapper.appendChild(dropdownLabel);
dropdownWrapper.appendChild(dropdown);
dropdownCol.append(dropdownWrapper);
dropdownRow.append(dropdownCol);
form.appendChild(dropdownRow);
} else {
// If only one package, use it directly
this.selectedPackageKey = Object.keys(this.packageData)[0];
}
// Render default fields (e.g., first name, last name)
const defaultFields = this.defaultFields();
this.addFieldsToRow(form, defaultFields, null);
this.addFieldsToRow(form, this.packageFields(this.packageData[this.selectedPackageKey]), "packagefields");
const terms = document.createElement("div");
terms.classList.add("row");
const termsCol = document.createElement("div");
termsCol.classList.add("col-12");
const termslabel = document.createElement("label")
termslabel.classList.add("form-label");
termslabel.innerHTML = 'By proceeding I agree to CruiseClubUK Terms & Conditions and my personal information being handled in accordance with CruiseClubUK Privacy Policy.';
termsCol.append(termslabel);
terms.append(termsCol)
form.appendChild(terms);
// Add Submit button
const buttonRow = document.createElement('div');
buttonRow.classList.add('row', 'mt-3');
const buttonCol = document.createElement('div');
buttonCol.classList.add('col-sm-12', 'col-md-6');
const button = document.createElement('a');
button.href = 'javascript:void();';
button.classList.add('btn', 'btn--sml', 'btn--primary');
button.textContent = 'Send Enquiry';
buttonCol.appendChild(button);
buttonRow.appendChild(buttonCol);
form.appendChild(buttonRow);
formCont.appendChild(form);
innerDiv.appendChild(titleParagraph);
innerDiv.appendChild(formCont);
section.appendChild(innerDiv);
const floatingButton = document.createElement('a');
floatingButton.href = 'javascript:void(0);';
floatingButton.id = 'enquireNowButton';
floatingButton.classList.add('btn', 'btn--sml', 'btn--primary');
floatingButton.textContent = 'ENQUIRE NOW';
let isButtonHidden = false;
floatingButton.addEventListener('click', (event) => {
event.preventDefault();
form.scrollIntoView({ behavior: 'smooth', block: 'start' });
floatingButton.style.display = 'none';
isButtonHidden = true;
});
formCont.addEventListener('focusin', () => {
floatingButton.style.display = 'none';
isButtonHidden = true;
});
formCont.addEventListener('focusout', () => {
if (!document.activeElement.closest('.form')) {
floatingButton.style.display = 'block';
isButtonHidden = false;
}
});
window.addEventListener('scroll', () => {
if (!isButtonHidden) {
floatingButton.style.display = 'block';
}
});
window.addEventListener('wheel', () => {
if (isButtonHidden) {
floatingButton.style.display = 'block';
isButtonHidden = false;
}
});
const targetElement = document.querySelector(targetSelector);
if (targetElement) {
targetElement.insertAdjacentElement('afterend', section);
document.body.append(floatingButton);
} else {
console.warn(`Element with selector "${targetSelector}" not found.`);
}
button.addEventListener('click', (event) => {
event.preventDefault();
if (button.disabled) return;
button.disabled = true;
button.classList.add('disabled-button');
const emailInput = document.getElementById('productEnquiryEmail');
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
const emailValue = emailInput.value;
emailInput.addEventListener('input', function() {
const emailValue = emailInput.value;
if (emailRegex.test(emailValue)) {
// Clear the custom error when the email is valid
emailInput.setCustomValidity('');
} else {
// Optionally, keep the custom error message
emailInput.setCustomValidity('Please enter a valid email address.');
}
});
// Only validate the email format using regex if the email field is valid
if (!emailRegex.test(emailValue)) {
// If the email is invalid, mark it as invalid and trigger the reportValidity() again
emailInput.setCustomValidity('Please enter a valid email address.');
console.warn('Invalid email format.');
form.reportValidity();
button.disabled = false;
button.classList.remove('disabled-button');
return;
}
if (!form.checkValidity()) {
console.warn('Validation failed.');
form.reportValidity();
button.disabled = false;
button.classList.remove('disabled-button');
return;
}
const spinnerOverlay = document.getElementById('spinnerOverlay');
spinnerOverlay.style.display = 'flex';
this.clearMessages();
const formData = this.serializeFormToJson(form);
const maxRetries = 3;
let retries = 0;
const sendRequest = () => {
jQuery.ajax({
url: "https://mycruises.com.au/wp-admin/admin-ajax.php?action=product_enquiry_submit",
method: "POST",
data: formData,
success: (response) => {
button.disabled = false;
this.showSuccessMessage(form);
button.classList.remove('disabled-button');
retries = 0; // Reset retries on success
this.clearNonHiddenFields();
spinnerOverlay.style.display = 'none';
if (typeof fbq === 'function') {
console.log('fb event fired');
fbq('track', 'Lead', {
value: 1.00,
currency: 'GBP'
});
}
},
error: (xhr, status, error) => {
console.error(`Request failed (Attempt ${retries + 1}):`, error, xhr);
if (retries < maxRetries) {
retries++; // Increment retry count
console.log(`Retrying... Attempt ${retries}`);
setTimeout(sendRequest, 2000); // Retry after a short delay
} else {
console.error("Max retry attempts reached. Form submission failed.");
button.disabled = false;
const errorMessage = xhr.responseText || "An error occurred while submitting the form. Please try again.";
this.showErrorMessage(form, errorMessage);
button.classList.remove('disabled-button');
spinnerOverlay.style.display = 'none';
}
}
});
}
// Call the sendRequest function initially
sendRequest();
});
}
isValidDate(dateString) {
const date = new Date(dateString);
return !isNaN(date.getTime());
}
createSuccessMessage() {
let successMessage = document.getElementById('successMessage');
// If success message already exists, update the first name and return
if (successMessage) {
const messageText = successMessage.querySelector('.success-text');
if (messageText) {
messageText.textContent = `Thank you, ${this.form.productEnquiryFirstName.value}! We've received your enquiry and are working on your perfect cruise journey. We'll be in touch soon.`;
}
successMessage.style.display = 'block';
return successMessage;
}
// Create new success message
successMessage = document.createElement('div');
successMessage.id = 'successMessage';
successMessage.classList.add('alert', 'alert-success', 'position-relative');
successMessage.role = 'alert';
// Create close button
const closeButton = document.createElement('button');
closeButton.type = 'button';
closeButton.classList.add('close', 'position-absolute', 'top-0', 'end-0', 'm-2');
closeButton.setAttribute('aria-label', 'Close');
closeButton.addEventListener('click', this.closeSuccessMessage);
const closeSpan = document.createElement('span');
closeSpan.setAttribute('aria-hidden', 'true');
closeSpan.innerHTML = '×';
closeButton.appendChild(closeSpan);
// Add the success message content
const messageText = document.createElement('span');
messageText.classList.add('success-text');
messageText.textContent = `Thank you, ${this.form.productEnquiryFirstName.value}! We've received your enquiry and are working on your perfect cruise journey. We'll be in touch soon.`;
// Append elements
successMessage.appendChild(closeButton);
successMessage.appendChild(messageText);
return successMessage;
}
showSuccessMessage(form) {
const successMessage = this.createSuccessMessage();
form.append(successMessage);
successMessage.style.display = 'block';
}
closeSuccessMessage() {
const successMessage = document.getElementById('successMessage');
if (successMessage) {
successMessage.style.display = 'none';
}
}
createErrorMessage(errorText) {
let errorMessage = document.getElementById('errorMessage');
// If error message already exists, update the text and return
if (errorMessage) {
const messageText = errorMessage.querySelector('.error-text');
if (messageText) {
messageText.textContent = errorText;
}
errorMessage.style.display = 'block';
return errorMessage;
}
// Create new error message
errorMessage = document.createElement('div');
errorMessage.id = 'errorMessage';
errorMessage.classList.add('alert', 'alert-danger', 'position-relative');
errorMessage.role = 'alert';
// Create close button
const closeButton = document.createElement('button');
closeButton.type = 'button';
closeButton.classList.add('close', 'position-absolute', 'top-0', 'end-0', 'm-2');
closeButton.setAttribute('aria-label', 'Close');
closeButton.addEventListener('click', this.closeErrorMessage);
const closeSpan = document.createElement('span');
closeSpan.setAttribute('aria-hidden', 'true');
closeSpan.innerHTML = '×';
closeButton.appendChild(closeSpan);
// Add the error message content
const messageText = document.createElement('span');
messageText.classList.add('error-text');
messageText.textContent = errorText;
// Append elements
errorMessage.appendChild(closeButton);
errorMessage.appendChild(messageText);
return errorMessage;
}
showErrorMessage(form, errorText) {
const errorMessage = this.createErrorMessage(errorText);
form.append(errorMessage);
errorMessage.style.display = 'block';
}
closeErrorMessage() {
const errorMessage = document.getElementById('errorMessage');
if (errorMessage) {
errorMessage.style.display = 'none';
}
}
clearMessages() {
this.closeSuccessMessage();
this.closeErrorMessage();
}
// Helper function to group fields into rows
addFieldsToRow(form, fields, clsName) {
let row;
// Filter out hidden fields
const visibleFields = fields.filter(field => field.type !== 'hidden');
visibleFields.forEach((field, index) => {
const isFullRow = field.isFullRow; // Check if the field is marked as full row
// Start a new row for every fieldsPerRow fields or if it's a full-row field
if (isFullRow || (index % this.fieldsPerRow === 0 && !isFullRow)) {
row = document.createElement('div');
if (clsName !== null && clsName !== '') {
row.classList.add('row', clsName);
} else {
row.classList.add('row');
}
}
// Create a column
const col = document.createElement('div');
if (isFullRow) {
// Full-row field (col-12 to take up the entire row)
col.classList.add('col-12');
// Full-row fields start a new row
row = document.createElement('div');
if (clsName !== null && clsName !== '') {
row.classList.add('row', clsName);
} else {
row.classList.add('row');
}
row.appendChild(col);
} else {
// Default field column (for fields that should be in a multi-column row)
const colWidth = 12 / this.fieldsPerRow;
col.classList.add(`col-md-${colWidth}`);
row.appendChild(col);
}
// Create the field and append it to the column
col.appendChild(this.createField(field));
// If the row has child elements, append it to the form
if (row.children.length > 0) {
form.appendChild(row);
}
});
fields
.filter(field => field.type === 'hidden')
.forEach(hiddenField => {
const inputElement = this.createField(hiddenField);
form.appendChild(inputElement);
});
}
getQueryParam(param) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(param);
}
// Default fields (user information)
defaultFields() {
var utm_source = this.getQueryParam("utm_source");
var utm_campaign = this.getQueryParam("utm_campaign")
var utm_medium = this.getQueryParam("utm_medium")
var utm_content = this.getQueryParam("utm_content")
var utm_term = this.getQueryParam("utm_term")
return [
{ label: 'First Name', id: 'productEnquiryFirstName', placeholder: 'Enter your first name', type: 'text', required: true },
{ label: 'Last Name', id: 'productEnquiryLastName', placeholder: 'Enter your last name', type: 'text', required: true },
{ label: 'Email', id: 'productEnquiryEmail', placeholder: 'Enter your email', type: 'email', required: true },
{
label: 'Mobile',
id: 'productEnquiryPhoneNumber',
placeholder: 'Enter your mobile number',
type: 'tel',
pattern: '^(?:\\+44\\s?7\\d{9}|07\\d{9})$', // Allow optional country code
title: 'Enter a valid UK phone number starting with +44 or 07',
required: true
},
{ label: 'Adults', id: 'productEnquiryAdults', placeholder: 'Enter the number of adults', type: 'number', min: 1, value: 1, required: true },
{ label: 'Children and Infants', id: 'productEnquiryChildren', placeholder: 'Enter the number of children', type: 'number', min: 0, value: 0, required: true },
{ label: 'UtmSource', id: 'utm_source', value: utm_source, type: 'hidden',readonly: true },
{ label: 'UtmCampaign', id: 'utm_campaign', value: utm_campaign, type: 'hidden',readonly: true },
{ label: 'UtmMedium', id: 'utm_medium', value: utm_medium, type: 'hidden',readonly: true },
{ label: 'UtmContent', id: 'utm_content', value: utm_content, type: 'hidden',readonly: true },
{ label: 'UtmTerm', id: 'utm_term', value: utm_term, type: 'hidden',readonly: true },
];
}
// Package-specific fields
packageFields(packageDetails) {
let departureDateField;
if (Array.isArray(packageDetails.departure_date)) {
// If it's an array, create a select input with options
departureDateField = {
label: 'Preferred Departure Date',
id: 'productEnquiryDepartureDate',
type: 'select',
options: packageDetails.departure_date,
required: true
};
} else {
// If it's a string, create a date input field
departureDateField = {
label: 'Preferred Departure Date',
id: 'productEnquiryDepartureDate',
type: 'hidden',
value: this.formatDate(packageDetails.departure_date, 'iso'),
required: true,
readonly: true
};
}
let departurePointField;
if (Array.isArray(packageDetails.departure_point)) {
// If departure_point is an array, create a select input with options
departurePointField = {
label: 'Departure Point',
id: 'productEnquiryDeparturePoint',
type: 'select',
options: packageDetails.departure_point, // Array of departure points
required: true
};
} else {
// If departure_point is a single value, create a text input field
departurePointField = {
label: 'Departure Point',
id: 'productEnquiryDeparturePoint',
value: packageDetails.departure_point, // Single value
type: 'text',
required: true,
readonly: true
};
}
return [
departurePointField,
departureDateField,
{ label: 'Cabin Type', id: 'productEnquiryRoomType', type: 'select', options: packageDetails.cabin_type, required: true , isFullRow: true},
{ label: 'Special Requests', id: 'productEnquiryNotes', type: 'textarea',
placeholder: 'You may want to let us know of any accessibility requests, any special occasion you are travelling for, frequent flyer numbers and anything else to make your holiday perfect.',
isFullRow: true },
{ label: 'I agree to receive emails about our latest travel packages, promotions, and updates.', id: 'productOptin', type: 'checkbox',
isFullRow: true, value:"0" },
{ label: 'Package', id: 'productEnquiryProductName', value: packageDetails.title, type: 'hidden',readonly: true },
{ label: 'No of Nights', id: 'productEnquiryNights', value: packageDetails.nights, type: 'hidden',readonly: true },
{ label: 'Advertised Price', id: 'productEnquiryPrice', value: packageDetails.price, type: 'hidden',readonly: true },
{ label: 'Action', id: 'action', value: 'product_enquiry_submit', type: 'hidden',readonly: true },
{ label: 'Url', id: 'productEnquiryProductUrl', value: this.getCurrentUrl(), type: 'hidden',readonly: true },
{ label: 'Deal Code', id: 'productCode', value: this.selectedPackageKey, type: 'hidden',readonly: true },
{ label: 'Cruise Ship', id: 'productEnquiryCruiseShip', value: packageDetails.ship, type: 'hidden',readonly: true },
{ label: 'Identity', id: 'identity', value: 'a3825f1758294128a41cc88c39cc10e7', type: 'hidden',readonly: true },
];
}
// Create a form field element dynamically
createField(field) {
const fieldWrapper = document.createElement('div');
let inputElement;
if (field.type === 'checkbox') {
fieldWrapper.classList.add('form-check');
inputElement = document.createElement('input');
inputElement.type = 'checkbox';
inputElement.id = field.id;
inputElement.name = field.name || field.id;
inputElement.classList.add('form-check-input');
inputElement.checked = field.checked || false;
if (field.readonly) inputElement.setAttribute('readonly', 'true');
if (field.required) inputElement.setAttribute('required', 'true');
fieldWrapper.appendChild(inputElement);
const label = document.createElement('label');
label.classList.add('form-check-label');
label.innerHTML = field.label;
label.setAttribute('for', field.id);
fieldWrapper.appendChild(label);
} else {
fieldWrapper.classList.add('form-group');
if (field.type !== 'hidden') {
const label = document.createElement('label');
label.textContent = field.label;
label.setAttribute('for', field.id);
fieldWrapper.appendChild(label);
}
if (field.type === 'textarea') {
inputElement = document.createElement('textarea');
inputElement.cols = field.cols || 40;
inputElement.rows = field.rows || 6;
} else if (field.type === 'select') {
inputElement = document.createElement('select');
inputElement.classList.add('custom-select');
field.options.forEach(option => {
const opt = document.createElement('option');
if (this.isValidDate(option)) {
opt.value = this.formatDate(option, 'iso');
opt.textContent = this.formatDate(option, 'uk');
} else {
opt.value = option;
opt.textContent = option;
}
inputElement.appendChild(opt);
});
} else {
inputElement = document.createElement('input');
inputElement.type = field.type || 'text';
}
inputElement.id = field.id;
inputElement.name = field.name || field.id;
inputElement.placeholder = field.placeholder || '';
inputElement.value = field.value !== undefined ? field.value : inputElement.value;
if (field.readonly) inputElement.setAttribute('readonly', 'true');
if (field.required) inputElement.setAttribute('required', 'true');
// Add validation attributes
if (field.min !== undefined && field.min !== null) {
inputElement.setAttribute('min', field.min);
}
if (field.max !== undefined && field.max !== null) {
inputElement.setAttribute('max', field.max);
}
if (field.pattern) inputElement.setAttribute('pattern', field.pattern);
if (field.title) inputElement.setAttribute('title', field.title);
// Add the input element directly for hidden fields
if (field.type === 'hidden') {
fieldWrapper.classList.add('d-none'); // Optional: Hide wrapper for hidden fields
}
fieldWrapper.appendChild(inputElement);
}
return fieldWrapper;
}
// Serialize form data to JSON
serializeFormToJson(form) {
const formData = new FormData(form);
const json = {};
const checkboxes = form.querySelectorAll('input[type="checkbox"]');
checkboxes.forEach(checkbox => {
const name = checkbox.name;
if (!checkbox.checked) {
json[name] = 0;
} else {
json[name] = 1;
}
});
formData.forEach((value, key) => {
if (!(key in json)) {
json[key] = value.trim();
}
});
return json;
}
clearNonHiddenFields() {
let fields = [...this.defaultFields(), ...this.packageFields(this.packageData[this.selectedPackageKey])];
fields.forEach(field => {
const element = document.getElementById(field.id);
if (element) {
if (field.type === 'hidden' || field.readonly) {
return;
}
if (field.type === 'checkbox') {
element.checked = false;
}
else if (field.type !== 'select' && field.value !== undefined && field.value !== null ) {
element.value = field.value;
}
else if (field.type === 'select') {
jQuery(element).val(jQuery(element).find('option:first').val()).trigger('change');
}
else {
element.value = '';
}
}
});
}
}
jQuery(document).ready(function() {
const textToRemove = ["REFERENCE", ":"];
const packageReferences = jQuery('.cruiseid')
.map(function() {
let text = jQuery(this).text().trim().toLowerCase();
textToRemove.forEach(str => {
text = text.toLowerCase().replace(str.toLowerCase(), '').trim();
});
return text;
})
.get();
// Initialize and render the component
const enquiryComponent = new EnquiryComponent(packageReferences);
enquiryComponent.init("#book");
});
function injectStyles() {
const styles = `
input[type="number"],input[type="date"] {
height: 50px;
line-height: 50px;
border: 1px solid #E8E8E8;
font-size: 1.6rem;
padding-left: 1rem;
display: block;
width: 100%;
color: #161616;
background: #fff;
font-weight: 300;
font-family: "Open Sans", sans-serif;
}
@media (min-width: 1024px) {
form {
padding: 2rem;
}
}
.form {
border-radius: 3px;
}
.form textarea{
padding: 6px;
border-radius: 3px;
}
.form input,select {
border-radius: 3px;
}
.select2-container {
border-radius: 3px;
}
.select2-dropdown {
border-radius: 3px;
}
.select2-search__field {
border-radius: 3px;
}
.select2-selection {
border-radius: 3px;
}
.form input[type="number"] {
padding-right: 0;
}
.form .select2-container--default .select2-selection--single .select2-selection__rendered {
color: #161616 !important;
}
.fade-in {
animation: fadeIn 1s ease-in-out;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.form {
position: relative;
}
.form .alert-success {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
padding: 15px 25px 15px 15px;
margin-top: 15px;
border-radius: 5px;
position: relative;
display: none;
font-size: 16px;
font-weight: 500;
line-height: 1.4em;
}
.form .alert-danger {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
padding: 15px 25px 15px 15px;
margin-top: 15px;
border-radius: 5px;
position: relative;
display: none;
font-size: 16px;
font-weight: 500;
line-height: 1.4em;
}
.form .alert-success .close,
.form .alert-danger .close {
background: transparent;
border: none;
font-size: 20px;
font-weight: bold;
color: inherit;
cursor: pointer;
position: absolute;
top: 10px;
right: 15px;
}
.form .alert-success .close:hover,
.form .alert-danger .close:hover {
opacity: 0.7;
text-decoration: none;
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.3);
}
.form .alert-success:hover {
box-shadow: 0px 4px 8px rgba(0, 128, 0, 0.2);
border-color: #28a745;
}
.form .alert-danger:hover {
box-shadow: 0px 4px 8px rgba(255, 0, 0, 0.2);
border-color: #d9534f;
}
.form .disabled-button {
pointer-events: none; /* Prevent clicks */
opacity: 0.6; /* Make it visually disabled */
cursor: not-allowed;
}
#enquireNowButton {
position: fixed;
bottom: 20px; /* Distance from the bottom of the screen */
left: 50%;
transform: translateX(-50%);
font-size: 16px;
z-index: 1000;
display: inline-block;
text-align: center;
background-color: #007bff;
color: white;
border-radius: 30px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
transition: background-color 0.3s ease, box-shadow 0.3s ease;
cursor: pointer;
}
#enquireNowButton:hover {
background-color: #0056b3; /* Darker shade on hover */
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
}
#enquireNowButton:active {
background-color: #003f75; /* Even darker shade when pressed */
}
.form-check {
display: block;
min-height: 1.5rem;
margin-bottom: 0.5rem;
position: relative;
}
.form-check-input {
width: 1.5rem;
height: 1.5rem;
margin-top: 0.25rem;
vertical-align: top;
background-color: white;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
border: 1px solid #adb5bd;
appearance: none; /* Remove default browser styling */
cursor: pointer;
transition: all 0.2s ease-in-out;
}
.form-check-input:checked {
background-color: #0d6efd; /* Bootstrap primary color */
border-color: #0d6efd;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23fff' d='M10.97 4.97a.75.75 0 011.07 1.05l-4 4a.75.75 0 01-1.07 0l-2-2a.75.75 0 111.07-1.05l1.47 1.47 3.47-3.47z'/%3E%3C/svg%3E");
}
.form-check-input:indeterminate {
background-color: #0d6efd;
border-color: #0d6efd;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23fff' d='M3 7.5h10v1H3v-1z'/%3E%3C/svg%3E");
}
.form-check-input:disabled {
pointer-events: none;
opacity: 0.5;
}
.form-check-input:disabled ~ .form-check-label {
opacity: 0.5;
cursor: not-allowed;
}
.form-check-input:focus {
border-color: #80bdff;
outline: 0;
box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
}
.form-check-label {
color: #212529;
cursor: pointer;
line-height: 30px;
}
.form-check-label a {
text-decoration: underline;
}
.form-label a {
text-decoration: underline;
}
.form-label {
line-height: 20px;
margin-bottom: 40px;
}
#productOptin {
display: inline;
width: 22px;
height: 22px;
float: left
}
#spinnerOverlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.2);
display: none;
justify-content: center;
align-items: center;
z-index: 100;
border-radius: 5px;
}
#spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
}
.icon-ship {
background-size: contain;
animation: sail 4s linear infinite, rock 2s ease-in-out infinite;
filter: invert(100%) sepia(100%) saturate(100%) hue-rotate(0deg);
}
@keyframes sail {
0% {
transform: translateX(-100%) rotate(0deg); /* Start off-screen to the left */
}
50% {
transform: translateX(50vw) rotate(10deg); /* Move to the center, slightly rotated */
}
100% {
transform: translateX(100%) rotate(0deg); /* Move off-screen to the right */
}
}
@keyframes rock {
0% {
transform: rotate(0deg); /* No rotation at the start */
}
50% {
transform: rotate(5deg); /* Rock slightly to the right */
}
100% {
transform: rotate(-5deg); /* Rock slightly to the left */
}
}
}
`;
const styleSheet = document.createElement("style");
styleSheet.type = "text/css";
styleSheet.innerText = styles;
document.head.appendChild(styleSheet);
}
// Call the function to inject the styles
injectStyles();