/**
* 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 = `
`;
// 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');