plugin and theme sync

This commit is contained in:
2024-03-25 02:27:05 -04:00
parent c3179e074e
commit 7d46673042
13 changed files with 358 additions and 147 deletions

View File

@@ -1,6 +1,15 @@
class AppointmentForm {
constructor(vehicle) {
this.vehicle = vehicle;
this.inputs = [
'name',
'email',
'phone',
'preferred-contact',
'message',
'agreeToOffersCheckbox',
'privacyPolicyCheckbox',
];
this.initForm();
this.modalDiv = null;
this.name = 'appointmentForm';
@@ -21,6 +30,7 @@ class AppointmentForm {
},
];
let checkboxes = ``;
const vehicleInput = `<input type="hidden" name="vehicle" id="vehicle" value='${JSON.stringify(this.vehicle)}'>`;
inputIds.forEach((input) => {
checkboxes += `
<div class=" mdc-form-field flex flex-row flex-nowrap w-full my-2 lg:my-0 ${input.name} hover:text-red-500">
@@ -38,38 +48,41 @@ class AppointmentForm {
</div>`;
});
this.modalDiv.innerHTML = `
<form class="p-4 md:p-5">
<div class="grid gap-4 grid-cols-2">
<div class="col-span-2">
<label for="name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Name</label>
<input type="text" name="name" id="name" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="Jane Doe" required="">
</div>
<div class="col-span-2">
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Email</label>
<input type="email" name="email" id="email" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="jane@gmail.com" required="">
</div>
<div class="col-span-2 ">
<label for="phone" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Phone</label>
<input type="tel" name="phone" id="phone" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="(123) 456-7890" required="">
</div>
<div class="col-span-2 ">
<label for="preferred-contact" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Preferred Contact Method</label>
<select id="preferred-contact" name="preferred-contact" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500">
<option selected="">---</option>
<option value="Call">Call</option>
<option value="Email">Email</option>
<option value="Text">Text</option>
</select>
</div>
<div class="col-span-2">
<label for="message" name="message" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Product Description</label>
<textarea id="message" rows="4" class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="I am interested in..."></textarea>
</div>
</div>
${checkboxes}
<button class="w-full bg-gray-500 hover:bg-gray-800 text-white p-2 rounded-md transition duration-300" id="send-button">Send</button>
<form class="p-4 md:p-5" id="appointmentForm">
<div class="grid gap-4 grid-cols-2">
<div class="col-span-2">
<label for="name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Name</label>
<input type="text" name="name" id="name" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="Jane Doe" required>
<div id="nameError" class="text-red-500 hidden">Please enter your name.</div>
</div>
<div class="col-span-2">
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Email</label>
<input type="email" name="email" id="email" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="jane@gmail.com" required>
<div id="emailError" class="text-red-500 hidden">Please enter a valid email address.</div>
</div>
<div class="col-span-2 ">
<label for="phone" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Phone</label>
<input type="tel" name="phone" id="phone" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="(123) 456-7890" required>
<div id="phoneError" class="text-red-500 hidden">Please enter a valid phone number.</div>
</div>
<div class="col-span-2 ">
<label for="preferred-contact" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Preferred Contact Method</label>
<select id="preferred-contact" name="preferred-contact" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500">
<option selected disabled>---</option>
<option value="Call">Call</option>
<option value="Email" selected>Email</option>
<option value="Text">Text</option>
</select>
<div id="preferredContactError" class="text-red-500 hidden">Please select a preferred contact method.</div>
</div>
<div class="col-span-2">
<label for="message" name="message" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Product Description</label>
<textarea id="message" rows="4" class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="I am interested in..."></textarea>
</div>
</div>
${vehicleInput}
${checkboxes}
<button class="w-full bg-gray-500 hover:bg-gray-800 text-white p-2 rounded-md transition duration-300 finance-view-only" id="send-button">Send</button>
</form>
`;
@@ -104,27 +117,56 @@ class AppointmentForm {
return this.modalDiv;
}
initializeFormEventListeners(modalDiv) {
const formInputs = [
'name',
'email',
'phone',
'preferred-contact',
'message',
'agreeToOffersCheckbox',
'privacyPolicyCheckbox',
];
formInputs.forEach((id) => {
const inputElement = modalDiv.querySelector(`#${id}`);
if (inputElement) {
inputElement.addEventListener('input', () => {
this.saveFormValues(); // Save form values whenever an input changes
});
}
let self = this;
self.inputs.forEach(id => {
const inputElement = modalDiv.querySelector(`#${id}`);
if (inputElement) {
inputElement.addEventListener('input', () => {
self.saveFormValues(); // Save form values whenever an input changes
});
}
});
}
const sendButton = modalDiv.querySelector('#send-button');
if (sendButton) {
sendButton.addEventListener('click', function(e) {
e.preventDefault();
if (self.validateForm()) {
console.log('Form submitted successfully');
}else{
return
}
const formData = {};
[...['loanTerm', 'intRate', 'downPayment', 'tradeValue', 'paymentFrequency', 'rate', 'customRateValue'],...self.inputs].forEach(inputID => {
const inputElement = document.getElementById(inputID);
if (inputElement) {
formData[inputID] = postDetails.hasOwnProperty(inputID) ? postDetails[inputID] : null;
}
});
// AJAX request
jQuery.ajax({
type: 'POST',
url: ajax_object.ajax_url,
data: {
action: 'send_appointment_data',
appointment_data: formData,
nonce: ajax_object.appointment_nonce
},
success: function(response) {
alert('Appointment data sent successfully!');
},
error: function(xhr, status, error) {
console.error(xhr.responseText);
}
});
});
}
}
initializeFormInputs() {
const storedValues =
@@ -133,7 +175,7 @@ class AppointmentForm {
const inputElement = document.getElementById(key);
if (inputElement) {
inputElement.value = storedValues[key];
inputElement.dispatchEvent(new Event('input')); // Dispatch input event
inputElement.dispatchEvent(new Event('input'));
}
}
}
@@ -142,13 +184,11 @@ class AppointmentForm {
this.checkboxes = modalDiv.querySelectorAll('.mdc-checkbox');
if (this.checkboxes) {
this.checkboxes.forEach((checkbox, index) => {
// Initialize the MDCCheckbox with the actual checkbox element
const checkboxElement = checkbox.querySelector(
`.mdc-checkbox__native-control.${inputIds[index].name}`
);
const checkboxInstance = new mdc.checkbox.MDCCheckbox(checkbox);
// If the checkbox is found, initialize the form field as well
if (checkboxElement) {
const formFieldInstance = new mdc.formField.MDCFormField(
modalDiv.querySelector(`.mdc-form-field.${inputIds[index].name}`)
@@ -164,18 +204,10 @@ class AppointmentForm {
}
saveFormValues() {
const formInputs = [
'name',
'email',
'phone',
'preferred-contact',
'message',
'agreeToOffersCheckbox',
'privacyPolicyCheckbox',
];
const formValues = {};
formInputs.forEach((input) => {
this.inputs.forEach((input) => {
const inputElement = document.getElementById(input);
if (inputElement) {
formValues[input] = inputElement.value;
@@ -184,5 +216,22 @@ class AppointmentForm {
localStorage.setItem(`autocart_${this.name}`, JSON.stringify(formValues));
}
validateForm() {
let isValid = true;
this.inputs.forEach((id) => {
const inputElement = document.getElementById(id);
const errorElement = document.getElementById(`${id}Error`);
if (inputElement && !inputElement.checkValidity()) {
isValid = false;
errorElement.classList.remove('hidden');
} else {
errorElement.classList.add('hidden');
}
});
return isValid;
}
}

View File

@@ -1,9 +1,18 @@
class FinanceForm {
constructor(vehicle, notifyParentCallback) {
constructor(vehicle,appointmentForm, notifyParentCallback) {
this.notifyParentCallback = notifyParentCallback;
this.inputs = [
'loanTerm',
'intRate',
'downPayment',
'tradeValue',
'paymentFrequency',
'rate',
'customRateValue',
];
this.modalDiv = null;
this.name = 'financeForm';
this.appointmentForm = appointmentForm;
this.frequencyMap = {
12: 'Monthly',
26: 'Bi-Weekly',
@@ -62,12 +71,37 @@ class FinanceForm {
// Initialize the form
this.initForm();
// this.initializeFormInputs();
this.initializeFormInputs();
}
generateLoanTermOptions(vehicleAge) {
const defaultOptions = [
{ year: 2, terms: [12, 24, 36, 48, 60, 72, 84, 96] },
{ year: 5, terms: [12, 24, 36, 48, 60, 72, 84] },
{ year: 7, terms: [12, 24, 36, 48, 60, 72] },
{ year: 8, terms: [12, 24, 36, 48, 60] },
{ year: 10, terms: [12, 24, 36, 48] }
];
const selectedOptions = defaultOptions.find(option => vehicleAge <= option.year);
if (selectedOptions) {
const optionsHTML = selectedOptions.terms.map(term => `<option value="${term}">${term} Month Term</option>`).join('\n');
return optionsHTML;
} else {
return '';
}
}
initForm() {
// console.log('initForm')
this.modalDiv = document.createElement('div');
const currentYear = new Date().getFullYear();
const vehicleYear = this.vehicle.year;
const vehicleAge = currentYear - vehicleYear;
const loanTermOptions = this.generateLoanTermOptions(vehicleAge);
// const modalDiv = document.createElement('div');
this.modalDiv.innerHTML = `
<div class="bg-white rounded-md grid lg:grid-cols-6 gap-4">
@@ -90,8 +124,8 @@ class FinanceForm {
<div class="tab-content" data-content="tab1">
<h4 class="text-xl mb-2">Lets Structure a Deal That Works For You</h4>
<p class="mb-4">
<h4 class="text-xl mb-2 finance-view-only">Lets Structure a Deal That Works For You</h4>
<p class="mb-4 finance-view-only">
We understand that purchasing a vehicle is a big decision, so we want you to be paying a price that youre comfortable with.
<strong>Lets structure a deal that works for you below:</strong>
</p>
@@ -128,13 +162,7 @@ class FinanceForm {
<div>
<label for="loanTerm" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Loan Term</label>
<select name="loanTerm" id="loanTerm" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-600 dark:border-gray-500 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" required="">
<option value="12" selected>12 Month Term</option>
<option value="24">24 Month Term</option>
<option value="36">36 Month Term</option>
<option value="48">48 Month Term</option>
<option value="60">60 Month Term</option>
<option value="72">72 Month Term</option>
<option value="84">84 Month Term</option>
${loanTermOptions}
</select>
</div>
<div>
@@ -169,9 +197,9 @@ class FinanceForm {
</div>
<div class="tab-content hidden" data-content="tab2">
<h4 class="text-xl mb-2">Lets Structure a Deal That Works For You</h4>
<h4 class="text-xl mb-2 finance-view-only">Lets Structure a Deal That Works For You</h4>
<p class="mb-4">
<p class="mb-4 finance-view-only">
We understand that purchasing a vehicle is a big decision, so we want you to be paying a price that youre comfortable with.
<strong>Lets structure a deal that works for you below:</strong>
</p>
@@ -257,22 +285,23 @@ class FinanceForm {
</span>
</p>
</div>
<button class="w-full bg-gray-500 hover:bg-gray-800 text-white p-2 rounded-md transition duration-300" id="next-step">next step</button>
<button class="w-full bg-gray-500 hover:bg-gray-800 text-white p-2 rounded-md transition duration-300" id="next-step">Next Step</button>
</div>
</div>
</div>
</div>
`;
const formContainer = this.modalDiv.querySelector(
'#appointmentFormContainer'
);
formContainer.appendChild(appointmentForm.initForm());
this.initializeTabNavigation(this.modalDiv);
this.initializeFormEventListeners(this.modalDiv);
return this.modalDiv;
}
const formContainer = this.modalDiv.querySelector(
'#appointmentFormContainer'
);
formContainer.appendChild(this.appointmentForm.initForm());
this.initializeTabNavigation(this.modalDiv);
this.initializeFormEventListeners(this.modalDiv);
return this.modalDiv;
}
// initializeFormInputs() {
// const storedValues = JSON.parse(localStorage.getItem(`autocart_${this.name}`)) || {};
@@ -290,24 +319,33 @@ class FinanceForm {
// }
initializeFormInputs() {
const storedValues =
JSON.parse(localStorage.getItem(`autocart_${this.name}`)) || {};
const storedValues = JSON.parse(localStorage.getItem(`autocart_${this.name}`)) || {};
const selectElements = document.querySelectorAll('select');
for (const key in storedValues) {
const inputElement = document.getElementById(key);
if (inputElement) {
inputElement.value = storedValues[key];
inputElement.dispatchEvent(new Event('input')); // Dispatch input event
}
const inputElement = document.getElementById(key);
if (inputElement) {
inputElement.value = storedValues[key];
if (inputElement.tagName.toLowerCase() === 'select') {
const optionValues = Array.from(inputElement.options).map(option => option.value);
const selectedValue = storedValues[key];
if (!optionValues.includes(selectedValue)) {
const closestValue = optionValues.reduce((a, b) => Math.abs(b - selectedValue) < Math.abs(a - selectedValue) ? b : a);
inputElement.value = closestValue;
}
}
inputElement.dispatchEvent(new Event('input'));
}
}
this.updateView();
}
}
calculatePayments() {
var vehiclePrice = this.vehicle.advertise_price;
this.loanTerm = document.getElementById('loanTerm').value;
this.paymentFrequency = document.getElementById('paymentFrequency').value;
this.intRate =
document.getElementById('rate').value == 'default-rate'
this.intRate = document.getElementById('rate').value == 'default-rate'
? 7.99
: document.getElementById('customRateValue').value;
this.downPayment = document.getElementById('downPayment').value;
@@ -347,11 +385,14 @@ class FinanceForm {
updateView() {
['default-rate', 'custom-rate'].forEach((el) => {
document.getElementById(el).classList.add('hidden');
document.getElementById(el)?.classList?.add('hidden');
});
document
if(document.getElementById('rate')){
document
.getElementById(document.getElementById('rate').value)
.classList.remove('hidden');
}
if (document.querySelectorAll('.loanTermSpan').length) {
document.querySelectorAll('.loanTermSpan').forEach((el) => {
@@ -448,17 +489,9 @@ class FinanceForm {
}
initializeFormEventListeners(modalDiv) {
const formInputs = [
'loanTerm',
'intRate',
'downPayment',
'tradeValue',
'paymentFrequency',
'rate',
'customRateValue',
];
formInputs.forEach((id) => {
this.inputs.forEach((id) => {
const inputElement = modalDiv.querySelector(`#${id}`);
if (inputElement) {
inputElement.addEventListener('input', () => {
@@ -470,18 +503,10 @@ class FinanceForm {
}
saveFormValues() {
const formInputs = [
'loanTerm',
'intRate',
'downPayment',
'tradeValue',
'paymentFrequency',
'rate',
'customRateValue',
];
const formValues = {};
formInputs.forEach((input) => {
this.inputs.forEach((input) => {
const inputElement = document.getElementById(input);
if (inputElement) {
formValues[input] = inputElement.value;

View File

@@ -93,6 +93,6 @@ class Modal {
}
}
document.addEventListener('DOMContentLoaded', function () {
console.log('modal is here');
});