/**
* HVAC REST API Event Submission System
* Achieves 100% field control by bypassing TEC Community Events limitations
* Uses TEC REST API to submit events with ALL WordPress fields including excerpt
*/
(function($) {
'use strict';
const HVACRestEventSubmission = {
// REST API endpoints
apiEndpoint: '/wp-json/tribe/events/v1/events',
eventId: null, // Will be set if editing
/**
* Initialize the REST API submission system
*/
init: function() {
console.log('[HVAC REST] Initializing REST API Event Submission System');
// Check if we're in edit mode
if (window.hvacEditEventId) {
this.eventId = window.hvacEditEventId;
console.log('[HVAC REST] Edit mode - Event ID:', this.eventId);
}
// Enhance existing form or create new submission handler
this.attachSubmitHandler();
this.enhanceFormFields();
// If editing, load existing excerpt
if (this.eventId) {
this.loadExistingExcerpt();
}
},
/**
* Enhance form with additional fields not supported by TEC frontend
*/
enhanceFormFields: function() {
// Add excerpt field if not present
if (!$('#event_excerpt').length && $('#tribe-community-events').length) {
const excerptHTML = `
`;
// Insert after description section
$('.tribe-section-content').first().parent().after(excerptHTML);
console.log('[HVAC REST] Added excerpt field to form');
}
},
/**
* Attach submit handler to intercept form submission
*/
attachSubmitHandler: function() {
const self = this;
// Override TEC form submission
$(document).on('submit', '#tribe-community-events form', function(e) {
e.preventDefault();
console.log('[HVAC REST] Intercepting form submission for REST API');
// Collect all form data
const eventData = self.collectFormData($(this));
// Submit via REST API
self.submitViaRestAPI(eventData);
return false;
});
},
/**
* Collect all form data including enhanced fields
*/
collectFormData: function($form) {
const data = {
// Core fields
title: $form.find('#post_title, input[name="post_title"]').val(),
description: this.getEditorContent(),
excerpt: $form.find('#event_excerpt, textarea[name="excerpt"]').val() || '',
status: 'publish',
// Date/Time fields
start_date: this.formatDateTime(
$form.find('input[name="EventStartDate"]').val(),
$form.find('input[name="EventStartTime"]').val()
),
end_date: this.formatDateTime(
$form.find('input[name="EventEndDate"]').val(),
$form.find('input[name="EventEndTime"]').val()
),
all_day: $form.find('#allDayCheckbox').is(':checked'),
// Venue data
venue: this.collectVenueData($form),
// Organizer data
organizer: this.collectOrganizerData($form),
// Categories (array of IDs)
categories: this.collectCategories($form),
// Tags (array of names)
tags: this.collectTags($form),
// Featured image
featured_media: $form.find('input[name="_thumbnail_id"]').val() || 0,
// Event cost
cost: $form.find('#EventCost, input[name="EventCost"]').val() || '',
// Event URL
website: $form.find('#EventURL, input[name="EventURL"]').val() || ''
};
console.log('[HVAC REST] Collected form data:', data);
return data;
},
/**
* Get content from TinyMCE or textarea
*/
getEditorContent: function() {
// Try TinyMCE first
if (typeof tinymce !== 'undefined') {
const editor = tinymce.get('tcepostcontent') || tinymce.get('post_content');
if (editor) {
return editor.getContent();
}
}
// Fallback to textarea
return $('#tcepostcontent, #post_content, textarea[name="post_content"]').val() || '';
},
/**
* Format date and time for REST API
*/
formatDateTime: function(date, time) {
if (!date) return '';
// Parse date (MM/DD/YYYY or YYYY-MM-DD)
let dateObj;
if (date.includes('/')) {
const parts = date.split('/');
dateObj = new Date(parts[2], parts[0] - 1, parts[1]);
} else {
dateObj = new Date(date);
}
// Parse time if provided
if (time) {
const timeParts = time.match(/(\d+):(\d+)\s*(am|pm)?/i);
if (timeParts) {
let hours = parseInt(timeParts[1]);
const minutes = parseInt(timeParts[2]);
const meridiem = timeParts[3];
if (meridiem) {
if (meridiem.toLowerCase() === 'pm' && hours !== 12) {
hours += 12;
} else if (meridiem.toLowerCase() === 'am' && hours === 12) {
hours = 0;
}
}
dateObj.setHours(hours, minutes, 0);
}
}
// Format as YYYY-MM-DD HH:MM:SS
return dateObj.toISOString().slice(0, 19).replace('T', ' ');
},
/**
* Collect venue data
*/
collectVenueData: function($form) {
const venueId = $form.find('#saved_tribe_venue').val();
if (venueId && venueId !== '0') {
return { id: venueId };
}
// New venue data
return {
venue: $form.find('input[name="venue[Venue]"]').val(),
address: $form.find('input[name="venue[Address]"]').val(),
city: $form.find('input[name="venue[City]"]').val(),
state_province: $form.find('#StateProvinceText').val(),
zip: $form.find('#EventZip').val(),
country: $form.find('#EventCountry').val(),
phone: $form.find('#EventPhone').val(),
website: $form.find('#EventWebsite').val()
};
},
/**
* Collect organizer data
*/
collectOrganizerData: function($form) {
const organizerId = $form.find('#saved_tribe_organizer').val();
if (organizerId && organizerId !== '0') {
return { id: organizerId };
}
// New organizer data
return {
organizer: $form.find('input[name="organizer[Organizer]"]').val(),
phone: $form.find('#organizer-phone').val(),
email: $form.find('#organizer-email').val(),
website: $form.find('#organizer-website').val()
};
},
/**
* Collect selected categories
*/
collectCategories: function($form) {
const categories = [];
// Checkboxes
$form.find('input[name="tax_input[tribe_events_cat][]"]:checked').each(function() {
categories.push($(this).val());
});
// Multi-select
const selected = $form.find('select[name="tax_input[tribe_events_cat][]"]').val();
if (selected) {
categories.push(...(Array.isArray(selected) ? selected : [selected]));
}
return categories;
},
/**
* Collect tags
*/
collectTags: function($form) {
const tags = [];
const tagInput = $form.find('input[name="tax_input[post_tag]"], #event-tags').val();
if (tagInput) {
// Split by comma and trim
return tagInput.split(',').map(tag => tag.trim()).filter(tag => tag);
}
return tags;
},
/**
* Submit event data via REST API
*/
submitViaRestAPI: function(eventData) {
const self = this;
// Show loading state
this.showLoadingState();
// Determine if we're creating or updating
const isUpdate = this.eventId && this.eventId > 0;
const requestUrl = isUpdate ?
this.apiEndpoint + '/' + this.eventId :
this.apiEndpoint;
const requestMethod = isUpdate ? 'PUT' : 'POST';
console.log('[HVAC REST] ' + (isUpdate ? 'Updating' : 'Creating') + ' event...');
// Prepare form data (REST API requires application/x-www-form-urlencoded)
const formData = new URLSearchParams();
// Add all fields
formData.append('title', eventData.title);
formData.append('description', eventData.description);
formData.append('excerpt', eventData.excerpt); // This is the key field!
formData.append('status', eventData.status);
formData.append('start_date', eventData.start_date);
formData.append('end_date', eventData.end_date);
formData.append('all_day', eventData.all_day ? '1' : '0');
// Add optional fields
if (eventData.cost) formData.append('cost', eventData.cost);
if (eventData.website) formData.append('website', eventData.website);
if (eventData.featured_media) formData.append('featured_media', eventData.featured_media);
// Add venue data
if (eventData.venue.id) {
formData.append('venue[id]', eventData.venue.id);
} else if (eventData.venue.venue) {
Object.keys(eventData.venue).forEach(key => {
formData.append(`venue[${key}]`, eventData.venue[key]);
});
}
// Add organizer data
if (eventData.organizer.id) {
formData.append('organizer[id]', eventData.organizer.id);
} else if (eventData.organizer.organizer) {
Object.keys(eventData.organizer).forEach(key => {
formData.append(`organizer[${key}]`, eventData.organizer[key]);
});
}
// Add categories
eventData.categories.forEach(cat => {
formData.append('categories[]', cat);
});
// Add tags
eventData.tags.forEach(tag => {
formData.append('tags[]', tag);
});
// Make REST API request
$.ajax({
url: requestUrl,
method: requestMethod,
data: formData.toString(),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-WP-Nonce': hvac_ajax.nonce // Use existing nonce
},
success: function(response) {
console.log('[HVAC REST] Event created successfully:', response);
self.handleSuccess(response);
},
error: function(xhr, status, error) {
console.error('[HVAC REST] Event creation failed:', error);
self.handleError(xhr, status, error);
}
});
},
/**
* Show loading state
*/
showLoadingState: function() {
const isUpdate = this.eventId && this.eventId > 0;
const buttonText = isUpdate ? 'Updating Event...' : 'Creating Event...';
const loadingText = isUpdate ?
'Updating your event with all fields...' :
'Creating your event with all fields...';
// Disable submit button
$('button[type="submit"], input[type="submit"]').prop('disabled', true).text(buttonText);
// Show loading indicator
if (!$('#hvac-rest-loading').length) {
$('' + loadingText + '
')
.insertAfter('.tribe-events-community-footer');
}
},
/**
* Handle successful event creation
*/
handleSuccess: function(response) {
const isUpdate = this.eventId && this.eventId > 0;
const successMessage = isUpdate ?
'Event updated successfully with 100% field control!' :
'Event created successfully with 100% field control!';
// Show success message
const successHTML = `
${successMessage}
Event ID: ${response.id}
View Event
`;
$('#tribe-community-events').prepend(successHTML);
// Scroll to top
$('html, body').animate({ scrollTop: 0 }, 'slow');
// Optionally redirect after delay
setTimeout(function() {
if (response.url) {
window.location.href = response.url;
}
}, 3000);
},
/**
* Handle error
*/
handleError: function(xhr, status, error) {
// Show error message
const errorHTML = `
Error creating event: ${error}
Please check the form and try again.
`;
$('#tribe-community-events').prepend(errorHTML);
// Re-enable submit button
$('button[type="submit"], input[type="submit"]').prop('disabled', false).text('Submit Event');
// Remove loading indicator
$('#hvac-rest-loading').remove();
// Log detailed error for debugging
console.error('[HVAC REST] Full error response:', xhr.responseJSON);
},
/**
* Load existing excerpt when editing
*/
loadExistingExcerpt: function() {
const self = this;
// Fetch event data from REST API
$.ajax({
url: this.apiEndpoint + '/' + this.eventId,
method: 'GET',
success: function(response) {
console.log('[HVAC REST] Loaded event data:', response);
// Populate excerpt field if it exists
if (response.excerpt && response.excerpt.rendered) {
const excerptField = $('#event_excerpt');
if (excerptField.length) {
// Strip HTML tags from rendered excerpt
const excerptText = $('').html(response.excerpt.rendered).text();
excerptField.val(excerptText);
console.log('[HVAC REST] Populated excerpt field');
}
}
},
error: function(xhr, status, error) {
console.error('[HVAC REST] Failed to load event data:', error);
}
});
}
};
// Initialize when document is ready
$(document).ready(function() {
if ($('#tribe-community-events').length > 0) {
HVACRestEventSubmission.init();
}
});
})(jQuery);