Files
Hi-School-Slide-Manager/assets/js/admin-sortable.js
T

207 lines
6.7 KiB
JavaScript

/**
* Hi-School Slide Manager - Admin Sortable functionality
*
* Handles drag-and-drop ordering of slides in the admin list table
*/
jQuery(document).ready(function($) {
'use strict';
// Only initialize on the slides list page
if (typeof hssmAjax === 'undefined' || !$('.wp-list-table tbody').length) {
return;
}
// Initialize sortable functionality
initializeSortable();
/**
* Initialize jQuery UI sortable on the slides table
*/
function initializeSortable() {
const $tbody = $('.wp-list-table tbody');
// Make the table body sortable
$tbody.sortable({
handle: '.hssm-drag-handle',
placeholder: 'ui-sortable-placeholder',
helper: function(e, tr) {
var $helper = tr.clone();
$helper.children().each(function(index) {
$(this).width(tr.children().eq(index).width());
});
return $helper;
},
start: function(e, ui) {
ui.placeholder.height(ui.item.height());
ui.item.addClass('ui-sortable-helper');
},
stop: function(e, ui) {
ui.item.removeClass('ui-sortable-helper');
updateSlideOrder();
},
tolerance: 'pointer',
cursor: 'move',
opacity: 0.8,
distance: 5
});
// Add visual feedback
$tbody.on('mouseenter', '.hssm-drag-handle', function() {
$(this).closest('tr').addClass('hssm-sortable-hover');
});
$tbody.on('mouseleave', '.hssm-drag-handle', function() {
$(this).closest('tr').removeClass('hssm-sortable-hover');
});
// Add CSS for hover effect
if (!$('#hssm-sortable-styles').length) {
$('<style id="hssm-sortable-styles">')
.text(`
.wp-list-table tbody tr.hssm-sortable-hover {
background-color: #f0f8ff;
}
.wp-list-table .hssm-drag-handle {
opacity: 0.6;
transition: opacity 0.2s ease;
}
.wp-list-table .hssm-drag-handle:hover {
opacity: 1;
}
.wp-list-table tbody tr.ui-sortable-helper td {
background-color: #f9f9f9;
border-color: #0073aa;
}
`)
.appendTo('head');
}
}
/**
* Update slide order via AJAX
*/
function updateSlideOrder() {
const slideIds = [];
// Collect all slide IDs in their new order
$('.wp-list-table tbody tr').each(function() {
const postId = $(this).attr('id');
if (postId && postId.startsWith('post-')) {
const slideId = parseInt(postId.replace('post-', ''));
if (slideId) {
slideIds.push(slideId);
}
}
});
if (slideIds.length === 0) {
return;
}
// Show loading indicator
showLoadingIndicator();
// Send AJAX request to update order
$.ajax({
url: hssmAjax.ajaxurl,
type: 'POST',
data: {
action: 'hssm_update_slide_order',
nonce: hssmAjax.nonce,
slide_ids: slideIds
},
success: function(response) {
hideLoadingIndicator();
if (response.success) {
showNotification('Slide order updated successfully!', 'success');
// Update the order column values
updateOrderColumnValues(slideIds);
} else {
showNotification('Failed to update slide order: ' + (response.data?.message || 'Unknown error'), 'error');
}
},
error: function(xhr, status, error) {
hideLoadingIndicator();
showNotification('Error updating slide order: ' + error, 'error');
}
});
}
/**
* Update the order column values in the table
*/
function updateOrderColumnValues(slideIds) {
slideIds.forEach(function(slideId, index) {
const $row = $('#post-' + slideId);
const $orderCell = $row.find('.column-order');
if ($orderCell.length) {
$orderCell.text(index);
}
});
}
/**
* Show loading indicator
*/
function showLoadingIndicator() {
if ($('#hssm-loading-indicator').length === 0) {
$('<div id="hssm-loading-indicator" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0,0,0,0.8); color: white; padding: 20px; border-radius: 5px; z-index: 9999; font-size: 16px;">')
.html('<span class="dashicons dashicons-update" style="animation: rotation 1s infinite linear; margin-right: 10px;"></span> Updating slide order...')
.appendTo('body');
}
}
/**
* Hide loading indicator
*/
function hideLoadingIndicator() {
$('#hssm-loading-indicator').remove();
}
/**
* Show notification message
*/
function showNotification(message, type) {
const $notice = $('<div class="notice notice-' + type + ' is-dismissible hssm-notice">')
.html('<p>' + message + '</p>')
.hide();
// Insert after the page title
$('.wrap h1').first().after($notice);
// Animate in
$notice.slideDown(300);
// Add dismiss functionality
$notice.on('click', '.notice-dismiss', function() {
$notice.slideUp(300, function() {
$(this).remove();
});
});
// Auto-dismiss success messages after 3 seconds
if (type === 'success') {
setTimeout(function() {
$notice.find('.notice-dismiss').click();
}, 3000);
}
}
// Add rotation animation for loading spinner
if (!$('#hssm-animation-styles').length) {
$('<style id="hssm-animation-styles">')
.text(`
@keyframes rotation {
from { transform: rotate(0deg); }
to { transform: rotate(359deg); }
}
.hssm-notice {
margin: 10px 0;
}
`)
.appendTo('head');
}
});