- Refactored registration form:
* Moved Application Details to Personal Information section
* Renamed Business Information to Training Organization Information
* Added required Organization Logo upload with media library integration
* Added Headquarters location fields (City, State/Province, Country)
* Moved training-related fields into Organization section
* Created conditional Training Venue Information section with auto-population
- Created comprehensive venue management system:
* Training Venues List page (/trainer/venue/list) with filtering and pagination
* Manage Venue page (/trainer/venue/manage) for create/edit operations
* Full integration with The Events Calendar venue post type
* AJAX-powered forms with real-time validation
- Created trainer profile system:
* Trainer Profile view page (/trainer/profile) with stats and certifications
* Profile Edit page (/trainer/profile/edit) with photo upload
* Years of experience tracking and professional information
* Integration with user meta and custom fields
- Created training organizers management:
* Organizers List page (/trainer/organizer/list) with search functionality
* Manage Organizer page (/trainer/organizer/manage) for CRUD operations
* Organization logo upload and headquarters tracking
* Full integration with The Events Calendar organizer post type
- Technical improvements:
* Modular PHP class architecture for each feature
* Comprehensive AJAX handlers with security nonces
* Responsive CSS design for all new pages
* JavaScript form validation and dynamic behavior
* Proper WordPress and TEC API integration
All new features follow hierarchical URL structure and include breadcrumb navigation.
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
364 lines
No EOL
13 KiB
JavaScript
364 lines
No EOL
13 KiB
JavaScript
/**
|
|
* HVAC Organizers JavaScript
|
|
*
|
|
* @package HVAC_Community_Events
|
|
* @version 2.0.0
|
|
*/
|
|
|
|
jQuery(document).ready(function($) {
|
|
// Cache DOM elements
|
|
const $organizerForm = $('#hvac-organizer-form');
|
|
const $uploadButton = $('#hvac-upload-logo');
|
|
const $removeButton = $('#hvac-remove-logo');
|
|
const $logoIdField = $('#org_logo_id');
|
|
const $currentLogo = $('.hvac-current-logo');
|
|
const $deleteButton = $('#hvac-delete-organizer');
|
|
|
|
// Form validation
|
|
function validateOrganizerForm() {
|
|
let isValid = true;
|
|
const errors = [];
|
|
|
|
// Clear previous errors
|
|
$('.hvac-form-error').removeClass('hvac-form-error');
|
|
$('.hvac-error-message').remove();
|
|
|
|
// Required fields
|
|
const requiredFields = [
|
|
{ id: 'org_name', label: 'Organization Name' },
|
|
{ id: 'hq_city', label: 'Headquarters City' },
|
|
{ id: 'hq_state', label: 'Headquarters State/Province' },
|
|
{ id: 'hq_country', label: 'Headquarters Country' }
|
|
];
|
|
|
|
requiredFields.forEach(field => {
|
|
const $field = $('#' + field.id);
|
|
const value = $field.val();
|
|
|
|
if (!value || value.trim() === '') {
|
|
isValid = false;
|
|
errors.push(field.label + ' is required');
|
|
$field.addClass('hvac-form-error');
|
|
$field.after('<span class="hvac-error-message">' + field.label + ' is required</span>');
|
|
}
|
|
});
|
|
|
|
// Validate email if provided
|
|
const email = $('#org_email').val();
|
|
if (email && !isValidEmail(email)) {
|
|
isValid = false;
|
|
errors.push('Please enter a valid email address');
|
|
$('#org_email').addClass('hvac-form-error');
|
|
$('#org_email').after('<span class="hvac-error-message">Please enter a valid email address</span>');
|
|
}
|
|
|
|
// Validate phone format if provided
|
|
const phone = $('#org_phone').val();
|
|
if (phone && !isValidPhone(phone)) {
|
|
isValid = false;
|
|
errors.push('Please enter a valid phone number');
|
|
$('#org_phone').addClass('hvac-form-error');
|
|
$('#org_phone').after('<span class="hvac-error-message">Please enter a valid phone number</span>');
|
|
}
|
|
|
|
// Validate website URL if provided
|
|
const website = $('#org_website').val();
|
|
if (website && !isValidURL(website)) {
|
|
isValid = false;
|
|
errors.push('Please enter a valid website URL');
|
|
$('#org_website').addClass('hvac-form-error');
|
|
$('#org_website').after('<span class="hvac-error-message">Please enter a valid website URL</span>');
|
|
}
|
|
|
|
return isValid;
|
|
}
|
|
|
|
// Email validation
|
|
function isValidEmail(email) {
|
|
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
return re.test(email);
|
|
}
|
|
|
|
// Phone validation
|
|
function isValidPhone(phone) {
|
|
const digits = phone.replace(/\D/g, '');
|
|
return digits.length >= 10 && digits.length <= 15;
|
|
}
|
|
|
|
// URL validation
|
|
function isValidURL(url) {
|
|
try {
|
|
new URL(url);
|
|
return true;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Show message
|
|
function showMessage(message, type = 'success') {
|
|
const messageClass = type === 'success' ? 'hvac-message-success' : 'hvac-message-error';
|
|
const $message = $('<div class="hvac-message ' + messageClass + '">' + message + '</div>');
|
|
|
|
// Remove any existing messages
|
|
$('.hvac-message').remove();
|
|
|
|
// Add new message
|
|
$('.hvac-page-header').after($message);
|
|
|
|
// Auto-hide success messages after 5 seconds
|
|
if (type === 'success') {
|
|
setTimeout(function() {
|
|
$message.fadeOut(function() {
|
|
$(this).remove();
|
|
});
|
|
}, 5000);
|
|
}
|
|
|
|
// Scroll to top
|
|
$('html, body').animate({
|
|
scrollTop: $('.hvac-page-header').offset().top - 100
|
|
}, 300);
|
|
}
|
|
|
|
// Handle organizer form submission
|
|
if ($organizerForm.length) {
|
|
$organizerForm.on('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
// Validate form
|
|
if (!validateOrganizerForm()) {
|
|
return false;
|
|
}
|
|
|
|
// Disable submit button
|
|
const $submitButton = $organizerForm.find('button[type="submit"]');
|
|
const originalText = $submitButton.text();
|
|
$submitButton.prop('disabled', true).text('Saving...');
|
|
|
|
// Gather form data
|
|
const formData = {
|
|
action: 'hvac_save_organizer',
|
|
nonce: hvacOrganizers.nonce,
|
|
organizer_id: $('input[name="organizer_id"]').val(),
|
|
org_name: $('#org_name').val(),
|
|
org_description: $('#org_description').val(),
|
|
hq_city: $('#hq_city').val(),
|
|
hq_state: $('#hq_state').val(),
|
|
hq_country: $('#hq_country').val(),
|
|
org_phone: $('#org_phone').val(),
|
|
org_email: $('#org_email').val(),
|
|
org_website: $('#org_website').val(),
|
|
org_logo_id: $('#org_logo_id').val()
|
|
};
|
|
|
|
// Send AJAX request
|
|
$.ajax({
|
|
url: hvacOrganizers.ajax_url,
|
|
type: 'POST',
|
|
data: formData,
|
|
success: function(response) {
|
|
if (response.success) {
|
|
showMessage(response.data.message, 'success');
|
|
|
|
// If creating new organizer, update form to edit mode
|
|
if (!formData.organizer_id && response.data.organizer_id) {
|
|
$('input[name="organizer_id"]').val(response.data.organizer_id);
|
|
$('.hvac-page-header h1').text('Edit Organizer');
|
|
$('.hvac-breadcrumb').html('<a href="/trainer/dashboard/">Trainer</a> > <a href="/trainer/organizer/list/">Organizers</a> > Edit');
|
|
|
|
// Add delete button if not present
|
|
if (!$('#hvac-delete-organizer').length) {
|
|
const deleteButton = '<button type="button" id="hvac-delete-organizer" class="hvac-button hvac-button-danger" data-organizer-id="' + response.data.organizer_id + '">Delete Organizer</button>';
|
|
$('.hvac-form-actions').append(deleteButton);
|
|
}
|
|
}
|
|
|
|
// Update button text
|
|
$submitButton.text('Update Organizer');
|
|
} else {
|
|
showMessage(response.data || 'An error occurred while saving the organizer.', 'error');
|
|
}
|
|
},
|
|
error: function() {
|
|
showMessage('An error occurred. Please try again.', 'error');
|
|
},
|
|
complete: function() {
|
|
// Re-enable submit button
|
|
$submitButton.prop('disabled', false).text(originalText);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Handle logo upload
|
|
if ($uploadButton.length) {
|
|
let mediaUploader;
|
|
|
|
$uploadButton.on('click', function(e) {
|
|
e.preventDefault();
|
|
|
|
// If the media uploader already exists, open it
|
|
if (mediaUploader) {
|
|
mediaUploader.open();
|
|
return;
|
|
}
|
|
|
|
// Create the media uploader
|
|
mediaUploader = wp.media({
|
|
title: 'Choose Organization Logo',
|
|
button: {
|
|
text: 'Use this logo'
|
|
},
|
|
multiple: false,
|
|
library: {
|
|
type: 'image'
|
|
}
|
|
});
|
|
|
|
// When an image is selected, run a callback
|
|
mediaUploader.on('select', function() {
|
|
const attachment = mediaUploader.state().get('selection').first().toJSON();
|
|
|
|
// Update the logo preview
|
|
$currentLogo.html('<img src="' + attachment.sizes.medium.url + '" alt="Organization logo" />');
|
|
|
|
// Update the hidden field
|
|
$logoIdField.val(attachment.id);
|
|
|
|
// Update button text
|
|
$uploadButton.text('Change Logo');
|
|
|
|
// Show remove button if not already visible
|
|
if (!$('#hvac-remove-logo').length) {
|
|
const removeBtn = '<button type="button" id="hvac-remove-logo" class="hvac-button hvac-button-danger-outline">Remove Logo</button>';
|
|
$uploadButton.after(removeBtn);
|
|
}
|
|
});
|
|
|
|
// Open the media uploader
|
|
mediaUploader.open();
|
|
});
|
|
}
|
|
|
|
// Handle logo removal
|
|
$(document).on('click', '#hvac-remove-logo', function(e) {
|
|
e.preventDefault();
|
|
|
|
// Clear the logo preview
|
|
$currentLogo.html('<div class="hvac-logo-placeholder-large"><span>No logo uploaded</span></div>');
|
|
|
|
// Clear the hidden field
|
|
$logoIdField.val('');
|
|
|
|
// Update button text
|
|
$uploadButton.text('Upload Logo');
|
|
|
|
// Remove the remove button
|
|
$(this).remove();
|
|
});
|
|
|
|
// Handle organizer deletion
|
|
$(document).on('click', '#hvac-delete-organizer', function(e) {
|
|
e.preventDefault();
|
|
|
|
const $deleteButton = $(this);
|
|
const organizerId = $deleteButton.data('organizer-id');
|
|
|
|
if (!organizerId) {
|
|
showMessage('Invalid organizer ID', 'error');
|
|
return;
|
|
}
|
|
|
|
// Confirm deletion
|
|
if (!confirm('Are you sure you want to delete this organizer? This action cannot be undone.')) {
|
|
return;
|
|
}
|
|
|
|
// Disable button
|
|
$deleteButton.prop('disabled', true).text('Deleting...');
|
|
|
|
// Send delete request
|
|
$.ajax({
|
|
url: hvacOrganizers.ajax_url,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'hvac_delete_organizer',
|
|
nonce: hvacOrganizers.nonce,
|
|
organizer_id: organizerId
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
showMessage(response.data || 'Organizer deleted successfully.', 'success');
|
|
|
|
// Redirect to organizers list after 2 seconds
|
|
setTimeout(function() {
|
|
window.location.href = '/trainer/organizer/list/';
|
|
}, 2000);
|
|
} else {
|
|
showMessage(response.data || 'Failed to delete organizer.', 'error');
|
|
// Re-enable button
|
|
$deleteButton.prop('disabled', false).text('Delete Organizer');
|
|
}
|
|
},
|
|
error: function() {
|
|
showMessage('An error occurred. Please try again.', 'error');
|
|
// Re-enable button
|
|
$deleteButton.prop('disabled', false).text('Delete Organizer');
|
|
}
|
|
});
|
|
});
|
|
|
|
// Real-time validation
|
|
$('#org_email').on('blur', function() {
|
|
const email = $(this).val();
|
|
$('.hvac-error-message', $(this).parent()).remove();
|
|
$(this).removeClass('hvac-form-error');
|
|
|
|
if (email && !isValidEmail(email)) {
|
|
$(this).addClass('hvac-form-error');
|
|
$(this).after('<span class="hvac-error-message">Please enter a valid email address</span>');
|
|
}
|
|
});
|
|
|
|
$('#org_phone').on('blur', function() {
|
|
const phone = $(this).val();
|
|
$('.hvac-error-message', $(this).parent()).remove();
|
|
$(this).removeClass('hvac-form-error');
|
|
|
|
if (phone && !isValidPhone(phone)) {
|
|
$(this).addClass('hvac-form-error');
|
|
$(this).after('<span class="hvac-error-message">Please enter a valid phone number</span>');
|
|
}
|
|
});
|
|
|
|
$('#org_website').on('blur', function() {
|
|
const website = $(this).val();
|
|
$('.hvac-error-message', $(this).parent()).remove();
|
|
$(this).removeClass('hvac-form-error');
|
|
|
|
if (website && !isValidURL(website)) {
|
|
$(this).addClass('hvac-form-error');
|
|
$(this).after('<span class="hvac-error-message">Please enter a valid website URL</span>');
|
|
}
|
|
});
|
|
|
|
// Auto-format phone number
|
|
$('#org_phone').on('input', function() {
|
|
let value = $(this).val().replace(/\D/g, '');
|
|
|
|
if (value.length > 0) {
|
|
if (value.length <= 3) {
|
|
value = value;
|
|
} else if (value.length <= 6) {
|
|
value = value.slice(0, 3) + '-' + value.slice(3);
|
|
} else if (value.length <= 10) {
|
|
value = value.slice(0, 3) + '-' + value.slice(3, 6) + '-' + value.slice(6);
|
|
} else {
|
|
value = value.slice(0, 3) + '-' + value.slice(3, 6) + '-' + value.slice(6, 10);
|
|
}
|
|
}
|
|
|
|
$(this).val(value);
|
|
});
|
|
}); |