973 lines
32 KiB
JavaScript
973 lines
32 KiB
JavaScript
jQuery( function( $ ) {
|
|
|
|
$( '.wcpdf-extensions .more' ).hide();
|
|
|
|
$( '.wcpdf-extensions > li' ).on( 'click', function( event ) {
|
|
$( this ).toggleClass( 'expanded' );
|
|
$( this ).find( '.more' ).slideToggle();
|
|
} );
|
|
|
|
$( '.edit-next-number' ).on( 'click', function( event ) {
|
|
// enable input & show save button
|
|
$( this ).hide();
|
|
$( this ).siblings( 'input' ).prop( 'disabled', false );
|
|
$( this ).siblings( '.save-next-number.button' ).show();
|
|
} );
|
|
|
|
$( '.save-next-number' ).on( 'click', function( event ) {
|
|
$input = $( this ).siblings( 'input' );
|
|
$input.addClass( 'ajax-waiting' );
|
|
let number = $input.val();
|
|
|
|
if ( number.length > 0 && number > 2147483647 ) {
|
|
alert( wpo_wcpdf_admin.mysql_int_size_limit );
|
|
$input.removeClass( 'ajax-waiting' );
|
|
return;
|
|
}
|
|
|
|
|
|
let data = {
|
|
security: $input.data( 'nonce' ),
|
|
action: 'wpo_wcpdf_set_next_number',
|
|
store: $input.data( 'store' ),
|
|
number: number,
|
|
};
|
|
|
|
xhr = $.ajax( {
|
|
type: 'POST',
|
|
url: wpo_wcpdf_admin.ajaxurl,
|
|
data: data,
|
|
success: function( response ) {
|
|
$input.removeClass( 'ajax-waiting' );
|
|
$input.siblings( '.edit-next-number' ).show();
|
|
$input.prop( 'disabled', 'disabled' );
|
|
$input.siblings( '.save-next-number.button' ).hide();
|
|
}
|
|
} );
|
|
} );
|
|
|
|
$( "[name='wpo_wcpdf_documents_settings_invoice[display_number]']" ).on( 'change', function( event ) {
|
|
if ( $( this ).val() == 'order_number' ) {
|
|
$( this ).closest( 'td' ).find( '.description' ).slideDown();
|
|
$( this ).closest( 'tr' ).nextAll( 'tr' ).has( 'input#next_invoice_number' ).first().hide();
|
|
} else {
|
|
$( this ).closest( 'td' ).find( '.description' ).hide();
|
|
$( this ).closest( 'tr' ).nextAll( 'tr' ).has( 'input#next_invoice_number' ).first().show();
|
|
}
|
|
} ).trigger( 'change' );
|
|
|
|
// enable settings document switch
|
|
$( '.wcpdf_document_settings_sections > h2' ).on( 'click', function() {
|
|
$( this ).parent().find( 'ul' ).toggleClass( 'active' );
|
|
} );
|
|
|
|
// Add admin pointers
|
|
$.each( wpo_wcpdf_admin.pointers, function( key, pointer ) {
|
|
|
|
$( pointer.target ).pointer(
|
|
{
|
|
content: pointer.content,
|
|
|
|
position:
|
|
{
|
|
edge: pointer.position.edge,
|
|
align: pointer.position.align
|
|
},
|
|
|
|
pointerClass: pointer.pointer_class,
|
|
|
|
pointerWidth: pointer.pointer_width,
|
|
|
|
close: function() {
|
|
jQuery.post(
|
|
wpo_wcpdf_admin.ajaxurl,
|
|
{
|
|
pointer: key,
|
|
action: 'dismiss-wp-pointer',
|
|
}
|
|
);
|
|
},
|
|
}
|
|
);
|
|
|
|
// Check if pointer was dismissed
|
|
if ( $.inArray( key, wpo_wcpdf_admin.dismissed_pointers.split(',') ) === -1 ) {
|
|
$( pointer.target ).pointer('open');
|
|
}
|
|
|
|
});
|
|
|
|
// enable WooCommerce help tips
|
|
$( '.woocommerce-help-tip' ).tipTip( {
|
|
'attribute': 'data-tip',
|
|
'fadeIn': 50,
|
|
'fadeOut': 50,
|
|
'delay': 200
|
|
} );
|
|
|
|
$( '#wpo-wcpdf-preview-wrapper #due_date' ).on( 'change', function() {
|
|
const $due_date_checkbox = $( '#wpo-wcpdf-preview-wrapper #due_date' );
|
|
const $due_date_days_input = $( '#wpo-wcpdf-preview-wrapper #due_date_days' );
|
|
|
|
if ( $due_date_checkbox.is( ':checked' ) ) {
|
|
$due_date_days_input.prop( 'disabled', false );
|
|
} else {
|
|
$due_date_days_input.prop( 'disabled', true );
|
|
}
|
|
} ).trigger( 'change' );
|
|
|
|
//----------> Preview <----------//
|
|
// objects
|
|
let $previewWrapper = $( '#wpo-wcpdf-preview-wrapper' );
|
|
let $preview = $( '#wpo-wcpdf-preview-wrapper .preview' );
|
|
let $previewOrderIdInput = $( '#wpo-wcpdf-preview-wrapper input[name="order_id"]' );
|
|
let $previewDocumentTypeInput = $( '#wpo-wcpdf-preview-wrapper input[name="document_type"]' );
|
|
let $previewOutputFormatInput = $( '#wpo-wcpdf-preview-wrapper input[name="output_format"]' );
|
|
let $previewNonceInput = $( '#wpo-wcpdf-preview-wrapper input[name="nonce"]' );
|
|
let $previewSettingsForm = $( '#wpo-wcpdf-settings' );
|
|
let previewXhr = null;
|
|
|
|
// variables
|
|
let previewOrderId, previewDocumentType, previewOutputFormat, previewNonce, previewSettingsFormData, previewTimeout, previewSearchTimeout, previousWindowWidth;
|
|
|
|
function loadPreviewData() {
|
|
previewOrderId = $previewOrderIdInput.val();
|
|
previewDocumentType = $previewDocumentTypeInput.val();
|
|
previewOutputFormat = $previewOutputFormatInput.val();
|
|
previewNonce = $previewNonceInput.val();
|
|
previewSettingsFormData = $previewSettingsForm.serialize();
|
|
}
|
|
|
|
function resetDocumentType() {
|
|
$previewDocumentTypeInput.val( $previewDocumentTypeInput.data( 'default' ) ).trigger( 'change' );
|
|
}
|
|
|
|
function resetOrderId() {
|
|
$previewOrderIdInput.val( '' ).trigger( 'change' );
|
|
}
|
|
|
|
resetDocumentType(); // force document type reset
|
|
resetOrderId(); // force order ID reset
|
|
loadPreviewData(); // load preview data
|
|
|
|
previousWindowWidth = $( window ).width();
|
|
determinePreviewStates(); // determine preview states based on screen size
|
|
|
|
$( window ).on( 'resize', determinePreviewStates );
|
|
|
|
function determinePreviewStates() {
|
|
// Check if preview states are allowed to change based on screen size
|
|
if ( $previewWrapper.attr( 'data-preview-states-lock') == false ) {
|
|
|
|
// On small screens: 2 preview states and close preview
|
|
if ( $(this).width() <= 1200 && ( previousWindowWidth > 1200 || $(this).width() == previousWindowWidth ) ) {
|
|
if ( $previewWrapper.attr( 'data-preview-state') == 'full' ) {
|
|
$previewWrapper.find( '.preview-document' ).show();
|
|
$previewWrapper.find( '.sidebar' ).hide();
|
|
$previewWrapper.find( '.slide-left' ).hide();
|
|
$previewWrapper.find( '.slide-right' ).show();
|
|
$previewWrapper.attr( 'data-preview-states', 2 );
|
|
$previewWrapper.attr( 'data-preview-state', 'full' );
|
|
$previewWrapper.attr( 'data-from-preview-state', '' );
|
|
} else {
|
|
$previewWrapper.find( '.preview-document' ).hide();
|
|
$previewWrapper.find( '.sidebar' ).show();
|
|
$previewWrapper.find( '.slide-left' ).show();
|
|
$previewWrapper.find( '.slide-right' ).hide();
|
|
$previewWrapper.attr( 'data-preview-states', 2 );
|
|
$previewWrapper.attr( 'data-preview-state', 'closed' );
|
|
$previewWrapper.attr( 'data-from-preview-state', '' );
|
|
}
|
|
|
|
// On larger screens: 3 preview states and show settings as sidebar
|
|
} else if ( $(this).width() > 1200 && ( previousWindowWidth <= 1200 || $(this).width() == previousWindowWidth ) ) {
|
|
if ( $previewWrapper.attr( 'data-preview-state') == 'full' ) {
|
|
$previewWrapper.find( '.preview-document' ).show();
|
|
$previewWrapper.find( '.sidebar' ).hide();
|
|
$previewWrapper.find( '.slide-left' ).hide();
|
|
$previewWrapper.find( '.slide-right' ).show();
|
|
$previewWrapper.attr( 'data-preview-states', 3 );
|
|
$previewWrapper.attr( 'data-preview-state', 'full' );
|
|
$previewWrapper.attr( 'data-from-preview-state', 'sidebar' );
|
|
$previewWrapper.addClass( 'static' );
|
|
} else if ( $previewWrapper.attr( 'data-preview-state') == 'closed' && $(this).width() !== previousWindowWidth ) {
|
|
$previewWrapper.find( '.preview-document' ).hide();
|
|
$previewWrapper.find( '.sidebar' ).show();
|
|
$previewWrapper.find( '.slide-left' ).show();
|
|
$previewWrapper.find( '.slide-right' ).hide();
|
|
$previewWrapper.attr( 'data-preview-states', 3 );
|
|
$previewWrapper.attr( 'data-preview-state', 'closed' );
|
|
$previewWrapper.attr( 'data-from-preview-state', '' );
|
|
$previewWrapper.removeClass( 'static' );
|
|
} else {
|
|
$previewWrapper.find( '.preview-document, .sidebar' ).show();
|
|
$previewWrapper.find( '.slide-left, .slide-right' ).show();
|
|
$previewWrapper.attr( 'data-preview-states', 3 );
|
|
$previewWrapper.attr( 'data-preview-state', 'sidebar' );
|
|
$previewWrapper.attr( 'data-from-preview-state', '' );
|
|
$previewWrapper.removeClass( 'static' );
|
|
}
|
|
}
|
|
}
|
|
previousWindowWidth = $(this).width();
|
|
}
|
|
|
|
$( '.slide-left' ).on( 'click', function() {
|
|
let previewStates = $previewWrapper.attr( 'data-preview-states' );
|
|
let previewState = $previewWrapper.attr( 'data-preview-state' );
|
|
|
|
$previewWrapper.find( '.preview-data-wrapper ul' ).removeClass( 'active' );
|
|
|
|
if ( previewStates == 3 ) {
|
|
if ( previewState == 'closed' ) {
|
|
$previewWrapper.find( '.preview-document' ).show();
|
|
$previewWrapper.find( '.slide-right' ).show();
|
|
$previewWrapper.attr( 'data-preview-state', 'sidebar' );
|
|
$previewWrapper.attr( 'data-from-preview-state', 'closed' );
|
|
} else {
|
|
$previewWrapper.find( '.slide-left' ).hide();
|
|
$previewWrapper.find( '.sidebar' ).delay(300).hide(0);
|
|
$previewWrapper.attr( 'data-preview-state', 'full' );
|
|
$previewWrapper.attr( 'data-from-preview-state', 'sidebar' );
|
|
makePreviewScrollable( $previewWrapper );
|
|
}
|
|
} else {
|
|
$previewWrapper.find( '.preview-document' ).show();
|
|
$previewWrapper.find( '.slide-left' ).hide();
|
|
$previewWrapper.find( '.slide-right' ).show();
|
|
$previewWrapper.attr( 'data-preview-state', 'full' );
|
|
$previewWrapper.attr( 'data-from-preview-state', 'closed' );
|
|
makePreviewScrollable( $previewWrapper );
|
|
}
|
|
} );
|
|
|
|
$( '.slide-right' ).on( 'click', function() {
|
|
let previewStates = $previewWrapper.attr( 'data-preview-states' );
|
|
let previewState = $previewWrapper.attr( 'data-preview-state' );
|
|
|
|
$previewWrapper.find( '.preview-data-wrapper ul' ).removeClass( 'active' );
|
|
|
|
if ( previewStates == 3 ) {
|
|
if ( previewState == 'full' ) {
|
|
$previewWrapper.find( '.slide-left' ).delay(400).show(0);
|
|
$previewWrapper.find( '.sidebar' ).show();
|
|
$previewWrapper.attr( 'data-preview-state', 'sidebar' );
|
|
$previewWrapper.attr( 'data-from-preview-state', 'full' );
|
|
} else {
|
|
$previewWrapper.find( '.preview-document' ).hide(300);
|
|
$previewWrapper.find( '.slide-right' ).hide();
|
|
$previewWrapper.attr( 'data-preview-state', 'closed' );
|
|
$previewWrapper.attr( 'data-from-preview-state', 'sidebar' );
|
|
}
|
|
} else {
|
|
$previewWrapper.find( '.preview-document' ).hide(300);
|
|
$previewWrapper.find( '.slide-left' ).show();
|
|
$previewWrapper.find( '.slide-right' ).hide();
|
|
$previewWrapper.attr( 'data-preview-state', 'closed' );
|
|
$previewWrapper.attr( 'data-from-preview-state', 'full' );
|
|
}
|
|
$previewWrapper.removeClass( 'static' );
|
|
} );
|
|
|
|
function makePreviewScrollable( wrapper ) {
|
|
window.scrollTo( 0, 0 );
|
|
let $wrapper = wrapper;
|
|
// Make preview scrollable after panel animation is complete
|
|
setTimeout( function() {
|
|
$wrapper.addClass( 'static' );
|
|
}, 300 );
|
|
}
|
|
|
|
$( '.preview-document .preview-data p' ).on( 'click', function() {
|
|
let $previewData = $( this ).closest( '.preview-data' );
|
|
$previewData.siblings( '.preview-data' ).find( 'ul' ).removeClass( 'active' );
|
|
$previewData.find( 'ul' ).toggleClass( 'active' );
|
|
} );
|
|
|
|
$( '.preview-document .preview-data ul > li' ).on( 'click', function() {
|
|
let $previewData = $( this ).closest( '.preview-data' );
|
|
$previewData.find( 'ul' ).toggleClass( 'active' );
|
|
if ( $( this ).hasClass( 'order-search' ) ) {
|
|
$previewData.find( 'p.last-order' ).hide();
|
|
$previewData.find( 'input[name="preview-order-search"]' ).addClass( 'active' );
|
|
$previewData.find( 'p.order-search' ).show().find( '.order-search-label' ).text( $( this ).text() );
|
|
} else {
|
|
$previewData.find( 'p.last-order' ).show();
|
|
$previewData.find( 'p.order-search' ).hide();
|
|
$previewData.find( 'input[name="preview-order-search"]' ).removeClass( 'active' ).val( '' );
|
|
$previewData.find( '#preview-order-search-results' ).hide();
|
|
$previewData.find( 'img.preview-order-search-clear' ).hide(); // remove the clear button
|
|
resetOrderId() // force order ID reset
|
|
triggerPreview(); // trigger preview
|
|
}
|
|
} );
|
|
|
|
// Preview on page load
|
|
triggerPreview();
|
|
|
|
// Custom trigger to signify settings have changed (will show save button and refresh preview)
|
|
$( document ).on( 'wpo-wcpdf-settings-changed', function( event, delay ) {
|
|
showSaveBtn();
|
|
triggerPreview( delay );
|
|
} );
|
|
|
|
// Custom trigger to refresh preview
|
|
$( document ).on( 'wpo-wcpdf-refresh-preview wpo_wcpdf_refresh_preview', function( event, delay ) {
|
|
triggerPreview( delay );
|
|
} );
|
|
|
|
// Preview on user click in search result
|
|
$( document ).on( 'click', '#preview-order-search-results a', function( event ) {
|
|
event.preventDefault();
|
|
$( '.preview-document .order-search-label').text( '#' + $( this ).data( 'order_id' ) );
|
|
$previewOrderIdInput.val( $( this ).data( 'order_id' ) ).trigger( 'change' );
|
|
$( this ).closest( 'div' ).hide(); // hide results div
|
|
$( this ).closest( 'div' ).children( 'a' ).remove(); // remove all results
|
|
triggerPreview();
|
|
} );
|
|
|
|
// Check for settings change
|
|
$( document ).on( 'keyup paste', '#wpo-wcpdf-settings input, #wpo-wcpdf-settings textarea', settingsChanged );
|
|
$( document ).on( 'change', '#wpo-wcpdf-settings input[type="checkbox"], #wpo-wcpdf-settings input[type="radio"], #wpo-wcpdf-settings select', function( event ) {
|
|
if ( 'shop_address_country' === event.target.id || ! event.isTrigger ) { // exclude programmatic triggers that aren't actually changing anything
|
|
settingsChanged( event );
|
|
}
|
|
} );
|
|
$( document ).on( 'select2:select select2:unselect', '#wpo-wcpdf-settings select.wc-enhanced-select', settingsChanged );
|
|
$( document.body ).on( 'wpo-wcpdf-media-upload-setting-updated', settingsChanged );
|
|
$( document ).on( 'click', '.wpo_remove_image_button, #wpo-wcpdf-settings .remove-requirement', settingsChanged );
|
|
|
|
// On Multilingual
|
|
if ( $( '#wpo_wcpdf_settings_general-shop_address_country-translations' ).length > 0 ) {
|
|
$( '#wpo-wcpdf-settings select[name^="wpo_wcpdf_settings_general[shop_address_country]"]' ).each( function() {
|
|
const $select = $( this );
|
|
if ( $select.val() ) {
|
|
shopCountryChanged( $select );
|
|
}
|
|
} );
|
|
}
|
|
|
|
function settingsChanged( event, previewDelay ) {
|
|
if ( 'shop_address_country' === event.target.id ) {
|
|
shopCountryChanged( $( event.target ) );
|
|
}
|
|
|
|
// Show secondary save button
|
|
showSaveBtn();
|
|
|
|
// Check if preview needs to reload and with what delay
|
|
let $element = $( event.target );
|
|
|
|
if ( ! settingIsExcludedForPreview( $element.attr('name') ) ) {
|
|
|
|
if ( $element.hasClass( 'remove-requirement' ) || $element.attr('id') == 'disable_for' ) {
|
|
return;
|
|
}
|
|
|
|
if ( $.inArray( event.type, ['keyup', 'paste'] ) !== -1 ) {
|
|
if ( $element.is( 'input[type="checkbox"], select' ) ) {
|
|
return;
|
|
} else {
|
|
previewDelay = event.type == 'keyup' ? 1000 : 0;
|
|
}
|
|
}
|
|
|
|
triggerPreview( previewDelay );
|
|
}
|
|
}
|
|
|
|
function shopCountryChanged( $countryField ) {
|
|
const selectedCountry = $countryField.val();
|
|
const $form = $countryField.closest( 'form' );
|
|
|
|
// Get the language key
|
|
const nameMatch = $countryField.attr( 'name' )
|
|
.match( /\[shop_address_country]\[(.*?)\]/ ); // 'pt-pt', 'default', etc.
|
|
const lang = nameMatch ? nameMatch[1] : 'default';
|
|
|
|
// Find the matching state field for that language
|
|
const $state = $form.find( `select[name="wpo_wcpdf_settings_general[shop_address_state][${lang}]"]` );
|
|
|
|
// Keep the original button lookup, but relative to $state
|
|
const $state_sync_button = $state
|
|
.closest( '.wpo-wcpdf-input-wrapper' )
|
|
.find( '#shop_address_state_action' );
|
|
|
|
// Clear previous states
|
|
$state.empty().prop( 'disabled', true );
|
|
$state_sync_button.prop( 'disabled', true );
|
|
|
|
// Temporary loading option
|
|
$state.append(
|
|
$( '<option>', {
|
|
value: '',
|
|
text: wpo_wcpdf_admin.shop_country_changed_messages.loading
|
|
} )
|
|
);
|
|
|
|
return $.ajax( {
|
|
url: wpo_wcpdf_admin.ajaxurl,
|
|
type: 'POST',
|
|
dataType: 'json',
|
|
data: {
|
|
action: 'wcpdf_get_country_states',
|
|
country: selectedCountry,
|
|
security: wpo_wcpdf_admin.nonce,
|
|
},
|
|
success: function( response ) {
|
|
$state.empty();
|
|
|
|
const states = response.data?.states;
|
|
const selected = response.data?.selected;
|
|
|
|
if ( response.success && states && Object.keys( states ).length > 0 ) {
|
|
$.each( states, function( code, name ) {
|
|
$state.append(
|
|
$( '<option>', {
|
|
value: code,
|
|
text: name,
|
|
selected: code === selected
|
|
} )
|
|
);
|
|
} );
|
|
$state.prop( 'disabled', false );
|
|
$state_sync_button.prop( 'disabled', false );
|
|
} else {
|
|
$state.append(
|
|
$( '<option>', {
|
|
value: '',
|
|
text: wpo_wcpdf_admin.shop_country_changed_messages.empty
|
|
} )
|
|
);
|
|
}
|
|
|
|
triggerPreview();
|
|
},
|
|
error: function() {
|
|
$state.empty().append(
|
|
$( '<option>', {
|
|
value: '',
|
|
text: wpo_wcpdf_admin.shop_country_changed_messages.error
|
|
} )
|
|
);
|
|
|
|
triggerPreview();
|
|
}
|
|
} );
|
|
}
|
|
|
|
function showSaveBtn( event ) {
|
|
$( '.preview-data-wrapper .save-settings p' ).css( 'margin-right', '0' );
|
|
}
|
|
|
|
// Submit settings form when clicking on secondary save button
|
|
$( document.body ).on( 'click', '.preview-data-wrapper .save-settings p input', function( event ) {
|
|
$( '#wpo-wcpdf-settings input#submit' ).trigger( 'click' );
|
|
} );
|
|
|
|
// Trigger the Preview
|
|
function triggerPreview( timeoutDuration = 0 ) {
|
|
$previewStates = $( '#wpo-wcpdf-preview-wrapper' ).data( 'preview-states' );
|
|
|
|
// Check if preview is disabled and return
|
|
if ( 'undefined' === $previewStates || 1 === $previewStates ) {
|
|
return;
|
|
}
|
|
|
|
timeoutDuration = typeof timeoutDuration == 'number' ? timeoutDuration : 0;
|
|
|
|
loadPreviewData();
|
|
clearTimeout( previewTimeout );
|
|
previewTimeout = setTimeout( function() { ajaxLoadPreview() }, timeoutDuration );
|
|
}
|
|
|
|
// Settings excluded from trigger the Preview
|
|
function settingIsExcludedForPreview( settingName ) {
|
|
let excluded = false;
|
|
if ( ! settingName ) {
|
|
return excluded;
|
|
}
|
|
let nameKey = settingName.includes( '[' ) ? settingName.match(/\[(.*?)\]/)[1] : settingName;
|
|
if ( $.inArray( nameKey, wpo_wcpdf_admin.preview_excluded_settings ) !== -1 ) {
|
|
excluded = true;
|
|
}
|
|
return excluded;
|
|
}
|
|
|
|
// Clear preview order search results/input
|
|
$( document ).on( 'click', 'img.preview-order-search-clear', function( event ) {
|
|
event.preventDefault();
|
|
$( this ).closest( 'div' ).find( 'input#preview-order-search' ).val( '' );
|
|
$( this ).closest( '.preview-data' ).find( '#preview-order-search-results' ).children( 'a' ).remove(); // remove previous results
|
|
$( this ).closest( '.preview-data' ).find( '#preview-order-search-results' ).children( '.error' ).remove(); // remove previous errors
|
|
$( this ).closest( '.preview-data' ).find( '#preview-order-search-results' ).hide();
|
|
$( this ).hide();
|
|
} );
|
|
|
|
// Trigger preview on document selection and change the document type input with the new value
|
|
$( '#wpo-wcpdf-preview-wrapper ul.preview-data-option-list li' ).on( 'click', function() {
|
|
let inputName = $( this ).closest( 'ul' ).data( 'input-name' );
|
|
let $input = $( '#wpo-wcpdf-preview-wrapper :input[name='+inputName+']');
|
|
$input.val( $( this ).data( 'value' ) ).trigger( 'change' );
|
|
} );
|
|
|
|
// Detect document type input changes and apply the same document title to the document selector
|
|
$previewDocumentTypeInput.on( 'change', function() {
|
|
let inputValue = $( this ).val();
|
|
if ( inputValue.length ) {
|
|
let inputName = $( this ).attr( 'name' );
|
|
let $ul = $( '#wpo-wcpdf-preview-wrapper ul.preview-data-option-list[data-input-name='+inputName+']' );
|
|
let $li = $ul.find( 'li[data-value='+inputValue+']' );
|
|
$ul.parent().find( '.current-label' ).text( $li.text() );
|
|
triggerPreview();
|
|
}
|
|
} ).trigger( 'change' );
|
|
|
|
// Detect order ID input changes
|
|
$previewOrderIdInput.on( 'change', function() {
|
|
triggerPreview();
|
|
} ).trigger( 'change' );
|
|
|
|
// Load the Preview with AJAX
|
|
function ajaxLoadPreview() {
|
|
console.log( 'Loading preview...' );
|
|
let worker = wpo_wcpdf_admin.pdfjs_worker;
|
|
let canvasId = 'preview-canvas';
|
|
let data = {
|
|
action: 'wpo_wcpdf_preview',
|
|
security: previewNonce,
|
|
order_id: previewOrderId,
|
|
document_type: previewDocumentType,
|
|
output_format: previewOutputFormat,
|
|
data: previewSettingsFormData,
|
|
};
|
|
|
|
// remove previous error notices
|
|
$preview.children( '.notice' ).remove();
|
|
|
|
// block ui
|
|
$preview.block( {
|
|
message: null,
|
|
overlayCSS: {
|
|
background: '#fff',
|
|
opacity: 0.6
|
|
}
|
|
} );
|
|
|
|
previewXhr = $.ajax( {
|
|
type: 'POST',
|
|
url: wpo_wcpdf_admin.ajaxurl,
|
|
data: data,
|
|
beforeSend: function( jqXHR, settings ) {
|
|
if ( previewXhr != null ) {
|
|
previewXhr.abort();
|
|
}
|
|
},
|
|
success: function( response, textStatus, jqXHR ) {
|
|
if ( response.data.error ) {
|
|
$( '#' + canvasId ).remove();
|
|
$preview.append( '<div class="notice notice-warning inline"><p>' + response.data.error + '</p></div>' );
|
|
} else if ( response.data.preview_data && response.data.output_format ) {
|
|
$( '#' + canvasId ).remove();
|
|
|
|
switch ( response.data.output_format ) {
|
|
default:
|
|
case 'pdf':
|
|
$preview.append( '<canvas id="' + canvasId + '" style="width:100%;"></canvas>' );
|
|
renderPdf( worker, canvasId, response.data.preview_data );
|
|
break;
|
|
case 'xml': {
|
|
const rawXml = response.data.preview_data;
|
|
|
|
// pretty-print xmlns declarations:
|
|
const pretty = rawXml.replace( /\s+(xmlns(?::[\w.-]+)?=)/g, '\n $1' );
|
|
|
|
// build <pre><code> safely
|
|
const $code = $( '<code>', { class: 'language-xml' } ).text( pretty );
|
|
$preview.empty().append( $( '<pre>' ).append( $code ) );
|
|
|
|
// highlight just this element
|
|
Prism.highlightElement( $code[0] );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$preview.unblock();
|
|
},
|
|
error: function( jqXHR, textStatus, errorThrown ) {
|
|
if ( textStatus != 'abort' ) {
|
|
let errorMessage = jqXHR.status + ': ' + jqXHR.statusText
|
|
$( '#' + canvasId ).remove();
|
|
$preview.append( '<div class="notice notice-warning inline"><p>' + errorMessage + '</p></div>' );
|
|
$preview.unblock();
|
|
}
|
|
},
|
|
} );
|
|
}
|
|
|
|
// pdf_js (third party library code)
|
|
function renderPdf( worker, canvasId, pdfData ) {
|
|
// atob() is used to convert base64 encoded PDF to binary-like data.
|
|
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding.)
|
|
pdfData = window.atob( pdfData );
|
|
|
|
// The workerSrc property shall be specified.
|
|
pdfjsLib.GlobalWorkerOptions.workerSrc = worker;
|
|
|
|
// Using DocumentInitParameters object to load binary data.
|
|
let loadingTask = pdfjsLib.getDocument( { data: pdfData } );
|
|
loadingTask.promise.then( function( pdf ) {
|
|
// Fetch the first page
|
|
let pageNumber = 1;
|
|
pdf.getPage( pageNumber ).then( function( page ) {
|
|
let scale = 2;
|
|
let viewport = page.getViewport( { scale: scale } );
|
|
|
|
// Prepare canvas using PDF page dimensions
|
|
let canvas = document.getElementById( canvasId );
|
|
let context = canvas.getContext( '2d' );
|
|
|
|
canvas.height = viewport.height;
|
|
canvas.width = viewport.width;
|
|
|
|
// Render PDF page into canvas context
|
|
let renderContext = {
|
|
canvasContext: context,
|
|
viewport: viewport
|
|
};
|
|
let renderTask = page.render( renderContext );
|
|
renderTask.promise.then( function() {
|
|
// page rendered
|
|
} );
|
|
} );
|
|
}, function( reason ) {
|
|
// PDF loading error
|
|
console.error( reason );
|
|
} );
|
|
}
|
|
|
|
// Preview on user input
|
|
$( '#preview-order-search' ).on( 'keyup paste', function( event ) {
|
|
let $elem = $( this );
|
|
$elem.addClass( 'ajax-waiting' );
|
|
let duration = event.type == 'keyup' ? 1000 : 0;
|
|
loadPreviewData();
|
|
clearTimeout( previewSearchTimeout );
|
|
previewSearchTimeout = setTimeout( function() { previewOrderSearch( $elem ) }, duration );
|
|
} );
|
|
|
|
// Preview order search
|
|
function previewOrderSearch( $elem ) {
|
|
let $div = $elem.closest( '.preview-data' ).find( '#preview-order-search-results' );
|
|
let value = $elem.val();
|
|
let nonce = $elem.data( 'nonce' );
|
|
let action = 'wpo_wcpdf_preview_order_search';
|
|
|
|
let data = {
|
|
security: nonce,
|
|
action: action,
|
|
search: value,
|
|
document_type: previewDocumentType,
|
|
};
|
|
|
|
$div.parent().find( 'img.preview-order-search-clear' ).hide(); // hide the clear button
|
|
$div.children( '.error' ).remove(); // remove previous errors
|
|
$div.children( 'a' ).remove(); // remove previous results
|
|
$div.hide(); // hide search results
|
|
|
|
$.ajax( {
|
|
type: 'POST',
|
|
url: wpo_wcpdf_admin.ajaxurl,
|
|
data: data,
|
|
success: function( response ) {
|
|
if ( response.data ) {
|
|
if ( response.data.error ) {
|
|
$div.append( '<span class="error">'+response.data.error+'</span>' );
|
|
$div.show();
|
|
} else {
|
|
$.each( response.data, function( i, item ) {
|
|
let firstLine = '<a data-order_id="'+i+'"><span class="order-number">#'+item.order_number+'</span> - '+item.billing_first_name+' '+item.billing_last_name;
|
|
if ( item.billing_company.length > 0 ) {
|
|
firstLine = firstLine+', '+item.billing_company;
|
|
}
|
|
let secondLine = '<br><span class="date">'+item.date_created+'</span><span class="total">'+item.total+'</span></a>';
|
|
$div.append( firstLine+secondLine );
|
|
$div.show();
|
|
} );
|
|
}
|
|
}
|
|
|
|
$elem.removeClass( 'ajax-waiting' );
|
|
$elem.closest( 'div' ).find( 'img.preview-order-search-clear' ).show();
|
|
}
|
|
} );
|
|
}
|
|
|
|
//----------> /Preview <----------//
|
|
//----------> Settings Accordion <----------//
|
|
|
|
function settingsAccordion() {
|
|
// Get current tab.
|
|
const params = new URLSearchParams( window.location.search );
|
|
const allowedTabs = [ 'general', 'documents', 'debug' ];
|
|
const tab = params.get( 'tab' ) || 'general';
|
|
|
|
if ( ! allowedTabs.includes( tab ) ) {
|
|
return;
|
|
}
|
|
|
|
const tabsMainCategory = {
|
|
general : 'display',
|
|
documents : 'general',
|
|
debug : 'filesystem_access' // Default open section for Advanced/Debug tab
|
|
};
|
|
|
|
const sections = $( '.settings_category h2' );
|
|
|
|
if ( sections.length === 0 ) {
|
|
return; // No sections found
|
|
}
|
|
|
|
// Accessibility attributes for accordion headers and panels
|
|
sections.each( function ( index ) {
|
|
const $header = $( this );
|
|
const $panel = $header.next( '.form-table' );
|
|
const $category = $header.parent( '.settings_category' );
|
|
const idBase = $category.attr( 'id' ) || $header.attr( 'id' ) || `wcpdf_${tab}_section_${index}`;
|
|
|
|
// Ensure header has an id and compute explicit ids
|
|
if ( ! $header.attr( 'id' ) ) {
|
|
$header.attr( 'id', `${idBase}_header` );
|
|
}
|
|
const headerElementId = $header.attr( 'id' );
|
|
const panelId = `${idBase}_panel`;
|
|
|
|
$header.attr( {
|
|
'role': 'button',
|
|
'tabindex': 0,
|
|
'aria-controls': panelId
|
|
} );
|
|
|
|
$panel.attr( {
|
|
'id': panelId,
|
|
'role': 'region',
|
|
'aria-labelledby': headerElementId
|
|
} );
|
|
} );
|
|
|
|
// Initialize accordion state
|
|
sections.each( function ( index ) {
|
|
const $header = $( this );
|
|
const $category = $header.parent( '.settings_category' );
|
|
const categoryId = $category.attr( 'id' ) || `wcpdf_${tab}_section_${index}`;
|
|
const $panel = $header.next( '.form-table' );
|
|
|
|
// Check localStorage for saved state
|
|
const stored = localStorage.getItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}` );
|
|
let shouldOpen = false;
|
|
|
|
if ( stored !== null ) {
|
|
// User has previously interacted with this section - use saved state
|
|
shouldOpen = stored === 'true';
|
|
} else if ( tabsMainCategory[ tab ] && categoryId === tabsMainCategory[ tab ] ) {
|
|
// First visit - open the default main category for this tab
|
|
shouldOpen = true;
|
|
}
|
|
// else: keep collapsed (shouldOpen = false)
|
|
|
|
// Set initial state
|
|
if ( shouldOpen ) {
|
|
$header.addClass( 'active' ).attr( 'aria-expanded', true );
|
|
$panel.show().attr( 'aria-hidden', 'false' );
|
|
} else {
|
|
$header.removeClass( 'active' ).attr( 'aria-expanded', false );
|
|
$panel.hide().attr( 'aria-hidden', 'true' );
|
|
}
|
|
} );
|
|
|
|
// Toggle section on click
|
|
function toggleSection( header ) {
|
|
const $header = $( header );
|
|
const categoryId = $header.parent( '.settings_category' ).attr( 'id' );
|
|
const $panel = $header.next( '.form-table' );
|
|
const willOpen = ! $panel.is( ':visible' );
|
|
|
|
$header.toggleClass( 'active', willOpen ).attr( 'aria-expanded', willOpen );
|
|
|
|
$panel.stop( true, false ).slideToggle( {
|
|
duration: 300,
|
|
easing: 'swing',
|
|
complete: function () {
|
|
const isVisible = $( this ).is( ':visible' );
|
|
$( this ).attr( 'aria-hidden', isVisible ? 'false' : 'true' );
|
|
if ( categoryId ) {
|
|
localStorage.setItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}`, isVisible );
|
|
}
|
|
}
|
|
} );
|
|
}
|
|
|
|
// Bind click events
|
|
sections.off( 'click' ).on( 'click', function () {
|
|
toggleSection( this );
|
|
} );
|
|
|
|
// Keyboard accessibility
|
|
sections.off( 'keydown' ).on( 'keydown', function ( e ) {
|
|
if ( e.key === 'Enter' || e.key === ' ' ) {
|
|
e.preventDefault();
|
|
toggleSection( this );
|
|
}
|
|
} );
|
|
}
|
|
|
|
// Initialize accordion
|
|
settingsAccordion();
|
|
//----------> /Settings Accordion <----------//
|
|
|
|
//----------> Conditional Visibility <----------//
|
|
const bound = new Set();
|
|
|
|
$( '[data-show_for_option_name]' ).each( function () {
|
|
const opt = $( this ).data( 'show_for_option_name' );
|
|
if ( bound.has( opt ) ) {
|
|
return;
|
|
}
|
|
|
|
$( document ).on( 'change', `[name="${opt}"], [name="${opt}[]"]`, toggle_conditional_visibility );
|
|
$( `[name="${opt}"], [name="${opt}[]"]` ).each( function () {
|
|
toggle_conditional_visibility( { target: this } );
|
|
} );
|
|
bound.add( opt );
|
|
} );
|
|
|
|
function toggle_conditional_visibility( e ) {
|
|
const $this = $( e.target );
|
|
let name = $this.prop( 'name' ).replace( '[]', '' ); // normalize multiselect
|
|
let value = $this.val();
|
|
let checkbox = false;
|
|
|
|
if ( $this.is( ':checkbox' ) ) {
|
|
value = $this.is( ':checked' );
|
|
checkbox = true;
|
|
}
|
|
|
|
$( "[data-show_for_option_name='" + name + "']" ).each( function() {
|
|
let show = false;
|
|
let show_for = $( this ).data( 'show_for_option_values' );
|
|
let keep_value = $( this ).data( 'keep_current_value' );
|
|
|
|
if ( checkbox ) {
|
|
show = value; // for checkboxes, checked = show
|
|
} else if ( Array.isArray( value ) ) { // Multiselect
|
|
show = value.some( item => show_for.includes( item ) );
|
|
} else {
|
|
show = show_for.includes( value );
|
|
}
|
|
|
|
let $row = $( this ).closest( 'tr' );
|
|
|
|
if ( show ) {
|
|
$row.show();
|
|
|
|
if ( checkbox ) {
|
|
$row.find( ':input[type=checkbox]' ).val( '1' );
|
|
}
|
|
} else {
|
|
$row.hide()
|
|
.find( ':input' ).each( function () {
|
|
const $input = $( this );
|
|
|
|
// Don't reset value
|
|
if ( keep_value ) {
|
|
return;
|
|
}
|
|
|
|
// Reset the input value
|
|
if ( $input.is( 'select' ) ) {
|
|
if ( $input.prop( 'multiple' ) ) {
|
|
$input.val( [] );
|
|
} else {
|
|
$input.prop( 'selectedIndex', 0 );
|
|
}
|
|
} else if ( $input.is( ':checkbox' ) ) {
|
|
$input.prop( 'checked', false );
|
|
} else {
|
|
$input.val( '' );
|
|
}
|
|
|
|
$input.trigger( 'change' );
|
|
} );
|
|
}
|
|
} );
|
|
}
|
|
//----------> /Conditional Visibility <----------//
|
|
|
|
//----------> Sync Address <----------//
|
|
|
|
$( '#wpo-wcpdf-settings .sync-address' ).on( 'click', function( event ) {
|
|
event.preventDefault();
|
|
|
|
const $button = $( this );
|
|
const $form = $( this ).closest('form');
|
|
const $icon = $button.find( 'span.dashicons' );
|
|
const $tooltip = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( '.sync-tooltip' );
|
|
let $field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'input' );
|
|
|
|
if ( $field.length === 0 ) {
|
|
$field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'select' );
|
|
}
|
|
|
|
// Rotate the icon to indicate processing.
|
|
$icon.toggleClass( 'rotate' );
|
|
|
|
$.ajax( {
|
|
type: 'POST',
|
|
url: wpo_wcpdf_admin.ajaxurl,
|
|
data: {
|
|
action: 'wpo_wcpdf_sync_address',
|
|
security: wpo_wcpdf_admin.nonce,
|
|
address_field: $field.attr( 'id' ),
|
|
},
|
|
success: function( response ) {
|
|
if ( response.success && response.data.value && '' !== response.data.value.trim() ) {
|
|
if ( 'shop_address_country' === $field.attr( 'id' ) ) {
|
|
const country_state = response.data.value.split( ':' );
|
|
$field.val( country_state[0] );
|
|
|
|
// Update states if the country changed.
|
|
shopCountryChanged( $field ).done( function() {
|
|
const matches = $field.attr( 'name' ).match( /\[([^\]]+)\]/g ); // matches all bracket parts
|
|
const lang = matches ? matches[ matches.length - 1 ].replace( /[\[\]]/g, '' ) : 'default';
|
|
const $stateField = $form.find( `select[name="wpo_wcpdf_settings_general[shop_address_state][${lang}]"]` );
|
|
|
|
// Update the selected state.
|
|
if ( $stateField.length !== 0 ) {
|
|
$stateField.val( country_state[1] );
|
|
}
|
|
} );
|
|
} else {
|
|
$field.val( response.data.value );
|
|
}
|
|
|
|
triggerPreview();
|
|
} else if ( ! response.success && response.data.message && '' !== response.data.message.trim() ) {
|
|
$tooltip.text( response.data.message ).addClass( 'visible' );
|
|
setTimeout( function() {
|
|
$tooltip.removeClass( 'visible' );
|
|
}, 3000 );
|
|
}
|
|
},
|
|
complete: function() {
|
|
// Reset the icon rotation.
|
|
$icon.toggleClass( 'rotate' );
|
|
}
|
|
} );
|
|
|
|
} );
|
|
|
|
//----------> /Sync Address <----------//
|
|
|
|
} );
|