/** * HVAC Enhanced Field Population System * * Integrates with the existing comprehensive field population system * to provide 100% field control for the enhanced TEC template. * * This system extends the existing JavaScript population logic * to support the new template structure with categories, featured images, and tags. * * @version 2.0.0 * @since August 12, 2025 */ (function(window, document, $) { 'use strict'; // Enhanced jQuery compatibility check if (typeof $ === 'undefined') { if (typeof window.jQuery !== 'undefined') { $ = window.jQuery; console.log('๐Ÿ”ง HVAC Enhanced Field Population: Using window.jQuery'); } else { console.error('โŒ HVAC Enhanced Field Population: jQuery is required but not found'); return; } } console.log('๐Ÿš€ HVAC Enhanced Field Population System v2.0 Loading...'); /** * Enhanced Field Population System */ window.HVACEnhancedFieldPopulation = window.HVACEnhancedFieldPopulation || {}; // Enhanced field selectors for new template structure const ENHANCED_FIELD_SELECTORS = { // Core WordPress fields title: [ '#post_title', 'input[name="post_title"]', '.tribe-common-form-control-text__input[name="post_title"]' ], content: [ '#tcepostcontent', '#post_content', 'textarea[name="post_content"]', '.wp-editor-area' ], excerpt: [ '#hvac_post_excerpt', 'textarea[name="post_excerpt"]', '.hvac-field-textarea[name="post_excerpt"]' ], // Enhanced taxonomy fields categories: [ 'input[name="tax_input\\[tribe_events_cat\\]\\[\\]"][type="checkbox"]', 'select[name="tax_input\\[tribe_events_cat\\]\\[\\]"]', 'select[name="tax_input\\[tribe_events_cat\\]"]', '.hvac-category-checkbox', 'input[type="checkbox"][name*="tribe_events_cat"]' ], tags: [ '#hvac_tags_input', 'input[name="tax_input\\[post_tag\\]"]', 'input[name="tax_input\\[post_tag\\]\\[\\]"]', 'select[name="tax_input\\[post_tag\\]\\[\\]"]', '.hvac-tags-input', 'input[name="newtag\\[post_tag\\]"]' ], // Featured image fields featured_image: [ '#hvac_featured_image_id', 'input[name="_thumbnail_id"]' ], // TEC specific fields (maintain compatibility) venue: [ '#tec_venue', 'select[name="venue[VenueID]"]', '#saved_venue' ], organizer: [ '#saved_organizer', 'select[name="organizer[OrganizerID]"]' ], start_date: [ '#EventStartDate', 'input[name="EventStartDate"]' ], start_time: [ '#EventStartTime', 'input[name="EventStartTime"]' ], end_date: [ '#EventEndDate', 'input[name="EventEndDate"]' ], end_time: [ '#EventEndTime', 'input[name="EventEndTime"]' ], cost: [ '#EventCost', 'input[name="EventCost"]' ] }; /** * Enhanced field population functions */ const FieldPopulators = { /** * Populate excerpt field with enhanced UX */ populateExcerpt: function(value) { const selectors = ENHANCED_FIELD_SELECTORS.excerpt; let populated = false; for (let selector of selectors) { const element = document.querySelector(selector); if (element) { element.value = value || ''; // Trigger events for enhanced field features element.dispatchEvent(new Event('input', { bubbles: true })); element.dispatchEvent(new Event('change', { bubbles: true })); // Update character counter if present const counter = document.querySelector('#excerpt-counter .current-count'); if (counter) { counter.textContent = (value || '').length; } console.log(`โœ… Excerpt populated: ${selector} (${(value || '').length} chars)`); populated = true; break; } } if (!populated) { console.warn('โŒ Excerpt field not found with any selector'); } return populated; }, /** * Populate categories with multi-select support */ populateCategories: function(categoryData) { if (!categoryData) return false; // Handle different data formats let categoryIds = []; if (Array.isArray(categoryData)) { categoryIds = categoryData; } else if (typeof categoryData === 'string') { categoryIds = categoryData.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id)); } else if (categoryData.ids) { categoryIds = categoryData.ids; } if (categoryIds.length === 0) return false; let populated = 0; let totalCheckboxes = 0; // Find and check category checkboxes with enhanced selectors categoryIds.forEach(categoryId => { // Try multiple selector patterns for better compatibility const selectors = [ `input[name="tax_input\\[tribe_events_cat\\]\\[\\]"][value="${categoryId}"]`, `input[name="tax_input\\[tribe_events_cat\\]\\[\\]"][value="${categoryId}"][type="checkbox"]`, `#in-tribe_events_cat-${categoryId}`, `input[type="checkbox"][name*="tribe_events_cat"][value="${categoryId}"]` ]; let checkbox = null; for (const selector of selectors) { try { checkbox = document.querySelector(selector); if (checkbox) break; } catch (error) { console.warn('Selector error:', selector, error); } } if (checkbox) { checkbox.checked = true; checkbox.dispatchEvent(new Event('change', { bubbles: true })); populated++; } else { console.warn(`Category checkbox not found for ID: ${categoryId}`); } totalCheckboxes++; }); // Update categories summary if present const selectedCount = document.getElementById('selected-count'); if (selectedCount) { selectedCount.textContent = populated; } console.log(`โœ… Categories populated: ${populated}/${totalCheckboxes} checkboxes`); return populated > 0; }, /** * Populate featured image with WordPress media integration */ populateFeaturedImage: function(imageData) { if (!imageData) return false; let imageId = ''; let imageUrl = ''; // Handle different data formats if (typeof imageData === 'object') { imageId = imageData.id || imageData.ID || ''; imageUrl = imageData.url || imageData.sizes?.medium?.url || imageData.sizes?.large?.url || ''; } else if (typeof imageData === 'string' || typeof imageData === 'number') { imageId = imageData.toString(); // For ID only, we'll need to make an AJAX call or use placeholder } // Set hidden field value const hiddenField = document.querySelector('#hvac_featured_image_id') || document.querySelector('input[name="_thumbnail_id"]'); if (hiddenField) { hiddenField.value = imageId; } // Update preview if URL is available const preview = document.querySelector('#hvac-image-preview'); if (preview && imageUrl) { preview.innerHTML = `Featured image preview`; // Show remove button const removeBtn = document.querySelector('#hvac-remove-image-btn'); if (removeBtn) { removeBtn.style.display = 'inline-block'; } // Update button text const uploadBtn = document.querySelector('#hvac-upload-image-btn'); if (uploadBtn) { uploadBtn.textContent = 'Change Image'; } // Show image details const imageDetails = document.querySelector('#hvac-image-details'); if (imageDetails) { imageDetails.style.display = 'block'; } } console.log(`โœ… Featured image populated: ID ${imageId}${imageUrl ? ` with URL ${imageUrl.substring(0, 50)}...` : ''}`); return true; }, /** * Populate tags with autocomplete integration */ populateTags: function(tagsData) { if (!tagsData) return false; // Handle different data formats let tags = []; if (Array.isArray(tagsData)) { tags = tagsData.map(tag => typeof tag === 'string' ? tag : tag.name || tag.slug).filter(Boolean); } else if (typeof tagsData === 'string') { tags = tagsData.split(',').map(tag => tag.trim()).filter(Boolean); } if (tags.length === 0) return false; const currentTagsContainer = document.querySelector('#hvac-current-tags'); if (!currentTagsContainer) { console.warn('โŒ Tags container not found'); return false; } // Clear existing tags currentTagsContainer.innerHTML = ''; // Add new tags using the enhanced UI system let addedCount = 0; tags.forEach(tag => { if (addTagToUI(tag.trim(), currentTagsContainer)) { addedCount++; } }); // Update counter const tagsCounter = document.querySelector('#hvac-tags-counter .current-tags-count'); if (tagsCounter) { tagsCounter.textContent = addedCount; } console.log(`โœ… Tags populated: ${addedCount}/${tags.length} tags added`); return addedCount > 0; }, /** * Populate standard TEC fields (maintain compatibility) */ populateStandardFields: function(eventData) { const results = {}; // Title if (eventData.title) { results.title = this.populateTextField(ENHANCED_FIELD_SELECTORS.title, eventData.title); } // Content if (eventData.content || eventData.description) { const content = eventData.content || eventData.description; results.content = this.populateContentField(content); } // Venue if (eventData.venue) { results.venue = this.populateSelectField(ENHANCED_FIELD_SELECTORS.venue, eventData.venue); } // Organizer if (eventData.organizer) { results.organizer = this.populateSelectField(ENHANCED_FIELD_SELECTORS.organizer, eventData.organizer); } // Dates and times if (eventData.start_date) { results.start_date = this.populateTextField(ENHANCED_FIELD_SELECTORS.start_date, eventData.start_date); } if (eventData.start_time) { results.start_time = this.populateTextField(ENHANCED_FIELD_SELECTORS.start_time, eventData.start_time); } if (eventData.end_date) { results.end_date = this.populateTextField(ENHANCED_FIELD_SELECTORS.end_date, eventData.end_date); } if (eventData.end_time) { results.end_time = this.populateTextField(ENHANCED_FIELD_SELECTORS.end_time, eventData.end_time); } // Cost if (eventData.cost !== undefined) { results.cost = this.populateTextField(ENHANCED_FIELD_SELECTORS.cost, eventData.cost); } return results; }, /** * Generic text field population with enhanced error handling */ populateTextField: function(selectors, value) { if (!selectors || selectors.length === 0) return false; for (let selector of selectors) { try { const element = document.querySelector(selector); if (element) { // Check if field is editable if (element.disabled || element.readOnly) { console.warn(`Field is disabled/readonly: ${selector}`); continue; } element.value = value || ''; // Trigger multiple event types for better compatibility ['input', 'change', 'keyup', 'blur'].forEach(eventType => { element.dispatchEvent(new Event(eventType, { bubbles: true })); }); // Mark field as populated for debugging element.setAttribute('data-hvac-populated', 'true'); return true; } } catch (error) { console.warn(`Selector error for "${selector}":`, error); } } return false; }, /** * Content field population (handles TinyMCE) */ populateContentField: function(content) { const selectors = ENHANCED_FIELD_SELECTORS.content; for (let selector of selectors) { const element = document.querySelector(selector); if (element) { // Check if this is a TinyMCE editor if (typeof tinyMCE !== 'undefined' && element.id) { const editor = tinyMCE.get(element.id); if (editor) { editor.setContent(content || ''); editor.fire('change'); return true; } } // Standard textarea element.value = content || ''; element.dispatchEvent(new Event('input', { bubbles: true })); element.dispatchEvent(new Event('change', { bubbles: true })); return true; } } return false; }, /** * Select field population */ populateSelectField: function(selectors, value) { for (let selector of selectors) { const element = document.querySelector(selector); if (element && element.tagName.toLowerCase() === 'select') { element.value = value || ''; element.dispatchEvent(new Event('change', { bubbles: true })); return true; } } return false; } }; /** * Helper function to add tags to UI (used by populateTags) */ function addTagToUI(tag, container) { if (!tag || !container) return false; const tagElement = document.createElement('div'); tagElement.className = 'hvac-tag-item'; tagElement.setAttribute('role', 'listitem'); tagElement.innerHTML = ` ${escapeHtml(tag)} `; // Add remove functionality const removeBtn = tagElement.querySelector('.hvac-tag-remove'); if (removeBtn) { removeBtn.addEventListener('click', function() { tagElement.remove(); }); } container.appendChild(tagElement); return true; } /** * HTML escape utility */ function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } /** * Main Enhanced Field Population Function * * This is the primary interface that integrates with existing systems */ window.HVACEnhancedFieldPopulation.populateAllFields = function(eventData) { console.log('๐ŸŽฏ Starting enhanced field population...'); console.log('๐Ÿ“Š Event data received:', eventData); const results = { // Enhanced WordPress fields excerpt: false, categories: false, featured_image: false, tags: false, // Standard fields (maintain compatibility) title: false, content: false, venue: false, organizer: false, start_date: false, start_time: false, end_date: false, end_time: false, cost: false }; try { // Populate enhanced WordPress fields if (eventData.excerpt || eventData.post_excerpt) { results.excerpt = FieldPopulators.populateExcerpt(eventData.excerpt || eventData.post_excerpt); } if (eventData.categories || eventData.category_ids || eventData.taxonomies?.categories) { const categoriesData = eventData.categories || eventData.category_ids || eventData.taxonomies?.categories; results.categories = FieldPopulators.populateCategories(categoriesData); } if (eventData.featured_image || eventData.thumbnail) { const imageData = eventData.featured_image || eventData.thumbnail; results.featured_image = FieldPopulators.populateFeaturedImage(imageData); } if (eventData.tags || eventData.post_tags || eventData.taxonomies?.tags) { const tagsData = eventData.tags || eventData.post_tags || eventData.taxonomies?.tags; results.tags = FieldPopulators.populateTags(tagsData); } // Populate standard TEC fields const standardResults = FieldPopulators.populateStandardFields(eventData); Object.assign(results, standardResults); } catch (error) { console.error('โŒ Enhanced field population error:', error); } // Calculate success metrics const successCount = Object.values(results).filter(Boolean).length; const totalFields = Object.keys(results).length; const successRate = totalFields > 0 ? Math.round((successCount / totalFields) * 100) : 0; console.log(`๐ŸŽ‰ Enhanced field population complete: ${successCount}/${totalFields} fields (${successRate}%)`); console.log('๐Ÿ“Š Detailed results:', results); return { success: successRate === 100, successRate: successRate, results: results, populated_fields: successCount, total_fields: totalFields }; }; /** * Field Access Testing Function with Enhanced Detection */ window.HVACEnhancedFieldPopulation.testFieldAccess = function() { console.log('๐Ÿงช Running enhanced field access test...'); const testResults = {}; const fieldTypes = Object.keys(ENHANCED_FIELD_SELECTORS); fieldTypes.forEach(fieldType => { const selectors = ENHANCED_FIELD_SELECTORS[fieldType]; testResults[fieldType] = { found: false, selector_used: null, element_type: null, all_attempts: [] }; for (let selector of selectors) { let element = null; let error = null; try { element = document.querySelector(selector); } catch (err) { error = err.message; } testResults[fieldType].all_attempts.push({ selector: selector, found: !!element, error: error }); if (element) { testResults[fieldType] = { ...testResults[fieldType], found: true, selector_used: selector, element_type: element.tagName.toLowerCase(), element_id: element.id || 'no-id', element_name: element.name || 'no-name', element_class: element.className || 'no-class', is_visible: element.offsetParent !== null, is_enabled: !element.disabled && !element.readOnly }; break; } } }); const foundCount = Object.values(testResults).filter(result => result.found).length; const totalCount = fieldTypes.length; const accessRate = Math.round((foundCount / totalCount) * 100); console.log(`๐ŸŽฏ Field access test: ${foundCount}/${totalCount} fields found (${accessRate}%)`); console.log('๐Ÿ” Detailed field access results:', testResults); // Log missing fields with their failed selectors const missingFields = Object.entries(testResults) .filter(([_, result]) => !result.found) .map(([fieldType, result]) => ({ field: fieldType, attempted_selectors: result.all_attempts.map(a => a.selector), errors: result.all_attempts.filter(a => a.error).map(a => `${a.selector}: ${a.error}`) })); if (missingFields.length > 0) { console.warn('โŒ Missing fields:', missingFields); } return { success: accessRate === 100, access_rate: accessRate, found_fields: foundCount, total_fields: totalCount, results: testResults, missing_fields: missingFields }; }; /** * Integration with existing comprehensive field population system */ window.HVACEnhancedFieldPopulation.integrateWithExistingSystem = function() { // Check if existing comprehensive system exists if (typeof window.populateAllEventFields === 'function') { console.log('๐Ÿ”— Integrating with existing comprehensive field population system...'); // Wrap existing function to include enhanced features const originalFunction = window.populateAllEventFields; window.populateAllEventFields = function(eventData) { console.log('๐Ÿš€ Running integrated field population (original + enhanced)...'); // Run original system first let originalResult = {}; try { originalResult = originalFunction.call(this, eventData) || {}; } catch (error) { console.warn('โš ๏ธ Original system error:', error); } // Run enhanced system let enhancedResult = {}; try { enhancedResult = window.HVACEnhancedFieldPopulation.populateAllFields(eventData); } catch (error) { console.warn('โš ๏ธ Enhanced system error:', error); } // Combine results const combinedResult = { original: originalResult, enhanced: enhancedResult, overall_success: (originalResult.success || false) && (enhancedResult.success || false), combined_success_rate: Math.round( ((originalResult.successRate || 0) + (enhancedResult.successRate || 0)) / 2 ) }; console.log('๐ŸŽฏ Integrated field population complete:', combinedResult); return combinedResult; }; console.log('โœ… Integration complete - enhanced system is now active'); } else { console.log('โ„น๏ธ No existing comprehensive system found - enhanced system running independently'); } }; /** * Initialize Enhanced Field Population System */ function initializeEnhancedSystem() { console.log('๐Ÿ”ง Initializing HVAC Enhanced Field Population System...'); // Wait for DOM to be ready with enhanced compatibility if (typeof $ !== 'undefined' && $.fn && $.fn.ready) { $(document).ready(function() { // Test initial field access setTimeout(() => { window.HVACEnhancedFieldPopulation.testFieldAccess(); }, 1000); // Integrate with existing system window.HVACEnhancedFieldPopulation.integrateWithExistingSystem(); // Set up global error handlers window.addEventListener('error', function(event) { if (event.error && event.error.message.includes('HVAC')) { console.error('๐Ÿšจ HVAC Enhanced Field Population Error:', event.error); } }); console.log('โœ… HVAC Enhanced Field Population System Ready'); }); } else { console.warn('โš ๏ธ jQuery not available, using fallback initialization'); // Fallback for when jQuery is not available if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { console.log('โœ… HVAC Enhanced Field Population System Ready (fallback)'); }); } else { console.log('โœ… HVAC Enhanced Field Population System Ready (fallback)'); } } } // Initialize when script loads initializeEnhancedSystem(); // Export for debugging and testing if (window.console && window.console.log) { window.HVACEnhancedFieldPopulation.debug = { SELECTORS: ENHANCED_FIELD_SELECTORS, FieldPopulators: FieldPopulators, version: '2.0.0' }; } })(window, document, window.jQuery); /** * Global compatibility function for existing integrations */ window.hvacEnhancedPopulateFields = function(eventData) { if (window.HVACEnhancedFieldPopulation && window.HVACEnhancedFieldPopulation.populateAllFields) { return window.HVACEnhancedFieldPopulation.populateAllFields(eventData); } console.warn('HVAC Enhanced Field Population System not initialized'); return { success: false, error: 'System not initialized' }; }; console.log('๐Ÿ“„ HVAC Enhanced Field Population Script Loaded v2.0.0');