# easy-invoice/2.2.0/assets/js/settings.js

Easy Invoice – Invoice Generator, PDF Quotes &amp; Payments, version 2.2.0. 631 lines.

- Page: https://pluginprobe.com/plugins/easy-invoice/2.2.0/code/assets/js/settings.js
- Raw: https://pluginprobe.com/plugins/easy-invoice/2.2.0/raw/assets/js/settings.js
- Modified: 2025-10-05T13:12:30+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/easy-invoice/2.2.0/code/assets/js/settings.js#L10-L20`.

```javascript
jQuery(function($) {
    // Add CSS for drag and drop functionality
    $('<style>')
        .prop('type', 'text/css')
        .html(`
            .gateway-handle {
                cursor: move;
                transition: color 0.2s ease;
            }
            .gateway-handle:hover {
                color: #6b7280 !important;
            }
            .gateway-item.dragging {
                opacity: 0.8;
                transform: rotate(2deg);
                box-shadow: 0 10px 25px rgba(0,0,0,0.15);
                z-index: 1000;
            }
            .gateway-item-placeholder {
                background: #f3f4f6;
                border: 2px dashed #d1d5db;
                border-radius: 0.5rem;
                height: 6rem;
                margin: 1.25rem 0;
            }
            body.dragging-gateway .gateway-item:not(.dragging) {
                transition: transform 0.2s ease;
            }
            body.dragging-gateway .gateway-item:not(.dragging):hover {
                transform: translateY(-2px);
            }
        `)
        .appendTo('head');
    
    
    // Initialize Select2 for multiselect fields if Select2 is available
    function initializeSelect2() {
        if ($.fn.select2) {
            $('select[multiple="multiple"]').each(function() {
                if (!$(this).hasClass('select2-hidden-accessible')) {
                    
                    $(this).select2({
                        width: '100%',
                        placeholder: $(this).attr('placeholder') || 'Select options',
                        closeOnSelect: false,
                        allowClear: true
                    });
                }
            });
        }
    }
    
    // Initialize Select2 on page load
    initializeSelect2();
    
    // Reinitialize Select2 after settings save
    $(document).on('settingsSaved', function() {
        setTimeout(function() {
            initializeSelect2();
        }, 500);
    });

    // Make gateways sortable
    if ($("#sortable-gateways").length) {
        $("#sortable-gateways").sortable({
            handle: ".gateway-handle",
            axis: "y",
            placeholder: "gateway-item-placeholder bg-gray-100 border-2 border-dashed border-gray-300 rounded-lg h-24",
            tolerance: "pointer",
            opacity: 0.8,
            update: function(event, ui) {
                // Update the order inputs when items are reordered
                $('#sortable-gateways .gateway-item').each(function(index) {
                    $(this).find('input.gateway-order-input').val($(this).data('gateway-id'));
                });
                
                // Show a subtle indication that order was updated
                if (typeof EasyInvoiceToast !== 'undefined') {
                    EasyInvoiceToast.info('Payment method order updated. Save settings to apply changes.', { duration: 3000 });
                }
            },
            start: function(event, ui) {
                ui.item.addClass('dragging');
                $('body').addClass('dragging-gateway');
            },
            stop: function(event, ui) {
                ui.item.removeClass('dragging');
                $('body').removeClass('dragging-gateway');
            }
        }).disableSelection();
    }

    // Toggle gateway settings visibility based on checkbox
    $('#settings-form').on('change', '.gateway-enable-checkbox', function() {
        var settingsDiv = $(this).closest('.gateway-item').find('.gateway-settings');
        if ($(this).is(':checked')) {
            settingsDiv.removeClass('hidden');
        } else {
            settingsDiv.addClass('hidden');
        }
    });

    // Initialize gateway settings visibility on page load
    $('.gateway-enable-checkbox').each(function() {
        var settingsDiv = $(this).closest('.gateway-item').find('.gateway-settings');
        if ($(this).is(':checked')) {
            settingsDiv.removeClass('hidden');
        } else {
            settingsDiv.addClass('hidden');
        }
    });

    // Generic function to handle all conditional fields
    function updateConditionalFields() {
        $('.conditional-field').each(function() {
            const field = $(this);
            let shouldShow = true;
            
            // Check all dependencies
            field.find('.depends-on-*').each(function() {
                const className = $(this).attr('class');
                const matches = className.match(/depends-on-([^-]+)-([^-]+)/);
                if (matches) {
                    const dependsKey = matches[1];
                    const dependsValue = matches[2];
                    const dependsField = $('select[name="settings[' + dependsKey + ']"], input[name="settings[' + dependsKey + ']"]');
                    
                    if (dependsField.length && dependsField.val() !== dependsValue) {
                        shouldShow = false;
                    }
                }
            });
            
            if (shouldShow) {
                field.removeClass('hidden');
            } else {
                field.addClass('hidden');
            }
        });
    }

    // Initialize conditional field visibility on page load
    updateConditionalFields();

    // Update fields when any dependency field changes
    $(document).on('change', 'select[name*="settings["], input[name*="settings["]', function() {
        updateConditionalFields();
    });

    // Handle logo upload
    $('.upload-logo-button').on('click', function(e) {
        e.preventDefault();

        
        const button = $(this);
        const fieldId = button.attr('id').replace('upload_image_button_', '');
        const previewId = '#' + fieldId + '-preview';
        const inputId = '#' + fieldId;
        

        
        if (typeof wp === 'undefined' || typeof wp.media === 'undefined') {
            console.error('WordPress media library not loaded');
            if (typeof EasyInvoiceToast !== 'undefined') {
                EasyInvoiceToast.show('error', 'Media library not available. Please refresh the page and try again.');
            }
            return;
        }
        
        const frame = wp.media({
            title: 'Select Company Logo',
            button: { text: 'Use this logo' },
            multiple: false
        });
        
        frame.on('select', function() {
            const attachment = frame.state().get('selection').first().toJSON();
            $(previewId).attr('src', attachment.url).removeClass('hidden');
            $(inputId).val(attachment.url);
        });
        
        frame.open();
    });

    // Handle form submission
    $('#save-settings, #save-settings-bottom').on('click', function(e) {
        e.preventDefault();
        const button = $(this);
        const originalText = button.html();
        
        // Sync wp_editor content before submission
        if (typeof tinyMCE !== 'undefined') {
            tinyMCE.triggerSave();
        }
        
        button.prop('disabled', true)
            .html('<i class="fas fa-spinner fa-spin mr-2"></i>Saving...');
        const formData = new FormData($('#settings-form')[0]);
        formData.append('action', 'easy_invoice_save_settings');
        formData.append('nonce', easyInvoiceSettings.nonce);
        if (!$('input[name="settings[easy_invoice_payment_methods][]"]:checked').length) {
            formData.append('settings[easy_invoice_payment_methods]', '');
        }

        
        $.ajax({
            url: easyInvoiceSettings.ajaxurl,
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: function(response) {
                
                if (response.success) {
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.success('Settings saved successfully');
                    } else {
                        // Simple fallback if toast system is not available
                        alert('Settings saved successfully');
                    }
                    
                    // Trigger settingsSaved event to reinitialize Select2
                    $(document).trigger('settingsSaved');
                } else {
                    // Check for error message in different possible locations
                    let errorMessage = 'Error saving settings';
                    if (response.message) {
                        errorMessage = response.message;
                    } else if (response.data && response.data.message) {
                        errorMessage = response.data.message;
                    }
                    
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.error(errorMessage);
                    } else {
                        alert(errorMessage);
                    }
                }
                button.prop('disabled', false).html(originalText);
            },
            error: function(xhr, status, error) {
                console.error('Settings save AJAX error:', {xhr, status, error});
                
                let errorMessage = 'Error saving settings';
                if (xhr.responseJSON && xhr.responseJSON.message) {
                    errorMessage = xhr.responseJSON.message;
                } else if (xhr.responseText) {
                    try {
                        const response = JSON.parse(xhr.responseText);
                        if (response.message) {
                            errorMessage = response.message;
                        }
                    } catch (e) {
                        console.error('Failed to parse error response:', e);
                    }
                }
                
                if (typeof EasyInvoiceToast !== 'undefined') {
                    EasyInvoiceToast.error(errorMessage);
                } else {
                    alert(errorMessage);
                }
                button.prop('disabled', false).html(originalText);
            }
        });
    });

    // Handle regenerate quote numbers functionality
    $(document).on('click', '.regenerate-quote-numbers-button', function(e) {
        e.preventDefault();
        const button = $(this);
        const originalText = button.html();
        
        // Check if EasyInvoiceConfirmation is available
        if (typeof EasyInvoiceConfirmation !== 'undefined' && EasyInvoiceConfirmation.confirmAction) {
            
            try {
                EasyInvoiceConfirmation.confirmAction(
                    'regenerate',
                    'all quote numbers',
                    function() {
                        // User confirmed, proceed with regeneration
                        performQuoteRegeneration(button, originalText);
                    }
                );
            } catch (error) {
                console.error('Error calling EasyInvoiceConfirmation.confirmAction:', error);
            }
        } else {
            // Fallback to browser confirm
            if (confirm('This will regenerate all quote numbers starting from the Next Quote Number. This action cannot be undone. Are you sure you want to continue?')) {
                performQuoteRegeneration(button, originalText);
            }
        }
    });

    function performQuoteRegeneration(button, originalText) {
        button.prop('disabled', true).html('Regenerating...');

        $.ajax({
            url: easyInvoiceSettings.ajaxurl,
            type: 'POST',
            data: {
                action: 'regenerate_quote_numbers',
                nonce: easyInvoiceSettings.nonce,
                easy_invoice_settings_nonce: $('input[name="easy_invoice_settings_nonce"]').val()
            },
            success: function(response) {
                if (response.success) {
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.success(response.data.message || 'Quote numbers regenerated successfully');
                    } else {
                        alert(response.data.message || 'Quote numbers regenerated successfully');
                    }
                    
                    // Update the Next Quote Number field if provided
                    if (response.data.next_number) {
                        $('input[name="settings[easy_invoice_next_quote_number]"]').val(response.data.next_number);
                    }
                    
                    // Reload the page after a short delay to show the updated numbers
                    setTimeout(function() {
                        location.reload();
                    }, 2000);
                } else {
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.error(response.data.message || 'Failed to regenerate quote numbers');
                    } else {
                        alert(response.data.message || 'Failed to regenerate quote numbers');
                    }
                }
                button.prop('disabled', false).html(originalText);
            },
            error: function(xhr, status, error) {
                console.error('AJAX Error:', error);
                console.error('Status:', status);
                console.error('Response:', xhr.responseText);
                if (typeof EasyInvoiceToast !== 'undefined') {
                    EasyInvoiceToast.error('Failed to regenerate quote numbers. Please try again.');
                } else {
                    alert('Failed to regenerate quote numbers. Please try again.');
                }
                button.prop('disabled', false).html(originalText);
            }
        });
    }

    // Handle test email functionality
    $(document).on('click', '.test-email-button', function(e) {
        e.preventDefault();
        const button = $(this);
        const originalText = button.html();
        const emailInput = button.closest('.mt-1').find('input[type="email"]');
        const resultDiv = button.closest('.mt-1').find('[id$="_result"]');
        const testEmail = emailInput.val().trim();

        if (!testEmail) {
            if (typeof EasyInvoiceToast !== 'undefined') {
                EasyInvoiceToast.show('error', 'Please enter a valid email address');
            }
            return;
        }

        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(testEmail)) {
            if (typeof EasyInvoiceToast !== 'undefined') {
                EasyInvoiceToast.show('error', 'Please enter a valid email address');
            }
            return;
        }

        button.prop('disabled', true)
            .html('<i class="fas fa-spinner fa-spin mr-2"></i>Sending...');

        $.ajax({
            url: easyInvoiceSettings.ajaxurl,
            type: 'POST',
            data: {
                action: 'easy_invoice_test_email',
                test_email: testEmail,
                nonce: easyInvoiceSettings.nonce
            },
            success: function(response) {
                if (response.success) {
                    resultDiv.html('<div class="text-green-600 text-sm"><i class="fas fa-check-circle mr-1"></i>' + response.data.message + '</div>')
                        .show();
                } else {
                    resultDiv.html('<div class="text-red-600 text-sm"><i class="fas fa-exclamation-circle mr-1"></i>' + (response.data && response.data.message ? response.data.message : 'Failed to send test email') + '</div>')
                        .show();
                }
                button.prop('disabled', false).html(originalText);
                
                // Hide result after 5 seconds
                setTimeout(function() {
                    resultDiv.fadeOut();
                }, 5000);
            },
            error: function() {
                resultDiv.html('<div class="text-red-600 text-sm"><i class="fas fa-exclamation-circle mr-1"></i>Error sending test email</div>')
                    .show();
                button.prop('disabled', false).html(originalText);
                
                // Hide result after 5 seconds
                setTimeout(function() {
                    resultDiv.fadeOut();
                }, 5000);
            }
        });
    });

    // Handle test template email functionality
    $(document).on('click', '.test-template-email-button', function(e) {
        e.preventDefault();
        const button = $(this);
        const originalText = button.html();
        const emailInput = button.closest('.mt-1').find('input[type="email"]');
        const resultDiv = button.closest('.mt-1').find('[id$="_result"]');
        const testEmail = emailInput.val().trim();
        const templateType = button.data('template-type');

        if (!testEmail) {
            if (typeof EasyInvoiceToast !== 'undefined') {
                EasyInvoiceToast.show('error', 'Please enter a valid email address');
            }
            return;
        }

        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(testEmail)) {
            if (typeof EasyInvoiceToast !== 'undefined') {
                EasyInvoiceToast.show('error', 'Please enter a valid email address');
            }
            return;
        }

        button.prop('disabled', true)
            .html('<i class="fas fa-spinner fa-spin mr-2"></i>Testing...');

        $.ajax({
            url: easyInvoiceSettings.ajaxurl,
            type: 'POST',
            data: {
                action: 'easy_invoice_test_template_email',
                test_email: testEmail,
                template_type: templateType,
                nonce: easyInvoiceSettings.nonce
            },
            success: function(response) {
                if (response.success) {
                    resultDiv.html('<div class="text-green-600 text-sm"><i class="fas fa-check-circle mr-1"></i>' + response.data.message + '</div>')
                        .show();
                } else {
                    resultDiv.html('<div class="text-red-600 text-sm"><i class="fas fa-exclamation-circle mr-1"></i>' + (response.data && response.data.message ? response.data.message : 'Failed to send template test email') + '</div>')
                        .show();
                }
                button.prop('disabled', false).html(originalText);
                
                // Hide result after 5 seconds
                setTimeout(function() {
                    resultDiv.fadeOut();
                }, 5000);
            },
            error: function() {
                resultDiv.html('<div class="text-red-600 text-sm"><i class="fas fa-exclamation-circle mr-1"></i>Error sending template test email</div>')
                    .show();
                button.prop('disabled', false).html(originalText);
                
                // Hide result after 5 seconds
                setTimeout(function() {
                    resultDiv.fadeOut();
                }, 5000);
            }
        });
    });

    // Handle test payment reminder email functionality
    $(document).on('click', '.test-payment-reminder-email-button', function(e) {
        e.preventDefault();
        const button = $(this);
        const originalText = button.html();
        const emailInput = button.closest('.mt-1').find('input[type="email"]');
        const resultDiv = button.closest('.mt-1').find('[id$="_result"]');
        const testEmail = emailInput.val().trim();

        if (!testEmail) {
            if (typeof EasyInvoiceToast !== 'undefined') {
                EasyInvoiceToast.show('error', 'Please enter a valid email address');
            }
            return;
        }

        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(testEmail)) {
            if (typeof EasyInvoiceToast !== 'undefined') {
                EasyInvoiceToast.show('error', 'Please enter a valid email address');
            }
            return;
        }

        button.prop('disabled', true)
            .html('<i class="fas fa-spinner fa-spin mr-2"></i>Testing...');

        $.ajax({
            url: easyInvoiceSettings.ajaxurl,
            type: 'POST',
            data: {
                action: 'easy_invoice_test_payment_reminder_email',
                test_email: testEmail,
                nonce: easyInvoiceSettings.nonce
            },
            success: function(response) {
                if (response.success) {
                    resultDiv.html('<div class="text-green-600 text-sm"><i class="fas fa-check-circle mr-1"></i>' + response.data.message + '</div>')
                        .show();
                } else {
                    resultDiv.html('<div class="text-red-600 text-sm"><i class="fas fa-exclamation-circle mr-1"></i>' + (response.data && response.data.message ? response.data.message : 'Failed to send test payment reminder email') + '</div>')
                        .show();
                }
                button.prop('disabled', false).html(originalText);
                
                // Hide result after 5 seconds
                setTimeout(function() {
                    resultDiv.fadeOut();
                }, 5000);
            },
            error: function() {
                resultDiv.html('<div class="text-red-600 text-sm"><i class="fas fa-exclamation-circle mr-1"></i>Error sending test payment reminder email</div>')
                    .show();
                button.prop('disabled', false).html(originalText);
                
                // Hide result after 5 seconds
                setTimeout(function() {
                    resultDiv.fadeOut();
                }, 5000);
            }
        });
    });

    // Handle regenerate invoice numbers functionality
    $(document).on('click', '.regenerate-invoice-numbers-button', function(e) {
        e.preventDefault();
        const button = $(this);
        const originalText = button.html();
        
        
        // Show confirmation dialog
        if (typeof EasyInvoiceConfirmation !== 'undefined') {
            try {
                EasyInvoiceConfirmation.confirmAction(
                    'regenerate',
                    'all invoice numbers',
                    function() {
                        // User confirmed, proceed with regeneration
                        performInvoiceRegeneration(button, originalText);
                    }
                );
            } catch (error) {
                console.error('Error calling EasyInvoiceConfirmation.confirmAction:', error);
            }
        } else {
            // Fallback to browser confirm
            if (confirm('This will regenerate all invoice numbers starting from the Last Invoice Number. This action cannot be undone. Are you sure you want to continue?')) {
                performInvoiceRegeneration(button, originalText);
            }
        }
    });

    // Function to perform the actual regeneration
    function performInvoiceRegeneration(button, originalText) {
        button.prop('disabled', true)
            .html('<i class="fas fa-spinner fa-spin mr-2"></i>Regenerating...');


        $.ajax({
            url: easyInvoiceSettings.ajaxurl,
            type: 'POST',
            data: {
                action: 'regenerate_invoice_numbers',
                nonce: easyInvoiceSettings.nonce,
                easy_invoice_settings_nonce: $('input[name="easy_invoice_settings_nonce"]').val()
            },
            success: function(response) {
                if (response.success) {
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.success(response.data.message);
                    } else {
                        alert(response.data.message);
                    }
                    
                    // Update the Next Invoice Number field if provided
                    if (response.data.next_number) {
                        $('input[name="settings[easy_invoice_next_invoice_number]"]').val(response.data.next_number);
                    }
                    
                    // Refresh the page to show updated values
                    setTimeout(function() {
                        location.reload();
                    }, 2000);
                } else {
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.error(response.data.message || 'Failed to regenerate invoice numbers');
                    } else {
                        alert(response.data.message || 'Failed to regenerate invoice numbers');
                    }
                }
                button.prop('disabled', false).html(originalText);
            },
            error: function(xhr, status, error) {
                console.error('Invoice regeneration AJAX error:', {xhr, status, error});
                
                let errorMessage = 'Error regenerating invoice numbers';
                if (xhr.responseJSON && xhr.responseJSON.data && xhr.responseJSON.data.message) {
                    errorMessage = xhr.responseJSON.data.message;
                } else if (xhr.responseText) {
                    try {
                        const response = JSON.parse(xhr.responseText);
                        if (response.data && response.data.message) {
                            errorMessage = response.data.message;
                        }
                    } catch (e) {
                        console.error('Failed to parse error response:', e);
                    }
                }
                
                if (typeof EasyInvoiceToast !== 'undefined') {
                    EasyInvoiceToast.error(errorMessage);
                } else {
                    alert(errorMessage);
                }
                button.prop('disabled', false).html(originalText);
            }
        });
    }
}); 
```
