# easy-invoice/2.1.13/assets/js/client-manager.js

Easy Invoice – Invoice Generator, PDF Quotes &amp; Payments, version 2.1.13. 609 lines.

- Page: https://pluginprobe.com/plugins/easy-invoice/2.1.13/code/assets/js/client-manager.js
- Raw: https://pluginprobe.com/plugins/easy-invoice/2.1.13/raw/assets/js/client-manager.js
- Modified: 2025-10-30T12:14:18+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.1.13/code/assets/js/client-manager.js#L10-L20`.

```javascript
/**
 * Easy Invoice - Client Management
 * Handles all client-related functionality including selection, adding new clients, 
 * and managing client data.
 */

(function($) {
    $(document).ready(function() {
        // Store client data in a JavaScript object
        var clientsData = {};
        
        // Load clients data from the global object if available
        function initializeClientData() {
            if (typeof window.easyInvoiceClients !== 'undefined') {
                clientsData = window.easyInvoiceClients;
            }
            
            // Make clientsData available globally
            window.easyInvoiceClients = clientsData;
        }
        
        // Initialize client data
        initializeClientData();
        
        // Handle client selection change
        function setupClientSelection() {
            var isInitialLoad = true; // Flag to prevent AJAX calls on initial load
            
            $("#select-client").on("change", function() {
                var clientId = $(this).val();
                
                // Skip AJAX call if this is the initial load or if we're initializing client
                if (isInitialLoad || (typeof window.isInitializingClient !== 'undefined' && window.isInitializingClient)) {
                    isInitialLoad = false;
                    return;
                }
                
                if (clientId) {
                    // Load client data via AJAX
                    loadClientData(clientId);
                } else {
                    // Clear client display
                    clearClientDisplay();
                }
            });
            
            // Auto-select client if client-id field has a value (for existing invoices)
            var existingClientId = $("#client-id").val();
            if (existingClientId && existingClientId !== '') {
                // Set the dropdown value without triggering change event
                $("#select-client").val(existingClientId);
                
                // Check if we have client data from PHP first
                if (typeof easyInvoice !== 'undefined' && easyInvoice.clientData && easyInvoice.clientData.id == existingClientId) {
                    loadClientDataFromPHP(easyInvoice.clientData);
                }
            }
            
            // Reset the flag after a short delay to allow for user interactions
            setTimeout(function() {
                isInitialLoad = false;
            }, 1000);
        }
        
        // Load client data from PHP (no AJAX needed)
        function loadClientDataFromPHP(clientData) {
            // Set client ID
            $("#client-id").val(clientData.id);
            
            // Update display fields
            $("#display-client-name").text(clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name) || 'N/A');
            $("#display-client-email").text(clientData.email || 'N/A');
            $("#display-client-phone").text(clientData.phone || 'N/A');
            $("#display-client-company").text(clientData.business_client_name || 'N/A');
            $("#display-client-address").text(clientData.address || 'N/A');
            $("#display-client-website").text(clientData.website || 'N/A');
            
            // Show client info display and hide no-client message
            $("#client-info-display").removeClass("hidden");
            $("#no-client-message").addClass("hidden");
            
            // Update the new selected client display
            var clientName = clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name) || 'N/A';
            $("#selected-client-name").text(clientName);
            $("#selected-client-email").text(clientData.email || 'N/A');
            $("#selected-client-display").removeClass("hidden");
            
            // Update the edit client link
            var editUrl = 'admin.php?page=easy-invoice-client-edit&client_id=' + clientData.id;
            $('#edit-selected-client').attr('href', editUrl).removeClass('hidden');

            // Store client data for later use
            clientsData[clientData.id] = {
                name: clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name),
                email: clientData.email,
                phone: clientData.phone,
                address: clientData.address,
                website: clientData.website,
                business_name: clientData.business_client_name,
                first_name: clientData.first_name,
                last_name: clientData.last_name
            };
        }

        // Load client data via AJAX
        function loadClientData(clientId) {
            $.ajax({
                url: easyInvoice.ajaxUrl,
                type: 'POST',
                data: {
                    action: 'easy_invoice_get_client',
                    client_id: clientId,
                    nonce: easyInvoice.nonce
                },
                success: function(response) {
                    if (response.success) {
                        var client = response.data;
                        
                        // Set client ID
                        $("#client-id").val(clientId);
                        
                        // Update display fields
                        $("#display-client-name").text(client.business_client_name || (client.first_name + ' ' + client.last_name) || 'N/A');
                        $("#display-client-email").text(client.email || 'N/A');
                        $("#display-client-phone").text(client.phone || 'N/A');
                        $("#display-client-company").text(client.business_client_name || 'N/A');
                        $("#display-client-address").text(client.address || 'N/A');
                        $("#display-client-website").text(client.website || 'N/A');
                        
                        // Show client info display and hide no-client message
                        $("#client-info-display").removeClass("hidden");
                        $("#no-client-message").addClass("hidden");
                        
                        // Update the new selected client display
                        var clientName = client.business_client_name || (client.first_name + ' ' + client.last_name) || 'N/A';
                        $("#selected-client-name").text(clientName);
                        $("#selected-client-email").text(client.email || 'N/A');
                        $("#selected-client-display").removeClass("hidden");
                        
                        // Update the edit client link
                        var editUrl = 'admin.php?page=easy-invoice-client-edit&client_id=' + clientId;
                        $('#edit-selected-client').attr('href', editUrl).removeClass('hidden');

                        // Store client data for later use
                        clientsData[clientId] = {
                            name: client.business_client_name || (client.first_name + ' ' + client.last_name),
                            email: client.email,
                            phone: client.phone,
                            address: client.address,
                            website: client.website,
                            business_name: client.business_client_name,
                            first_name: client.first_name,
                            last_name: client.last_name
                        };
                    } else {
                        clearClientDisplay();
                    }
                },
                error: function(xhr, status, error) {
                    clearClientDisplay();
                }
            });
        }
        
        // Clear client display
        function clearClientDisplay() {
            $("#client-id").val("");
            $("#display-client-name").text("-");
            $("#display-client-email").text("-");
            $("#display-client-phone").text("-");
            $("#display-client-company").text("-");
            $("#display-client-address").text("-");
            $("#display-client-website").text("-");
            
            $("#client-info-display").addClass("hidden");
            $("#no-client-message").removeClass("hidden");
            $("#selected-client-display").addClass("hidden");
            $("#edit-selected-client").addClass("hidden");
        }
        
        // Clean up existing handlers to prevent duplicates
        function cleanUpExistingHandlers() {
            $("#add-new-client-btn").off("click");
            $(document).off("click", "#add-new-client-btn");
            $(".close-modal").off("click");
            $(document).off("click", ".close-modal");
            $(document).off("click", "#add-save-client-btn");
            $(document).off("click", "#add-cancel-add-client");
        }
        
        // Setup client modal functionality
        function setupClientModal() {
            // Clean up existing handlers first
            cleanUpExistingHandlers();
            
            // Simple function to toggle modal visibility
            function toggleClientModal(show) {
                if (show) {
                    $("#add_client_modal").removeClass("hidden");
                } else {
                    $("#add_client_modal").addClass("hidden");
                    
                    // Reset form when closing
                    $("#add-client-form")[0].reset();
                }
            }
            
            // Simple button click handler
            $(document).on("click", "#add-new-client-btn", function(e) {
                e.preventDefault();
                e.stopPropagation();
                
                // Simple modal show
                $("#add_client_modal").removeClass("hidden");
                
                return false;
            });
            
            // Use event delegation for close buttons
            $(document).on("click", ".close-modal", function(e) {
                e.preventDefault();
                e.stopPropagation();
                toggleClientModal(false);
                return false;
            });
            
            // Handle cancel button
            $(document).on("click", "#add-cancel-add-client", function(e) {
                e.preventDefault();
                e.stopPropagation();
                toggleClientModal(false);
                return false;
            });
            
            // Close when clicking on the background
            $(document).on("click", "#add_client_modal", function(e) {
                if (e.target === this) {
                    toggleClientModal(false);
                }
            });
            
            // Handle client form submission via button click
            $(document).on("click", "#add-save-client-btn", function(e) {
                e.preventDefault();
                e.stopPropagation(); // Prevent event bubbling to parent form
                
                // Check if we can find the form fields directly (since form tag might not be rendering)
                var $businessNameField = $("#add-client-business-name");
                var $emailField = $("#add-client-email");
                var $usernameField = $("#add-client-username");
                var $passwordField = $("#add-client-password");
                
                if ($businessNameField.length === 0 || $emailField.length === 0 || $usernameField.length === 0 || $passwordField.length === 0) {
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.error("Client form fields not found! Please refresh the page and try again.");
                    } else {
                        console.error("Client form fields not found! Please refresh the page and try again.");
                    }
                    return;
                }
                
                // Check if easyInvoice object exists
                if (typeof easyInvoice === 'undefined') {
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.error("Error: easyInvoice object is not defined. Please refresh the page.");
                    } else {
                        console.error("Error: easyInvoice object is not defined. Please refresh the page.");
                    }
                    return;
                }
                
                // Check if required fields are filled
                var businessName = $businessNameField.val();
                var email = $emailField.val();
                var username = $usernameField.val();
                var password = $passwordField.val();
                
                // Validate required fields
                if (!businessName || !email || !username ) {
                    if (typeof EasyInvoiceToast !== 'undefined') {
                        EasyInvoiceToast.error("Please fill in all required fields (Business Name, Email, Username, Password)");
                    } else {
                        console.error("Please fill in all required fields (Business Name, Email, Username, Password)");
                    }
                    return;
                }
                
                // Get form data using new field names - ensure no conflicts with main form
                var clientData = {
                    business_client_name: businessName,
                    email: email,
                    username: username,
                    password: password,
                    address: $("#add-client-address").val(),
                    phone: $("#add-client-phone").val(),
                    first_name: $("#add-client-first-name").val(),
                    last_name: $("#add-client-last-name").val(),
                    website: $("#add-client-website").val(),
                    action: "easy_invoice_add_client",
                    nonce: easyInvoice.nonce,
                    suppress_global_toast: true, // Prevent global toasts
                    is_client_form: true // Flag to identify this is client form data
                };
                
                // Show loading state
                var submitBtn = $(this);
                var originalText = submitBtn.text();
                submitBtn.prop("disabled", true).html("<i class=\"fas fa-spinner fa-spin mr-2\"></i> Saving...");
                
                // Send AJAX request
                $.ajax({
                    url: easyInvoice.ajaxUrl,
                    type: "POST",
                    data: clientData,
                    timeout: 10000, // 10 second timeout
                    success: function(response) {
                        // Always reset the button and clear the form
                        submitBtn.prop("disabled", false).html(originalText);
                        $("#add-client-business-name, #add-client-email, #add-client-username, #add-client-password, #add-client-first-name, #add-client-last-name, #add-client-address, #add-client-phone, #add-client-website").val("");
                        
                        if (response.success) {
                            // Close modal
                            $("#add_client_modal").addClass("hidden");
                            
                            // If we're in an invoice or quote builder, select the new client
                            if (typeof window.selectClientFromOption === 'function') {
                                // Create client data object for selection
                                var newClientData = {
                                    name: clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name),
                                    email: clientData.email,
                                    company: clientData.business_client_name,
                                    phone: clientData.phone,
                                    website: clientData.website,
                                    address: clientData.address
                                };
                                
                                // Select the new client in the main form
                                window.selectClientFromOption({
                                    getAttribute: function(attr) {
                                        if (attr === 'data-client-id') return response.data.client_id;
                                        if (attr === 'data-client-name') return newClientData.name;
                                        if (attr === 'data-client-email') return newClientData.email;
                                        if (attr === 'data-client-company') return newClientData.company;
                                        if (attr === 'data-client-phone') return newClientData.phone;
                                        if (attr === 'data-client-website') return newClientData.website;
                                        if (attr === 'data-client-address') return newClientData.address;
                                        return '';
                                    }
                                });
                            }
                            
                            // Add the new client to the table
                            var clientName = clientData.business_client_name || (clientData.first_name + ' ' + clientData.last_name);
                            if (clientName.trim() === '') {
                                clientName = clientData.username;
                            }
                            
                            // Create new table row
                            var newRow = `
                                <tr>
                                    <td class="px-6 py-4 whitespace-nowrap">
                                        <div class="text-sm text-gray-500 font-mono font-semibold">${response.data.client_id}</div>
                                    </td>
                                    <td class="px-6 py-4 whitespace-nowrap">
                                        <div class="text-sm font-medium text-gray-900">${clientName}</div>
                                    </td>
                                    <td class="px-6 py-4 whitespace-nowrap">
                                        <div class="text-sm text-gray-500">${clientData.email}</div>
                                    </td>
                                    <td class="px-6 py-4 whitespace-nowrap">
                                        <div class="text-sm text-gray-500">${clientData.username}</div>
                                    </td>
                                    <td class="px-6 py-4 whitespace-nowrap">
                                        <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
                                            <i class="fas fa-user mr-1"></i>
                                            Client
                                        </span>
                                    </td>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
                                        <div class="flex items-center space-x-2">
                                            <a href="?page=easy-invoice-client-view&client_id=${response.data.client_id}" 
                                               class="inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors duration-200"
                                               title="View Client">
                                                <i class="fas fa-eye mr-1"></i>
                                                View
                                            </a>
                                            <a href="?page=easy-invoice-client-edit&client_id=${response.data.client_id}" 
                                               class="inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded text-blue-700 bg-blue-100 hover:bg-blue-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-200"
                                               title="Edit Client">
                                                <i class="fas fa-edit mr-1"></i>
                                                Edit
                                            </a>
                                            <button type="button" 
                                                    class="delete-client inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 transition-colors duration-200"
                                                    data-id="${response.data.client_id}"
                                                    title="Delete Client">
                                                <i class="fas fa-trash mr-1"></i>
                                                Delete
                                            </button>
                                        </div>
                                    </td>
                                </tr>
                            `;
                            
                            // Remove "No clients found" row if it exists
                            $(".client-list-table tbody tr td[colspan='6']").closest("tr").remove();
                            
                            // Add new row at the top of the table (since we order by ID DESC)
                            $(".client-list-table tbody").prepend(newRow);
                            
                            // Update total clients count
                            var currentCount = parseInt($("h3:contains('Total Clients')").next().text()) || 0;
                            $("h3:contains('Total Clients')").next().text(currentCount + 1);
                            
                            // Show server's success message (don't add additional client-side message)
                            if (typeof showToast === 'function' && response.data.message) {
                                showToast(response.data.message, "success");
                            }
                        } else {
                            if (typeof showToast === 'function') {
                                showToast(response.data.message || "Error adding client", "error");
                            }
                        }
                    },
                    error: function(xhr, status, error) {
                        submitBtn.prop("disabled", false).html(originalText);
                        if (typeof EasyInvoiceToast !== 'undefined') {
                            EasyInvoiceToast.error("Error connecting to server. Please try again.");
                        } else if (typeof showToast === 'function') {
                            showToast("Error connecting to server. Please try again.", "error");
                        } else {
                            console.error("Error connecting to server. Please try again.");
                        }
                    },
                    timeout: function() {
                        submitBtn.prop("disabled", false).html(originalText);
                        if (typeof EasyInvoiceToast !== 'undefined') {
                            EasyInvoiceToast.error("Request timed out. Please try again.");
                        } else if (typeof showToast === 'function') {
                            showToast("Request timed out. Please try again.", "error");
                        } else {
                            console.error("Request timed out. Please try again.");
                        }
                    }
                });
            });
        }
        
        // Setup password field functionality
        function setupPasswordFields() {
            // Show/hide password functionality for add client modal
            $(document).on('click', '#show-password', function() {
                const passwordInput = $('#client-password');
                const icon = $(this).find('i');
                if (passwordInput.attr('type') === 'password') {
                    passwordInput.attr('type', 'text');
                    icon.removeClass('fa-eye').addClass('fa-eye-slash');
                } else {
                    passwordInput.attr('type', 'password');
                    icon.removeClass('fa-eye-slash').addClass('fa-eye');
                }
            });

            // Show/hide password functionality for edit client page
            $(document).on('click', '#edit-show-password', function() {
                const passwordInput = $('#edit-client-password');
                const icon = $(this).find('i');
                if (passwordInput.attr('type') === 'password') {
                    passwordInput.attr('type', 'text');
                    icon.removeClass('fa-eye').addClass('fa-eye-slash');
                } else {
                    passwordInput.attr('type', 'password');
                    icon.removeClass('fa-eye-slash').addClass('fa-eye');
                }
            });

            // Generate password functionality for add client modal
            $(document).on('click', '#add-generate-password, #edit-generate-password', function() {
                const button = $(this);
                const isEditMode = button.attr('id') === 'edit-generate-password';
                const passwordInput = isEditMode ? $('#edit-client-password') : $('#add-client-password');
                const showPasswordBtn = isEditMode ? $('#edit-show-password') : $('#add-show-password');
                
                button.prop('disabled', true);

                $.ajax({
                    url: easyInvoice.ajaxUrl,
                    type: 'POST',
                    data: {
                        action: 'easy_invoice_generate_password',
                        nonce: easyInvoice.nonce,
                        suppress_global_toast: true // Prevent global success toast
                    },
                    success: function(response) {
                        if (response.success) {
                            passwordInput.val(response.data.password);
                            passwordInput.attr('type', 'text');
                            showPasswordBtn.find('i').removeClass('fa-eye').addClass('fa-eye-slash');
                        } else {
                          
                        }
                    },
                    error: function() {
                        if (typeof EasyInvoiceToast !== 'undefined') {
                            EasyInvoiceToast.error('Error connecting to server');
                        } else if (typeof showToast === 'function') {
                            showToast('Error connecting to server', 'error');
                        } else {
                            console.error('Error connecting to server');
                        }
                    },
                    complete: function() {
                        button.prop('disabled', false);
                    }
                });
            });


        }

        // Setup client edit functionality
        function setupClientEdit() {
            // Disable HTML5 validation for password field in edit mode
            if ($("#edit-client-form").length) {
                $("#edit-client-password").removeAttr("required");
            }

            // Handle client edit form submission
            $(document).on("submit", "#edit-client-form", function(e) {
                e.preventDefault();
                
                let isSubmitting = false;
                if (isSubmitting) return;
                
                isSubmitting = true;
                
                const clientData = {
                    client_id: $("#edit-client-id").val(),
                    business_client_name: $("#edit-client-business-name").val(),
                    email: $("#edit-client-email").val(),
                    username: $("#edit-client-username").val(),
                    password: $("#edit-client-password").val(),
                    address: $("#edit-client-address").val(),
                    phone: $("#edit-client-phone").val(),
                    first_name: $("#edit-client-first-name").val(),
                    last_name: $("#edit-client-last-name").val(),
                    website: $("#edit-client-website").val(),
                    action: "easy_invoice_update_client",
                    nonce: easyInvoice.nonce
                };
                
                const submitBtn = $("#edit-save-client-btn");
                const originalText = submitBtn.text();
                submitBtn.prop("disabled", true).html("<i class=\"fas fa-spinner fa-spin mr-2\"></i> Saving...");
                
                $.ajax({
                    url: easyInvoice.ajaxUrl,
                    type: "POST",
                    data: clientData,
                    success: function(response) {
                        // Re-enable the button regardless of success/failure
                        submitBtn.prop("disabled", false).text(originalText);
                        isSubmitting = false;
                    },
                    error: function() {
                        if (typeof EasyInvoiceToast !== 'undefined') {
                            EasyInvoiceToast.error("Error connecting to server");
                        } else if (typeof showToast === 'function') {
                            showToast("Error connecting to server", "error");
                        } else {
                            console.error("Error connecting to server");
                        }
                        submitBtn.prop("disabled", false).text(originalText);
                        isSubmitting = false;
                    }
                });
            });
        }
        
        // Initialize all client functionality
        function initializeClientManager() {
            // Prevent multiple initializations
            if (window.clientManagerInitialized) {
                return;
            }
            
            setupClientSelection();
            setupClientModal();
            setupPasswordFields();
            setupClientEdit();
            
            // Mark as initialized
            window.clientManagerInitialized = true;
        }
        
        // Initialize the client manager
        initializeClientManager();
        
        // Expose client manager functions globally
        window.clientManager = {
            initializeClientData: initializeClientData,
            refreshClientList: function(newClientData) {
                clientsData = newClientData || clientsData;
                window.easyInvoiceClients = clientsData;
            },
            setupModal: setupClientModal
        };
    });
})(jQuery); 
```
