Customer Form Auto-Fill & Navigation Helper

Adds A-Z dropdown navigation, Tab key support for form fields, and copy customer details functionality

Size

11.7 KB

Version

1.1.1

Created

Nov 29, 2025

Updated

3 months ago

1// ==UserScript==
2// @name		Customer Form Auto-Fill & Navigation Helper
3// @description		Adds A-Z dropdown navigation, Tab key support for form fields, and copy customer details functionality
4// @version		1.1.1
5// @match		http://192.168.3.251/*
6// ==/UserScript==
7(function() {
8    'use strict';
9
10    console.log('Customer Form Auto-Fill & Navigation Helper loaded');
11
12    // Debounce function to prevent excessive calls
13    function debounce(func, wait) {
14        let timeout;
15        return function executedFunction(...args) {
16            const later = () => {
17                clearTimeout(timeout);
18                func(...args);
19            };
20            clearTimeout(timeout);
21            timeout = setTimeout(later, wait);
22        };
23    }
24
25    // Initialize the extension
26    async function init() {
27        console.log('Initializing Customer Form Helper...');
28        
29        // Wait for the page to be fully loaded
30        if (document.readyState === 'loading') {
31            document.addEventListener('DOMContentLoaded', setupFeatures);
32        } else {
33            setupFeatures();
34        }
35    }
36
37    function setupFeatures() {
38        console.log('Setting up features...');
39        
40        // Add A-Z dropdown navigation
41        addAlphabetNavigation();
42        
43        // Enable Tab key support for all form fields
44        enableTabKeySupport();
45        
46        // Add copy customer details functionality
47        addCopyCustomerDetailsButton();
48        
49        // Observe DOM changes to re-apply features when needed
50        observeDOMChanges();
51    }
52
53    // Add A-Z dropdown navigation
54    function addAlphabetNavigation() {
55        console.log('Adding A-Z navigation...');
56        
57        // Check if we're on the customer list page
58        const customerTable = document.querySelector('#example1');
59        if (!customerTable) {
60            console.log('Customer table not found, skipping A-Z navigation');
61            return;
62        }
63
64        // Check if navigation already exists
65        if (document.getElementById('az-navigation')) {
66            console.log('A-Z navigation already exists');
67            return;
68        }
69
70        // Create A-Z navigation container
71        const navContainer = document.createElement('div');
72        navContainer.id = 'az-navigation';
73        navContainer.style.cssText = `
74            margin: 15px 0;
75            padding: 15px;
76            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
77            border-radius: 8px;
78            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
79        `;
80
81        // Create label
82        const label = document.createElement('label');
83        label.textContent = 'Quick Search by Letter: ';
84        label.style.cssText = `
85            color: white;
86            font-weight: bold;
87            font-size: 14px;
88            margin-right: 10px;
89        `;
90
91        // Create dropdown
92        const dropdown = document.createElement('select');
93        dropdown.id = 'az-dropdown';
94        dropdown.style.cssText = `
95            padding: 8px 15px;
96            border: 2px solid white;
97            border-radius: 5px;
98            font-size: 14px;
99            font-weight: bold;
100            background: white;
101            color: #667eea;
102            cursor: pointer;
103            min-width: 100px;
104            transition: all 0.3s ease;
105        `;
106
107        // Add hover effect
108        dropdown.addEventListener('mouseenter', () => {
109            dropdown.style.transform = 'scale(1.05)';
110            dropdown.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)';
111        });
112        dropdown.addEventListener('mouseleave', () => {
113            dropdown.style.transform = 'scale(1)';
114            dropdown.style.boxShadow = 'none';
115        });
116
117        // Add default option
118        const defaultOption = document.createElement('option');
119        defaultOption.value = '';
120        defaultOption.textContent = 'Select Letter';
121        dropdown.appendChild(defaultOption);
122
123        // Add A-Z options
124        for (let i = 65; i <= 90; i++) {
125            const letter = String.fromCharCode(i);
126            const option = document.createElement('option');
127            option.value = letter;
128            option.textContent = letter;
129            dropdown.appendChild(option);
130        }
131
132        // Add "All" option
133        const allOption = document.createElement('option');
134        allOption.value = 'ALL';
135        allOption.textContent = 'Show All';
136        dropdown.appendChild(allOption);
137
138        // Handle dropdown change
139        dropdown.addEventListener('change', async function() {
140            const selectedLetter = this.value;
141            console.log('Selected letter:', selectedLetter);
142            
143            if (selectedLetter === '') {
144                return;
145            }
146
147            const searchBox = document.querySelector('#txtSearch');
148            if (searchBox) {
149                if (selectedLetter === 'ALL') {
150                    searchBox.value = '';
151                } else {
152                    searchBox.value = selectedLetter;
153                }
154                
155                // Trigger search
156                const searchButton = document.querySelector('#btnSearch');
157                if (searchButton) {
158                    searchButton.click();
159                }
160            }
161        });
162
163        navContainer.appendChild(label);
164        navContainer.appendChild(dropdown);
165
166        // Insert navigation before the table
167        const tableContainer = customerTable.closest('.card-body');
168        if (tableContainer) {
169            tableContainer.insertBefore(navContainer, tableContainer.firstChild);
170            console.log('A-Z navigation added successfully');
171        }
172    }
173
174    // Enable Tab key support for all form fields
175    function enableTabKeySupport() {
176        console.log('Enabling Tab key support...');
177        
178        const form = document.querySelector('#frmParty');
179        if (!form) {
180            console.log('Form not found, skipping Tab key support');
181            return;
182        }
183
184        // Get all form inputs, selects, and textareas
185        const formFields = form.querySelectorAll('input:not([type="hidden"]), select, textarea');
186        console.log('Found', formFields.length, 'form fields');
187
188        formFields.forEach((field, index) => {
189            // Set tabindex for proper tab order
190            field.setAttribute('tabindex', index + 1);
191            
192            // Add visual feedback on focus
193            field.addEventListener('focus', function() {
194                this.style.outline = '2px solid #667eea';
195                this.style.boxShadow = '0 0 8px rgba(102, 126, 234, 0.5)';
196            });
197            
198            field.addEventListener('blur', function() {
199                this.style.outline = '';
200                this.style.boxShadow = '';
201            });
202
203            // Handle Tab key for select2 dropdowns
204            if (field.classList.contains('select2-hidden-accessible')) {
205                const select2Container = field.nextElementSibling;
206                if (select2Container && select2Container.classList.contains('select2')) {
207                    select2Container.addEventListener('keydown', function(e) {
208                        if (e.key === 'Tab') {
209                            // Let the default Tab behavior work
210                            console.log('Tab pressed on select2 field');
211                        }
212                    });
213                }
214            }
215        });
216
217        console.log('Tab key support enabled for all form fields');
218    }
219
220    // Add copy customer details functionality
221    function addCopyCustomerDetailsButton() {
222        console.log('Adding copy customer details button...');
223        
224        // Check if we're on the customer list page
225        const customerTable = document.querySelector('#example1 tbody');
226        if (!customerTable) {
227            console.log('Customer table body not found');
228            return;
229        }
230
231        // Add copy button to each customer row
232        const rows = customerTable.querySelectorAll('tr');
233        console.log('Found', rows.length, 'customer rows');
234
235        rows.forEach((row) => {
236            // Check if copy button already exists
237            if (row.querySelector('.copy-customer-btn')) {
238                return;
239            }
240
241            const actionCell = row.querySelector('td:last-child div');
242            if (!actionCell) {
243                return;
244            }
245
246            // Create copy button
247            const copyButton = document.createElement('button');
248            copyButton.className = 'btn btn-icon btn-info copy-customer-btn';
249            copyButton.title = 'Copy Customer Details';
250            copyButton.style.cssText = `
251                margin-left: 5px;
252                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
253                border: none;
254                transition: all 0.3s ease;
255            `;
256            
257            copyButton.innerHTML = '<i class="fas fa-copy"></i>';
258
259            // Add hover effect
260            copyButton.addEventListener('mouseenter', () => {
261                copyButton.style.transform = 'scale(1.1)';
262                copyButton.style.boxShadow = '0 4px 8px rgba(102, 126, 234, 0.4)';
263            });
264            copyButton.addEventListener('mouseleave', () => {
265                copyButton.style.transform = 'scale(1)';
266                copyButton.style.boxShadow = 'none';
267            });
268
269            // Handle copy button click
270            copyButton.addEventListener('click', async function(e) {
271                e.preventDefault();
272                e.stopPropagation();
273                
274                const cells = row.querySelectorAll('td');
275                if (cells.length >= 3) {
276                    const customerName = cells[0].textContent.trim();
277                    const address = cells[1].textContent.trim();
278                    const state = cells[2].textContent.trim();
279                    
280                    const customerDetails = `Customer Name: ${customerName}\nAddress: ${address}\nState: ${state}`;
281                    
282                    try {
283                        // Use GM.setClipboard to copy to clipboard
284                        await GM.setClipboard(customerDetails);
285                        
286                        // Show success feedback
287                        const originalHTML = copyButton.innerHTML;
288                        copyButton.innerHTML = '<i class="fas fa-check"></i>';
289                        copyButton.style.background = 'linear-gradient(135deg, #11998e 0%, #38ef7d 100%)';
290                        
291                        setTimeout(() => {
292                            copyButton.innerHTML = originalHTML;
293                            copyButton.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)';
294                        }, 2000);
295                        
296                        console.log('Customer details copied to clipboard');
297                    } catch (error) {
298                        console.error('Failed to copy to clipboard:', error);
299                        alert('Failed to copy customer details');
300                    }
301                }
302            });
303
304            actionCell.appendChild(copyButton);
305        });
306
307        console.log('Copy buttons added to all customer rows');
308    }
309
310    // Observe DOM changes to re-apply features when needed
311    function observeDOMChanges() {
312        const observer = new MutationObserver(debounce((mutations) => {
313            console.log('DOM changed, re-applying features...');
314            
315            // Re-apply features if new content is loaded
316            addAlphabetNavigation();
317            enableTabKeySupport();
318            addCopyCustomerDetailsButton();
319        }, 1000));
320
321        observer.observe(document.body, {
322            childList: true,
323            subtree: true
324        });
325
326        console.log('DOM observer started');
327    }
328
329    // Start the extension
330    init();
331
332})();