jQuery(document).ready(function($) {
// Initialize Select2 on the country dropdown
const $countrySelect = $('#cod_form_country');
if ($countrySelect.length) {
$countrySelect.select2({
templateResult: formatCountry,
templateSelection: formatCountry,
width: 'resolve' // Ensures Select2 takes the full width of its container
});
}
// Initialize Select2 on all dial code dropdowns (for phone and WhatsApp)
const $dialCodeSelects = $('.dial-code-select');
if ($dialCodeSelects.length) {
$dialCodeSelects.select2({
templateResult: formatDialCode, // Use a specific formatter for dial codes
templateSelection: formatDialCode,
width: 'resolve'
});
}
// Function to format country options with flags and dial codes for the main country select
function formatCountry(country) {
if (!country.id) {
return country.text;
}
const countryCode = country.id;
const countryData = cod_form_vars.countries_data[countryCode];
if (!countryData) {
return country.text; // Fallback if data is missing
}
const $span = $(
'' +
(countryData.flag_svg ? '' + countryData.flag_svg + '' : '') +
'' + countryData.name + '' + // Display full country name
(countryData.dial_code ? ' (' + countryData.dial_code + ')' : '') +
''
);
return $span;
}
// Function to format dial code options with flags and dial codes for phone/WhatsApp
function formatDialCode(option) {
if (!option.id) {
return option.text;
}
// Find the corresponding country data using the dial code
let countryData = null;
for (const code in cod_form_vars.countries_data) {
if (cod_form_vars.countries_data[code].dial_code === option.id) {
countryData = cod_form_vars.countries_data[code];
break;
}
}
if (!countryData) {
return option.text; // Fallback if data is missing
}
const $span = $(
'' +
(countryData.flag_svg ? '' + countryData.flag_svg + '' : '') +
'' + countryData.dial_code + '' +
''
);
return $span;
}
// Update the dial code input when a country is selected in the main country field
$countrySelect.on('select2:select', function (e) {
const countryCode = e.params.data.id;
const countryData = cod_form_vars.countries_data[countryCode];
if (countryData && countryData.dial_code) {
// Set the phone dial code and trigger change to update Select2 display
$('#cod_form_phone_dial_code').val(countryData.dial_code).trigger('change');
// If WhatsApp is present and empty, update it too
const $whatsappDialCode = $('#cod_form_whatsapp_dial_code');
if ($whatsappDialCode.length && $whatsappDialCode.val() === '') {
$whatsappDialCode.val(countryData.dial_code).trigger('change');
}
}
});
// Handle form submission via AJAX
$('#cod-form').on('submit', function(e) {
e.preventDefault(); // Prevent default form submission
const $form = $(this);
const $submitButton = $form.find('button[type="submit"]');
const originalButtonText = $submitButton.text();
// Clear previous messages
$('.cod-form-message').remove(); // Remove any existing messages
// Disable button and show loading text
$submitButton.prop('disabled', true).text(cod_form_vars.messages.processing || 'Processing...');
$form.addClass('loading'); // Add a class for potential loading styles
let errors = [];
// Get field configurations from localized script
const fieldsConfig = cod_form_vars.fields_config;
const selectedCountryCode = $countrySelect.val(); // Get the selected country code once
// Iterate over all fields and perform validation based on their settings
for (const fieldId in fieldsConfig) {
const fieldProps = fieldsConfig[fieldId];
if (!fieldProps.visible) {
continue; // Skip validation for non-visible fields
}
// Get input value for general fields
let inputValue = $(`#cod_form_${fieldId}`).val();
if (fieldId === 'phone') {
const $phoneDialCode = $('#cod_form_phone_dial_code');
const $phoneLocalNum = $('#cod_form_phone_local_num');
const phoneDialVal = $phoneDialCode.val();
const phoneLocalVal = $phoneLocalNum.val();
if (fieldProps.required && (!phoneDialVal || !phoneLocalVal)) {
errors.push(cod_form_vars.messages.phone_required);
} else if (phoneDialVal && phoneLocalVal) { // Only validate if both parts are filled
const phoneValidationResult = validatePhoneNumber(selectedCountryCode, phoneLocalVal, 'phone');
if (phoneValidationResult !== true) {
errors.push(phoneValidationResult);
}
}
} else if (fieldId === 'whatsapp') {
const $whatsappDialCode = $('#cod_form_whatsapp_dial_code');
const $whatsappLocalNum = $('#cod_form_whatsapp_local_num');
const whatsappDialVal = $whatsappDialCode.val();
const whatsappLocalVal = $whatsappLocalNum.val();
// If WhatsApp is required and not filled
if (fieldProps.required && (!whatsappDialVal || !whatsappLocalVal)) {
errors.push(fieldProps.label + ' ' + (cod_form_vars.messages.whatsapp_required_full || cod_form_vars.messages.phone_required));
}
// If WhatsApp is optional but partially filled, or completely filled, validate
else if ((whatsappDialVal && !whatsappLocalVal) || (!whatsappDialVal && whatsappLocalVal)) {
errors.push(cod_form_vars.messages.whatsapp_required || 'Both WhatsApp dial code and number are required if you provide one.');
} else if (whatsappDialVal && whatsappLocalVal) { // If both are filled, validate format
const whatsappValidationResult = validatePhoneNumber(selectedCountryCode, whatsappLocalVal, 'whatsapp');
if (whatsappValidationResult !== true) {
errors.push(whatsappValidationResult);
}
}
} else if (fieldId === 'email') {
// Email is optional by default, so only validate if filled
if (inputValue && !isValidEmail(inputValue)) {
errors.push(cod_form_vars.messages.invalid_email || 'Please enter a valid email address.');
} else if (fieldProps.required && !inputValue) { // If email is required but empty
errors.push(fieldProps.label + ' ' + (cod_form_vars.messages.field_required || 'is required.'));
}
} else {
// General required field check for text/textarea/select fields
if (fieldProps.required && !inputValue) {
errors.push(fieldProps.label + ' ' + (cod_form_vars.messages.field_required || 'is required.'));
}
}
}
// If client-side validation fails, display errors and re-enable button
if (errors.length > 0) {
displayMessage(errors.join(' '), 'error');
$submitButton.prop('disabled', false).text(originalButtonText);
$form.removeClass('loading');
return;
}
// Get product ID from the form
const productId = $form.find('input[name="product_id"]').val() || null;
// Perform AJAX request
$.ajax({
url: cod_form_vars.ajax_url,
type: 'POST',
dataType: 'json',
data: $form.serialize() + '&action=cod_form_submit_ajax&nonce=' + cod_form_vars.nonce + '&product_id=' + productId,
success: function(response) {
if (response.success) {
displayMessage(response.data.message, 'success');
// Redirect to order received page on success
if (response.data.redirect_url) {
window.location.href = response.data.redirect_url;
} else {
// Optionally clear the form or show a success message
$form[0].reset(); // Clear form fields
$countrySelect.val(null).trigger('change'); // Reset Select2 for country
$dialCodeSelects.val(null).trigger('change'); // Reset Select2 for dial codes
}
} else {
displayMessage(response.data.message, 'error');
}
},
error: function(xhr, status, error) {
console.error('AJAX Error:', status, error);
displayMessage(cod_form_vars.messages.error_creating_order || 'An unexpected error occurred. Please try again.', 'error');
},
complete: function() {
$submitButton.prop('disabled', false).text(originalButtonText);
$form.removeClass('loading');
}
});
});
// Handle coupon application via AJAX
$('#apply-coupon-button').on('click', function(e) {
e.preventDefault();
const $couponInput = $('#cod_form_coupon_code');
const couponCode = $couponInput.val();
const $couponMessage = $('.coupon-message');
$couponMessage.removeClass('success error').text(''); // Clear previous messages
if (!couponCode) {
$couponMessage.text(cod_form_vars.messages.enter_coupon_code || 'Please enter a coupon code.').addClass('error');
return;
}
const $button = $(this);
const originalButtonText = $button.text();
$button.prop('disabled', true).text(cod_form_vars.messages.applying_coupon || 'Applying...');
// Get product ID from a hidden input or data attribute on the form
const productId = $('#cod-form').find('input[name="product_id"]').val() || null;
if (!productId) {
$couponMessage.text('Product ID not found for coupon application.').addClass('error');
$button.prop('disabled', false).text(originalButtonText);
return;
}
$.ajax({
url: cod_form_vars.ajax_url,
type: 'POST',
dataType: 'json',
data: {
action: 'cod_form_apply_coupon',
coupon_code: couponCode,
product_id: productId, // Pass product ID to AJAX handler
nonce: cod_form_vars.nonce
},
success: function(response) {
if (response.success) {
$couponMessage.text(cod_form_vars.messages.coupon_applied).addClass('success');
// Update invoice details if provided in response
if (response.data.invoice_html) {
$('.invoice-details-box').replaceWith(response.data.invoice_html);
}
} else {
$couponMessage.text(response.data.message || cod_form_vars.messages.coupon_invalid).addClass('error');
}
},
error: function(xhr, status, error) {
console.error('AJAX Error:', status, error);
$couponMessage.text(cod_form_vars.messages.error_applying_coupon).addClass('error');
},
complete: function() {
$button.prop('disabled', false).text(originalButtonText);
}
});
});
// Helper function to display messages
function displayMessage(message, type) {
const $form = $('#cod-form');
let $messageDiv = $form.find('.cod-form-message');
if ($messageDiv.length === 0) {
$messageDiv = $('
');
$form.prepend($messageDiv);
}
$messageDiv.removeClass('success error').addClass(type).html(message).show();
// Scroll to the message
$('html, body').animate({
scrollTop: $messageDiv.offset().top - 50
}, 500);
}
// Basic email validation
function isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
// Phone number validation function (client-side)
function validatePhoneNumber(countryCode, localNumber, fieldType) {
const countriesData = cod_form_vars.countries_data;
if (!countriesData[countryCode] || !countriesData[countryCode].phone_validation) {
return true; // No validation rules for this country, assume valid
}
const validationRules = countriesData[countryCode].phone_validation;
let cleanLocalNum = localNumber.replace(/[^0-9]/g, ''); // Remove non-digits
// Specific rule for Jordan: remove leading zero if present
if (countryCode === 'JO' && validationRules.remove_leading_zero && cleanLocalNum.startsWith('0')) {
cleanLocalNum = cleanLocalNum.substring(1);
}
// Validate length
// Corrected: Use validationRules.length instead of validationLocalNum.length
if (validationRules.length && cleanLocalNum.length !== validationRules.length) {
if (fieldType === 'whatsapp') {
return cod_form_vars.messages.whatsapp_invalid_length;
}
return cod_form_vars.messages.invalid_phone_length;
}
// Validate prefixes
if (validationRules.prefixes && validationRules.prefixes.length > 0) {
let prefixMatch = false;
for (let i = 0; i < validationRules.prefixes.length; i++) {
if (cleanLocalNum.startsWith(validationRules.prefixes[i])) {
prefixMatch = true;
break;
}
}
if (!prefixMatch) {
if (fieldType === 'whatsapp') {
return cod_form_vars.messages.whatsapp_invalid_prefix;
}
return cod_form_vars.messages.invalid_phone_prefix;
}
}
return true; // Phone number is valid
}
// Set dynamic CSS variables for styling
function setCssVariables() {
// Get styling settings from localized script (if available)
const stylingSettings = cod_form_vars.styling_settings || {};
const root = document.documentElement;
// Apply fallback values if settings are not defined
root.style.setProperty('--form-bg-color', stylingSettings.form_bg_color || '#f9f9f9');
root.style.setProperty('--form-border-radius', (stylingSettings.form_border_radius || '8px'));
root.style.setProperty('--form-padding', (stylingSettings.form_padding || '20px'));
root.style.setProperty('--form-box-shadow', stylingSettings.form_box_shadow || '0 2px 10px rgba(0,0,0,0.1)');
root.style.setProperty('--title-color', stylingSettings.title_color || '#333');
root.style.setProperty('--label-color', stylingSettings.label_color || '#333');
root.style.setProperty('--input-text-color', stylingSettings.input_text_color || '#555');
root.style.setProperty('--input-border-color', stylingSettings.input_border_color || '#ddd');
root.style.setProperty('--input-bg-color', stylingSettings.input_bg_color || '#ffffff');
root.style.setProperty('--button-bg-color', stylingSettings.button_bg_color || '#0073aa');
root.style.setProperty('--button-text-color', stylingSettings.button_text_color || '#ffffff');
root.style.setProperty('--button-border-radius', (stylingSettings.button_border_radius || '6px'));
root.style.setProperty('--button-padding', stylingSettings.button_padding || '12px 20px');
root.style.setProperty('--button-box-shadow', stylingSettings.button_box_shadow || '0 4px 6px rgba(0,0,0,0.1)');
// New styling settings for additional option box
root.style.setProperty('--additional-option-bg-color', stylingSettings.additional_option_bg_color || '#e6ffe6');
root.style.setProperty('--additional-option-border-color', stylingSettings.additional_option_border_color || '#a3e6a3');
root.style.setProperty('--additional-option-border-style', stylingSettings.additional_option_border_style || 'dashed');
root.style.setProperty('--additional-option-border-width', stylingSettings.additional_option_border_width || '2px');
root.style.setProperty('--additional-option-border-radius', stylingSettings.additional_option_border_radius || '8px');
root.style.setProperty('--additional-option-padding', stylingSettings.additional_option_padding || '15px');
// Calculate hover colors (example: 10% darker)
const buttonBgColor = stylingSettings.button_bg_color || '#0073aa';
root.style.setProperty('--button-hover-bg-color', adjustBrightness(buttonBgColor, -10));
const inputBgColor = stylingSettings.input_bg_color || '#ffffff';
root.style.setProperty('--input-hover-bg-color', adjustBrightness(inputBgColor, -5)); // Slightly darker for hover
root.style.setProperty('--input-selected-bg-color', adjustBrightness(inputBgColor, -10)); // Darker for selected
}
// Helper function to adjust hex color brightness (client-side)
function adjustBrightness(hex, percent) {
// Remove # if present
hex = hex.replace('#', '');
// Convert hex to RGB
let r = parseInt(hex.substring(0, 2), 16);
let g = parseInt(hex.substring(2, 4), 16);
let b = parseInt(hex.substring(4, 6), 16);
// Adjust brightness
r = Math.round(r * (100 + percent) / 100);
g = Math.round(g * (100 + percent) / 100);
b = Math.round(b * (100 + percent) / 100);
// Ensure values are within 0-255 range
r = Math.max(0, Math.min(255, r));
g = Math.max(0, Math.min(255, g));
b = Math.max(0, Math.min(255, b));
// Convert RGB to hex
const toHex = (c) => ('0' + c.toString(16)).slice(-2);
return '#' + toHex(r) + toHex(g) + toHex(b);
}
// Call setCssVariables on document ready
setCssVariables();
});
Droopy eyelid – SKINCI
Just because you visited our website, you will get a 10% discount coupon on the available products. Place the discount coupon in the designated box to get the discount.