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

Event Summary

Brief summary for search results and previews (excerpt)

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