Checkpoint before implementation. Includes audit findings (FINDINGS.md), architectural recommendation (RECOMMENDATION.md), and existing code changes to Form, Order, Render, and form-action.js from recent development. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
641 lines
27 KiB
JavaScript
641 lines
27 KiB
JavaScript
jQuery(function($){
|
||
|
||
console.info(formipay_form);
|
||
let formipay_form_id = $('[data-form-id]').attr('data-form-id');
|
||
let formipay = formipay_form.forms[formipay_form_id];
|
||
|
||
var select_fields = $('.formipay-input.formipay-select');
|
||
if(select_fields.length > 0){
|
||
$.each(select_fields, function(index, field){
|
||
new Choices('#'+$(field).attr('id'));
|
||
});
|
||
}
|
||
|
||
function validateForm(input_class) {
|
||
var valid = true;
|
||
input_class.each(function () {
|
||
if ($(this).val() === '') {
|
||
valid = false;
|
||
return false;
|
||
}
|
||
});
|
||
return valid;
|
||
}
|
||
|
||
// Optional safety: guard for bad inputs to price_format
|
||
function price_format(nStr) {
|
||
nStr = isNaN(parseFloat(nStr)) ? 0 : parseFloat(nStr); nStr = nStr.toFixed(formipay.decimal_digits) + '';
|
||
var x = nStr.split('.');
|
||
var x1 = x[0];
|
||
var x2 = x.length > 1 ? formipay.decimal_symbol + x[1] : '';
|
||
var rgx = /(\d+)(\d{3})/;
|
||
while (rgx.test(x1)) {
|
||
x1 = x1.replace(rgx, '$1' + formipay.thousand_separator + '$2');
|
||
}
|
||
return formipay.currency + ' ' + x1 + x2;
|
||
}
|
||
|
||
// Removed unconditional product price write: in static-products mode there is no #product_price and this forced a 0.
|
||
$('.formipay-payment-option-group:first-child').find('input').trigger('click');
|
||
|
||
// PAGE BREAK
|
||
var page_break = $('.formipay-page-break');
|
||
if(page_break.length > 0){
|
||
$.each( $('.formipay-field-group:not(.formipay-page-break)'), function(){
|
||
var prev_page_break = $(this).prev('.formipay-page-break');
|
||
$(this).appendTo(prev_page_break);
|
||
} );
|
||
var payment_page_break = $('.formipay-page-break.formipay-page-break-payment');
|
||
$('.result-wrapper').appendTo(payment_page_break);
|
||
$.each( page_break, function(index, page){
|
||
if(index > 0){
|
||
$(page).hide();
|
||
}
|
||
index = index + 1;
|
||
$(page).addClass('formipay-page-'+index);
|
||
});
|
||
$('.formipay-page-break-payment .formipay-submit-button').appendTo('.formipay-bottom-pagination').css({
|
||
'margin-left': 'unset',
|
||
'margin-right': 'unset'
|
||
}).hide();
|
||
}
|
||
var page_break_progress = $('.formipay-progress');
|
||
if(page_break_progress.length > 0){
|
||
// $(page_break_progress[0]).addClass('active');
|
||
$.each(page_break_progress, function(index, page){
|
||
if(index == 0){
|
||
$(page).addClass('active');
|
||
}
|
||
index = index + 1;
|
||
$(page).attr('data-page-number', index);
|
||
});
|
||
}
|
||
|
||
$('.formipay-progress').on('click', function(){
|
||
var page_number = $(this).attr('data-page-number');
|
||
var inputs_in_page = $('.formipay-page-break:visible').find('.formipay-input');
|
||
var valid_to_continue = check_page_input_invalid(inputs_in_page);
|
||
|
||
if(valid_to_continue === false){
|
||
return false;
|
||
}
|
||
|
||
if($('.formipay-page-'+page_number).hasClass('formipay-page-break-payment')){
|
||
$('.formipay-page-break-next-button').hide();
|
||
$('.formipay-page-break-next-button').siblings('.formipay-submit-button').show();
|
||
}else{
|
||
$('.formipay-page-break-next-button').show();
|
||
$('.formipay-page-break-next-button').siblings('.formipay-submit-button').hide();
|
||
}
|
||
|
||
$('.formipay-progress').removeClass('active');
|
||
$(this).addClass('active');
|
||
$('.formipay-page-break').hide();
|
||
$('.formipay-page-'+page_number).show();
|
||
});
|
||
|
||
function check_page_input_invalid(inputs){
|
||
var invalid_input = 0;
|
||
inputs.each(function(index, field) {
|
||
var the_label = $(field).data('label');
|
||
// $(field).removeAttr('style');
|
||
$(field).removeClass('formipay-input-invalid')
|
||
if (!$(field).is(':valid')) {
|
||
// $(field).attr('style', 'border-color: #d93258!important;');
|
||
$(field).addClass('formipay-input-invalid');
|
||
$(field).siblings('.formipay-validate-field').remove();
|
||
if ($(field).attr('type') == 'select' || $(field).attr('type') == 'radio' || $(field).attr('type') == 'checkbox') {
|
||
if ($(field).attr('type') == 'radio' || $(field).attr('type') == 'checkbox') {
|
||
if ($('[name="' + $(field).attr('name') + '"]:checked').length == 0) {
|
||
var notice_message = formipay.notice_empty_select_message;
|
||
$(field).parent().append('<p class="formipay-validate-field"><i class="bi bi-exclamation-circle"></i> '+notice_message.replace('{{field}}', the_label)+'</p>');
|
||
invalid_input ++;
|
||
}
|
||
} else if ($(field).attr('name').search('agreement') != -1) {
|
||
var notice_message = formipay.notice_empty_agreement_message;
|
||
$(field).parent().append('<p class="formipay-validate-field"><i class="bi bi-exclamation-circle"></i> '+notice_message.replace('{{field}}', the_label)+'</p>');
|
||
invalid_input ++;
|
||
} else {
|
||
var notice_message = formipay.notice_empty_select_message;
|
||
$(field).parent().append('<p class="formipay-validate-field"><i class="bi bi-exclamation-circle"></i> '+notice_message.replace('{{field}}', the_label)+'</p>');
|
||
invalid_input ++;
|
||
}
|
||
} else {
|
||
var notice_message = formipay.notice_empty_text_message;
|
||
$(field).parent().append('<p class="formipay-validate-field"><i class="bi bi-exclamation-circle"></i> '+notice_message.replace('{{field}}', the_label)+'</p>');
|
||
invalid_input ++;
|
||
}
|
||
}
|
||
});
|
||
if(invalid_input > 0){
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
$('.formipay-page-break-next-button').on('click', function(e){
|
||
var next_page = $('.formipay-page-break:visible').next('.formipay-page-break');
|
||
var inputs_in_page = $('.formipay-page-break:visible').find('.formipay-input');
|
||
|
||
var valid_to_continue = check_page_input_invalid(inputs_in_page);
|
||
|
||
if(valid_to_continue === false){
|
||
return false;
|
||
}
|
||
|
||
var active_progress = $('.formipay-progress.active');
|
||
if(next_page.length > 0){
|
||
active_progress.next('.formipay-progress').addClass('active');
|
||
active_progress.removeClass('active');
|
||
if(next_page.hasClass('formipay-page-break-payment')){
|
||
// $(this).prop('disabled', true);
|
||
$(this).hide();
|
||
$(this).siblings('.formipay-submit-button').show();
|
||
}
|
||
$('.formipay-page-break:visible').hide();
|
||
next_page.show();
|
||
e.target.blur()
|
||
}
|
||
$('.formipay-page-break-prev-button').prop('disabled', false);
|
||
});
|
||
|
||
$('.formipay-page-break-prev-button').on('click', function(e){
|
||
var prev_page = $('.formipay-page-break:visible').prev('.formipay-page-break');
|
||
var active_progress = $('.formipay-progress.active');
|
||
if(prev_page.length > 0){
|
||
active_progress.prev('.formipay-progress').addClass('active');
|
||
active_progress.removeClass('active');
|
||
if(prev_page.is('.formipay-page-break:nth-child(2)')){
|
||
$(this).prop('disabled', true);
|
||
}
|
||
$('.formipay-page-break-next-button').show();
|
||
$('.formipay-page-break-next-button').siblings('.formipay-submit-button').hide();
|
||
$('.formipay-page-break:visible').hide();
|
||
prev_page.show();
|
||
e.target.blur()
|
||
}
|
||
$('.formipay-page-break-next-button').prop('disabled', false);
|
||
});
|
||
|
||
$('.formipay-input-calculable, .formipay-qty-input').on('change', function(){
|
||
var form = $(this).parents('form');
|
||
set_qty_button();
|
||
do_calculate(form, 'calculate');
|
||
});
|
||
|
||
function set_qty_button() {
|
||
var input = $('.formipay-qty-input');
|
||
var min_val = input.attr('min');
|
||
var max_val = input.attr('max');
|
||
|
||
$('button.qty-min, button.qty-plus').prop('disabled', false);
|
||
|
||
if(input.val() == min_val){
|
||
$('button.qty-min').prop('disabled', true);
|
||
}
|
||
if(max_val && input.val() == max_val){
|
||
$('button.qty-plus').prop('disabled', true);
|
||
}
|
||
}
|
||
|
||
set_qty_button();
|
||
|
||
$('button.qty-min').on('click', function(){
|
||
var value = parseInt($('.formipay-qty-input').val());
|
||
$('.formipay-qty-input').val(value-1).trigger('change');
|
||
});
|
||
|
||
$('button.qty-plus').on('click', function(){
|
||
var value = parseInt($('.formipay-qty-input').val());
|
||
$('.formipay-qty-input').val(value+1).trigger('change');
|
||
});
|
||
|
||
function do_calculate(form, action, condition = 'general'){
|
||
var form_id = form.data('form-id');
|
||
var inputs = form.find('.formipay-input');
|
||
var meta_inputs = form.find('.formipay-meta-input');
|
||
|
||
var form_inputs = new FormData();
|
||
|
||
form_inputs.append('action', 'formipay_submission');
|
||
form_inputs.append('nonce', formipay_form.nonce);
|
||
form_inputs.append('data[qty]', $('.formipay-qty-input').val());
|
||
form_inputs.append('form_id', form_id);
|
||
form_inputs.append('currency', formipay.currency_code || 'IDR');
|
||
|
||
var $valid = true; // Initialize as true
|
||
|
||
inputs.each(function(index, field) {
|
||
var the_key = $(field).attr('name');
|
||
var the_label = $(field).data('label');
|
||
|
||
// $(field).removeAttr('style');
|
||
$(field).removeClass('formipay-input-invalid');
|
||
|
||
if (!$(field).is(':valid')) {
|
||
// $(field).attr('style', 'border-color: #d93258!important;');
|
||
$(field).siblings('.formipay-validate-field').remove();
|
||
|
||
if ($(field).attr('type') == 'select' || $(field).attr('type') == 'radio' || $(field).attr('type') == 'checkbox') {
|
||
var notice_message;
|
||
if ($(field).attr('type') == 'radio' || $(field).attr('type') == 'checkbox') {
|
||
if (!$('[name="' + $(field).attr('name') + '"]:checked').length) {
|
||
var notice_message = formipay.notice_empty_select_message;
|
||
|
||
$valid = false; // Set valid to false
|
||
}
|
||
} else if ($(field).attr('name').search('agreement') != -1) {
|
||
var notice_message = formipay.notice_empty_agreement_message;
|
||
$valid = false; // Set valid to false
|
||
} else {
|
||
var notice_message = formipay.notice_empty_select_message;
|
||
$valid = false; // Set valid to false
|
||
}
|
||
} else {
|
||
var notice_message = formipay.notice_empty_text_message;
|
||
$valid = false; // Set valid to false
|
||
}
|
||
|
||
if($valid == false && action == 'checkout' && condition == 'general'){
|
||
$(field).addClass('formipay-input-invalid');
|
||
$(field).parent().append('<p class="formipay-validate-field"><i class="bi bi-exclamation-circle"></i> '+notice_message.replace('{{field}}', the_label)+'</p>');
|
||
}
|
||
|
||
} else {
|
||
var the_value;
|
||
if ($(field).attr('type') == 'checkbox') {
|
||
var val = [];
|
||
form.find('[name="' + the_key + '"]:checked').each(function(i, check) {
|
||
val[i] = $(check).val();
|
||
});
|
||
the_value = val;
|
||
} else if ($(field).attr('type') == 'radio') {
|
||
the_value = $('[name=' + the_key + ']:checked').val();
|
||
} else {
|
||
the_value = $(field).val();
|
||
}
|
||
|
||
if ($(field).attr('type') == 'hidden' || $(field).parent().is(':hidden')) {
|
||
if ($(field).hasClass('formipay-select')) {
|
||
form_inputs.append('data[' + the_key + '][value]', the_value);
|
||
form_inputs.append('data[' + the_key + '][label]', $(field).find('option:selected').attr('data-label'));
|
||
} else {
|
||
form_inputs.append('data[' + the_key + ']', the_value);
|
||
}
|
||
} else {
|
||
$(field).siblings('.formipay-validate-field').remove();
|
||
|
||
if ($(field).hasClass('formipay-select')) {
|
||
form_inputs.append('data[' + the_key + '][value]', the_value);
|
||
form_inputs.append('data[' + the_key + '][label]', $(field).find('option:selected').attr('data-label'));
|
||
} else {
|
||
form_inputs.append('data[' + the_key + ']', the_value);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
if(meta_inputs.length > 0){
|
||
$.each(meta_inputs, function(key, field){
|
||
var the_key = $(field).attr('name');
|
||
var the_value = $(field).val();
|
||
form_inputs.append('meta_data[' + the_key + ']', the_value);
|
||
});
|
||
}
|
||
|
||
if($valid || action == 'calculate') {
|
||
|
||
form_inputs.append('purpose', action);
|
||
|
||
$.ajax({
|
||
url: formipay_form.ajax_url,
|
||
data: form_inputs,
|
||
processData: false,
|
||
contentType: false,
|
||
type: 'POST',
|
||
enctype: 'multipart/form-data',
|
||
beforeSend: function() {
|
||
form.find('.formipay-submit-button').text(formipay.button_processing_text).prop('disabled', true);
|
||
$(document).trigger('formipayCalculateAjaxBeforeSend', [form, action]);
|
||
},
|
||
success: function(res) {
|
||
console.log(res);
|
||
form.find('.formipay-submit-button').text(formipay.button_text).prop('disabled', false);
|
||
$(document).trigger('formipayCalculateAjaxSuccess', [res, form, action]);
|
||
},
|
||
error: function(xhr, status, error) {
|
||
Swal.fire({
|
||
title: 'Error!',
|
||
html: xhr.responseText,
|
||
icon: 'error',
|
||
customClass: {
|
||
confirmButton: 'formipay-button-error'
|
||
},
|
||
allowOutsideClick: false,
|
||
allowEscapeKey: false,
|
||
showCloseButton: false,
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
window.location.reload();
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
$(document).on('change', '.formipay-input-invalid', function(){
|
||
if($(this).is(':valid')){
|
||
$(this).removeClass('formipay-input-invalid');
|
||
$(this).siblings('.formipay-validate-field').remove();
|
||
}
|
||
});
|
||
|
||
var forms = $('.formipay-form');
|
||
if(forms.length > 0){
|
||
$.each(forms, function(index, form){
|
||
do_calculate($(form), 'calculate', 'first-load');
|
||
});
|
||
}
|
||
|
||
$(document).on('formipayCalculateAjaxBeforeSend', function(event, form, action) {
|
||
|
||
if( action === 'checkout' ){
|
||
form.find('.formipay-validate-field').remove();
|
||
var form_id = form.data('form-id');
|
||
|
||
$('.formipay-input').removeAttr('style');
|
||
$('[data-form-id=' + form_id + ']').siblings('.submit-response').html('');
|
||
$('[data-form-id=' + form_id + ']').siblings('.submit-response').hide();
|
||
$('[data-form-id=' + form_id + ']').siblings('.submit-response').removeClass('formipay-message-success formipay-message-failed');
|
||
}
|
||
|
||
});
|
||
|
||
$(document).on('formipayCalculateAjaxSuccess', function(event, res, form, action) {
|
||
|
||
if(action == 'calculate') {
|
||
var button_text = form.find('.formipay-submit-button').data('button-text');
|
||
|
||
// If backend returns structured items, rebuild dynamic rows
|
||
if(res && Array.isArray(res.items)){
|
||
// Remove previously injected rows (keep total/grand-total rows)
|
||
form.find('.formipay-item-row:not(.formipay-total-row):not(.formipay-grand-total-row)').remove();
|
||
|
||
// If server provides totals
|
||
if(typeof res.total !== 'undefined'){
|
||
form.find('td.grand_total').html(price_format(res.total));
|
||
}
|
||
|
||
// If server provides per-line subtotals
|
||
if(res.items.length){
|
||
// If server distinguishes a primary product subtotal, reflect it
|
||
// but do not rely on index 0 always being product
|
||
res.items.forEach(function(item, index){
|
||
var qty = '';
|
||
if('qty' in item && item.qty > 1){ qty = ' x ' + item.qty; }
|
||
|
||
// If context is 'product' and there is a dedicated product row, update it
|
||
if(item.context === 'product' && form.find('tr.formipay-product-row').length === 1 && index === 0){
|
||
form.find('td.product_price').html(price_format(item.subtotal));
|
||
return; // skip duplicate append below
|
||
}
|
||
|
||
// Append any extra dynamic items before the total row
|
||
form.find('table#formipay-review-order .formipay-total-row').before(
|
||
'<tr class="formipay-item-row '+(item.context||'')+'">\n' +
|
||
' <th>'+ item.item + qty +'</th>\n' +
|
||
' <td>'+ price_format(item.subtotal) +'</td>\n' +
|
||
'</tr>'
|
||
);
|
||
});
|
||
}
|
||
|
||
// Update button from new grand total
|
||
var grand_html = form.find('td.grand_total').text();
|
||
form.find('.formipay-submit-button').html(button_text + ' - ' + grand_html);
|
||
} else {
|
||
// Backend didn’t send calculable payload; keep server-rendered table intact
|
||
var grand_html = form.find('td.grand_total').text();
|
||
if(grand_html){
|
||
form.find('.formipay-submit-button').html(button_text + ' - ' + grand_html);
|
||
} else {
|
||
// Fallback: no grand total cell; do nothing
|
||
}
|
||
}
|
||
}else if(action == 'checkout'){
|
||
var form_id = form.data('form-id');
|
||
if(res.success) {
|
||
if(res.data.response_type == 'notice') {
|
||
$('[data-form-id=' + form_id + ']').find('.submit-response').html('Success! ' + res.data.message);
|
||
$('[data-form-id=' + form_id + ']').find('.submit-response').addClass('formipay-message-success');
|
||
$('[data-form-id=' + form_id + ']').find('.submit-response').show();
|
||
setTimeout(() => {
|
||
window.location.href = res.data.url;
|
||
}, 2500);
|
||
} else if(res.data.response_type == 'popup') {
|
||
let timerInterval;
|
||
Swal.fire({
|
||
title: 'Success!',
|
||
html: res.data.message,
|
||
icon: 'success',
|
||
timer: 2500,
|
||
timerProgressBar: true,
|
||
showConfirmButton: false,
|
||
willClose: () => {
|
||
clearInterval(timerInterval);
|
||
},
|
||
allowOutsideClick: false,
|
||
allowEscapeKey: false,
|
||
showCloseButton: false,
|
||
}).then((result) => {
|
||
if (result.dismiss === Swal.DismissReason.timer) {
|
||
window.location.href = res.data.url;
|
||
}
|
||
});
|
||
}
|
||
} else {
|
||
if(res.data.response_type == 'notice') {
|
||
$('[data-form-id=' + form_id + ']').find('.submit-response').html('Failed! ' + res.data.message);
|
||
$('[data-form-id=' + form_id + ']').find('.submit-response').addClass('formipay-message-failed');
|
||
$('[data-form-id=' + form_id + ']').find('.submit-response').show();
|
||
} else if(res.data.response_type == 'popup') {
|
||
Swal.fire({
|
||
title: 'Failed!',
|
||
html: res.data.message,
|
||
icon: 'error',
|
||
customClass: {
|
||
confirmButton: 'formipay-button-error'
|
||
},
|
||
allowOutsideClick: false,
|
||
allowEscapeKey: false,
|
||
showCloseButton: false,
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
window.location.reload();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
});
|
||
|
||
$('.formipay-form .formipay-submit-button').on('submit click', function(e) {
|
||
e.preventDefault();
|
||
var form = $(this).parents('form');
|
||
do_calculate(form, 'checkout');
|
||
});
|
||
|
||
$('#apply_coupon_code').on('click', function(e){
|
||
e.preventDefault();
|
||
var $thisbutton = $(this);
|
||
var form = $thisbutton.closest('form');
|
||
if($('.formipay-code-input').val() !== ''){
|
||
$.ajax({
|
||
type: 'post',
|
||
url: formipay_form.ajax_url,
|
||
data: {
|
||
action: 'check_coupon_code',
|
||
code: $('.formipay-code-input').val(),
|
||
form: form.data('form-id'),
|
||
security: formipay_form.frontend_nonce
|
||
},
|
||
beforeSend: function() {
|
||
$thisbutton.addClass('loading').prop('disabled', true);
|
||
},
|
||
success: function (res) {
|
||
if(res.success){
|
||
$thisbutton
|
||
.html('<i class="bi bi-check-circle"></i>')
|
||
.removeClass('loading')
|
||
.css('background-color', '#008000');
|
||
}else{
|
||
$thisbutton
|
||
.html('<i class="bi bi-exclamation-circle"></i>')
|
||
.removeClass('loading')
|
||
.css('background-color', '#FF0000');
|
||
$('.formipay-code-input').val('');
|
||
}
|
||
do_calculate(form, 'calculate');
|
||
setTimeout(() => {
|
||
$thisbutton
|
||
.removeAttr('style')
|
||
.html($thisbutton.data('text'))
|
||
.prop('disabled', false);
|
||
}, 3000);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
const $phoneInput = $(`[name=${formipay.buyer_phone_field}]`);
|
||
const $countrySelect = formipay.buyer_country_field !== "" ? $(`[name=${formipay.buyer_country_field}]`) : '';
|
||
|
||
let countryCode = formipay.buyer_phone_country_code || '';
|
||
|
||
// Function: Get all available phone codes from select options
|
||
function getAllCountryCodes() {
|
||
const codes = [];
|
||
$countrySelect.find('option').each(function () {
|
||
const code = $(this).data('phone-code');
|
||
if (code) codes.push(code.toString());
|
||
});
|
||
return codes;
|
||
}
|
||
|
||
// Function: Convert number to WhatsApp-compatible format
|
||
function toWhatsAppNumber(phoneNumber, newCountryCode = '62') {
|
||
if (!phoneNumber) return '';
|
||
|
||
let cleaned = phoneNumber.replace(/\D/g, '');
|
||
|
||
// Step 1: Remove any existing known country code
|
||
const knownCountryCodes = getAllCountryCodes();
|
||
|
||
knownCountryCodes.forEach(code => {
|
||
if (cleaned.startsWith(code)) {
|
||
cleaned = cleaned.substring(code.length);
|
||
}
|
||
});
|
||
|
||
// Step 2: Remove leading zero after removing old country code
|
||
if (cleaned.startsWith('0')) {
|
||
cleaned = cleaned.substring(1);
|
||
}
|
||
|
||
// Step 3: Add new country code
|
||
return newCountryCode + cleaned;
|
||
}
|
||
|
||
// Get current country code dynamically
|
||
function getCurrentCountryCode() {
|
||
return $countrySelect.length > 0
|
||
? ($countrySelect.find(':selected').data('phone-code') || '')
|
||
: (formipay.buyer_phone_country_code || '');
|
||
}
|
||
|
||
// On country change: Update country code and re-format phone number
|
||
if ($countrySelect.length > 0) {
|
||
$countrySelect.on('change', function () {
|
||
const oldCountryCode = countryCode;
|
||
countryCode = $countrySelect.find(':selected').data('phone-code') || '';
|
||
|
||
if (!countryCode) return;
|
||
|
||
const currentValue = $phoneInput.val().trim();
|
||
|
||
// If there's a current phone number and country changed
|
||
if (currentValue && currentValue !== oldCountryCode) {
|
||
const converted = toWhatsAppNumber(currentValue, countryCode);
|
||
$phoneInput.val(converted);
|
||
} else {
|
||
// Set placeholder if empty
|
||
$phoneInput.val(countryCode);
|
||
}
|
||
});
|
||
}
|
||
|
||
// On focus: insert country code as placeholder
|
||
$phoneInput.on('focus', function () {
|
||
const $this = $(this);
|
||
const currentValue = $this.val().trim();
|
||
const currentCode = getCurrentCountryCode();
|
||
|
||
if (!currentCode) return;
|
||
|
||
// Save original value before modifying
|
||
$this.data('original-value', currentValue);
|
||
|
||
if (currentValue === '' || currentValue === currentCode) {
|
||
$this.val(currentCode);
|
||
}
|
||
});
|
||
|
||
// On blur: clean up or convert to WhatsApp number
|
||
$phoneInput.on('blur', function () {
|
||
const $this = $(this);
|
||
const originalValue = $this.data('original-value') || '';
|
||
const currentValue = $this.val().trim();
|
||
const currentCode = getCurrentCountryCode();
|
||
|
||
if (!currentCode) return;
|
||
|
||
// Case: user left field empty or only had country code
|
||
if (currentValue === '' || currentValue === currentCode || currentValue.length <= 4) {
|
||
$this.val(''); // Clear it for placeholder behavior
|
||
return;
|
||
}
|
||
|
||
// Skip conversion if already formatted
|
||
const isAlreadyFormatted = getAllCountryCodes().some(code =>
|
||
currentValue.startsWith(code)
|
||
);
|
||
|
||
if (!isAlreadyFormatted || originalValue !== currentValue) {
|
||
const waNumber = toWhatsAppNumber(currentValue, currentCode);
|
||
$this.val(waNumber);
|
||
}
|
||
});
|
||
|
||
}); |