forked from alaguraj/odoo-testing-addons
add order fulfillment type selection and optimize checkout UI, and update docker container naming conventions
This commit is contained in:
parent
467181c4af
commit
ed6e69e191
@ -84,11 +84,6 @@
|
|||||||
|
|
||||||
<input type="hidden" name="fulfilment_type" id="hidden_fulfilment_type" value="delivery"/>
|
<input type="hidden" name="fulfilment_type" id="hidden_fulfilment_type" value="delivery"/>
|
||||||
|
|
||||||
<div class="section-header"><i class="fa fa-clock-o me-2"></i>Preferred Greeting / Timing</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<input type="datetime-local" name="delivery_time" id="delivery_time_input" class="form-control form-control-lg border-0 bg-light" required="required"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="uber_message" class="alert d-none my-3" role="alert"></div>
|
<div id="uber_message" class="alert d-none my-3" role="alert"></div>
|
||||||
<div id="contact_info_header" class="section-header mt-4"><i class="fa fa-user me-2"></i>Contact Details</div>
|
<div id="contact_info_header" class="section-header mt-4"><i class="fa fa-user me-2"></i>Contact Details</div>
|
||||||
</xpath>
|
</xpath>
|
||||||
@ -106,8 +101,105 @@
|
|||||||
function initUnifiedForm() {
|
function initUnifiedForm() {
|
||||||
const hiddenType = document.getElementById('hidden_fulfilment_type');
|
const hiddenType = document.getElementById('hidden_fulfilment_type');
|
||||||
const msgDiv = document.getElementById('uber_message');
|
const msgDiv = document.getElementById('uber_message');
|
||||||
const submitBtn = document.querySelector('button[type="submit"]') || document.querySelector('.btn-primary');
|
const submitBtn = document.querySelector('button[type="submit"]') || document.querySelector('.btn-primary') || document.querySelector('.s_website_form_send');
|
||||||
let debounceTimer;
|
let debounceTimer;
|
||||||
|
|
||||||
|
// Force Name, Email, and Phone to be required
|
||||||
|
['name', 'email', 'phone'].forEach(fieldName => {
|
||||||
|
const input = document.querySelector(`form.checkout_autoformat [name="${fieldName}"]`);
|
||||||
|
if (input) input.setAttribute('required', 'required');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 1. Add prominent red required icons to labels
|
||||||
|
document.querySelectorAll('form.checkout_autoformat .control-label, form.checkout_autoformat label').forEach(label => {
|
||||||
|
const inputId = label.getAttribute('for');
|
||||||
|
const input = inputId ? document.getElementById(inputId) : label.closest('.mb-3')?.querySelector('input, select');
|
||||||
|
if (input && input.hasAttribute('required') && !label.querySelector('.fa-asterisk')) {
|
||||||
|
label.innerHTML += ' <i class="fa fa-asterisk text-danger" style="font-size: 7px; vertical-align: top; margin-left: 2px;"></i>';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. Clear error state on input change (Real-time update)
|
||||||
|
document.querySelectorAll('form.checkout_autoformat input, form.checkout_autoformat select').forEach(input => {
|
||||||
|
const handler = function() {
|
||||||
|
const val = this.value ? this.value.trim() : "";
|
||||||
|
// Check if the field is actually filled (0 is valid for select if it's not the placeholder)
|
||||||
|
const isFilled = val && val !== "0" && val !== "";
|
||||||
|
|
||||||
|
if (isFilled) {
|
||||||
|
this.classList.remove('is-invalid');
|
||||||
|
this.style.borderColor = '';
|
||||||
|
|
||||||
|
// Update the summary error list dynamically
|
||||||
|
const form = this.closest('form');
|
||||||
|
const errorDiv = document.getElementById('chennora_val_error');
|
||||||
|
if (errorDiv) {
|
||||||
|
const stillInvalid = form.querySelectorAll('.is-invalid');
|
||||||
|
if (stillInvalid.length === 0) {
|
||||||
|
errorDiv.style.display = 'none';
|
||||||
|
} else {
|
||||||
|
let missingNames = [];
|
||||||
|
stillInvalid.forEach(inv => {
|
||||||
|
const l = form.querySelector(`label[for="${inv.name}"]`) || inv.closest('.mb-3')?.querySelector('label');
|
||||||
|
missingNames.push(l ? l.textContent.replace('*', '').trim() : inv.name);
|
||||||
|
});
|
||||||
|
errorDiv.innerHTML = `<strong>Missing Required Fields:</strong><br/>${missingNames.join(', ')}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
input.addEventListener('input', handler);
|
||||||
|
input.addEventListener('change', handler);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. Custom Validation on Submit
|
||||||
|
if (submitBtn) {
|
||||||
|
submitBtn.addEventListener('click', function(e) {
|
||||||
|
const form = document.querySelector('form.checkout_autoformat');
|
||||||
|
if (!form) return;
|
||||||
|
|
||||||
|
// Reset errors before checking
|
||||||
|
let missingFields = [];
|
||||||
|
const requiredInputs = form.querySelectorAll('input[required]:not([type="hidden"]), select[required]');
|
||||||
|
|
||||||
|
requiredInputs.forEach(input => {
|
||||||
|
// Skip hidden fields (from pickup/delivery toggle or company hide)
|
||||||
|
const container = input.closest('div[class*="col-"], .mb-3');
|
||||||
|
if (container && container.style.display === 'none') return;
|
||||||
|
if (input.name === 'company_name' || input.name === 'vat') return;
|
||||||
|
|
||||||
|
const val = input.value ? input.value.trim() : "";
|
||||||
|
const isMissing = !val || val === "0" || val === "";
|
||||||
|
|
||||||
|
if (isMissing) {
|
||||||
|
const label = form.querySelector(`label[for="${input.name}"]`) || input.closest('.mb-3')?.querySelector('label');
|
||||||
|
const fieldName = label ? label.textContent.replace('*', '').trim() : input.name;
|
||||||
|
missingFields.push(fieldName);
|
||||||
|
input.classList.add('is-invalid');
|
||||||
|
input.style.borderColor = '#dc3545';
|
||||||
|
} else {
|
||||||
|
input.classList.remove('is-invalid');
|
||||||
|
input.style.borderColor = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (missingFields.length > 0) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
let errorDiv = document.getElementById('chennora_val_error');
|
||||||
|
if (!errorDiv) {
|
||||||
|
errorDiv = document.createElement('div');
|
||||||
|
errorDiv.id = 'chennora_val_error';
|
||||||
|
errorDiv.className = 'alert alert-danger mt-3 animated fadeIn';
|
||||||
|
form.insertBefore(errorDiv, form.firstChild);
|
||||||
|
}
|
||||||
|
errorDiv.style.display = 'block';
|
||||||
|
errorDiv.innerHTML = `<strong>Missing Required Fields:</strong><br/>${missingFields.join(', ')}`;
|
||||||
|
errorDiv.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getAddressContainers() {
|
function getAddressContainers() {
|
||||||
const addressNames = ['street', 'street2', 'city', 'zip', 'country_id', 'state_id'];
|
const addressNames = ['street', 'street2', 'city', 'zip', 'country_id', 'state_id'];
|
||||||
@ -143,11 +235,19 @@
|
|||||||
containers.forEach(c => c.style.display = 'none');
|
containers.forEach(c => c.style.display = 'none');
|
||||||
if (addrHeader) addrHeader.style.display = 'none';
|
if (addrHeader) addrHeader.style.display = 'none';
|
||||||
if (msgDiv) msgDiv.style.display = 'none';
|
if (msgDiv) msgDiv.style.display = 'none';
|
||||||
if (submitBtn) submitBtn.disabled = false;
|
// Remove required for pickup
|
||||||
|
containers.forEach(c => {
|
||||||
|
c.querySelectorAll('input, select').forEach(i => i.removeAttribute('required'));
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
containers.forEach(c => c.style.display = '');
|
containers.forEach(c => c.style.display = '');
|
||||||
if (addrHeader) addrHeader.style.display = '';
|
if (addrHeader) addrHeader.style.display = '';
|
||||||
if (msgDiv) msgDiv.style.display = '';
|
if (msgDiv) msgDiv.style.display = '';
|
||||||
|
// Restore required
|
||||||
|
['street', 'city', 'zip', 'country_id', 'state_id'].forEach(name => {
|
||||||
|
const i = document.querySelector(`[name="${name}"]`);
|
||||||
|
if (i) i.setAttribute('required', 'required');
|
||||||
|
});
|
||||||
checkUber();
|
checkUber();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user