/home/coolpkct/www/websites/alylela.com/wp-content/plugins/wp-db-scout/assets/js/wds-ajax-search.js
/**
* WP DB Scout AJAX Search JavaScript
*/
(function($) {
'use strict';
var WDSSearch = {
searchTimeout: null,
currentRequest: null,
lastSearch: '',
init: function() {
this.bindEvents();
this.updateCharCount();
},
bindEvents: function() {
// Search input with debounce
$('#wds-search-input').on('input', this.handleSearchInput.bind(this));
// Character counter
$('#wds-search-input').on('keyup', this.updateCharCount.bind(this));
// Toggle details
$(document).on('click', '.wds-toggle-details', this.toggleDetails);
// Search options
$('#wds-exclude-system, #wds-use-cache').on('change', function() {
// Re-search if we have a valid search term
var searchTerm = $('#wds-search-input').val();
if (searchTerm.length >= 5) {
WDSSearch.performSearch(searchTerm);
}
});
},
handleSearchInput: function(e) {
var searchTerm = $(e.target).val().trim();
// Clear previous timeout
if (this.searchTimeout) {
clearTimeout(this.searchTimeout);
}
// Cancel current request if exists
if (this.currentRequest && this.currentRequest.readyState !== 4) {
this.currentRequest.abort();
}
// Check minimum length
if (searchTerm.length < 5) {
this.clearResults();
return;
}
// Check maximum length
if (searchTerm.length > 200) {
this.showError(wds_ajax.strings.max_chars || 'Search term must be less than 200 characters');
return;
}
// Debounce search (wait 500ms after user stops typing)
this.searchTimeout = setTimeout(function() {
WDSSearch.performSearch(searchTerm);
}, 500);
},
performSearch: function(searchTerm) {
// Don't search if it's the same as last search
if (searchTerm === this.lastSearch) {
return;
}
this.lastSearch = searchTerm;
// Show loading state
this.showLoading(wds_ajax.strings.searching_database || 'Searching database...');
console.log('WDS: Starting search for:', searchTerm);
// Prepare data
var data = {
action: 'wds_search_database',
nonce: wds_ajax.nonce,
search_term: searchTerm,
exclude_system: $('#wds-exclude-system').is(':checked'),
use_cache: $('#wds-use-cache').is(':checked')
};
console.log('WDS: Request data:', data);
// Perform AJAX request
this.currentRequest = $.ajax({
url: wds_ajax.ajax_url,
type: 'POST',
data: data,
success: function(response) {
console.log('WDS: Response received:', response);
if (response.success) {
WDSSearch.displayResults(response.data);
} else {
var errorMsg = response.data && response.data.message ? response.data.message : wds_ajax.strings.error;
console.error('WDS: Search failed:', errorMsg);
WDSSearch.showError(errorMsg);
}
},
error: function(xhr, status, error) {
if (status !== 'abort') {
console.error('WDS: AJAX error:', status, error);
console.error('WDS: Response text:', xhr.responseText);
WDSSearch.showError(wds_ajax.strings.error);
}
},
complete: function() {
WDSSearch.hideLoading();
}
});
},
displayResults: function(data) {
var $results = $('#wds-search-results');
$results.empty();
// Check if we have database results
if (data.results && data.results.length > 0) {
// Show database results
this.displayDatabaseResults(data);
}
// Check if we have theme results
else if (data.theme_results && Object.keys(data.theme_results).length > 0) {
// Show theme file results
this.displayThemeResults(data);
}
else {
this.showNoResults();
return;
}
},
displayDatabaseResults: function(data) {
var $results = $('#wds-search-results');
// Show summary
$('.wds-results-summary').show();
$('.wds-results-count').text(data.total_matches + ' ' + (wds_ajax.strings.results_found || 'results found') + ' ' + data.count + ' ' + (wds_ajax.strings.table || 'tables'));
$('.wds-searched-term').text(data.search_term);
// Display each table's results
data.results.forEach(function(tableResult) {
var $tableHtml = WDSSearch.createTableResult(tableResult);
$results.append($tableHtml);
});
// Animate appearance
$results.find('.wds-result-table').each(function(index) {
$(this).delay(index * 50).animate({opacity: 1}, 300);
});
},
displayThemeResults: function(data) {
var $results = $('#wds-search-results');
// Show summary for theme results
$('.wds-results-summary').show();
$('.wds-results-count').html('<span class="dashicons dashicons-media-code"></span> Found in theme files');
$('.wds-searched-term').text(data.search_term);
// Add notice about theme search
var $notice = $('<div class="notice notice-info wds-theme-notice">');
$notice.html('<p><span class="dashicons dashicons-info"></span> No database matches found. Showing results from theme files:</p>');
$results.append($notice);
// Display theme results
for (var themeName in data.theme_results) {
var themeFiles = data.theme_results[themeName];
var $themeSection = $('<div class="wds-theme-section">');
$themeSection.append('<h3 class="wds-theme-name"><span class="dashicons dashicons-admin-appearance"></span> Theme: ' + themeName + '</h3>');
themeFiles.forEach(function(fileResult) {
var $fileHtml = WDSSearch.createThemeFileResult(fileResult);
$themeSection.append($fileHtml);
});
$results.append($themeSection);
}
// Animate appearance
$results.find('.wds-file-result').each(function(index) {
$(this).delay(index * 30).animate({opacity: 1}, 200);
});
},
createTableResult: function(tableData) {
var template = document.getElementById('wds-result-template');
var $clone = $(template.content.cloneNode(true));
// Set table info
$clone.find('.table-name').text(tableData.table_name);
$clone.find('.table-rows').text(this.formatNumber(tableData.table_info.rows));
$clone.find('.table-size').text(this.formatBytes(tableData.table_info.size));
$clone.find('.match-count').text(tableData.match_count);
// Add matches
var $matchesContainer = $clone.find('.wds-table-matches');
tableData.matches.forEach(function(match) {
var $matchHtml = WDSSearch.createMatchItem(match);
$matchesContainer.append($matchHtml);
});
return $clone;
},
createThemeFileResult: function(fileData) {
var $fileDiv = $('<div class="wds-file-result">');
// File header
var $header = $('<div class="wds-file-header">');
$header.append('<span class="dashicons dashicons-media-text"></span>');
$header.append('<strong class="wds-file-path">' + fileData.file + '</strong>');
$header.append('<span class="wds-file-meta"> (' + fileData.file_type + ', ' + fileData.matches.length + ' matches)</span>');
$fileDiv.append($header);
// File matches
var $matchesDiv = $('<div class="wds-file-matches">');
fileData.matches.forEach(function(match) {
var $matchItem = $('<div class="wds-file-match">');
// Line number
$matchItem.append('<span class="wds-line-number">Line ' + match.line_number + ':</span>');
// Context with highlighted match
if (match.context && match.context.length > 0) {
var $contextDiv = $('<div class="wds-match-context">');
match.context.forEach(function(contextLine) {
var $line = $('<div class="wds-context-line">');
if (contextLine.is_match) {
$line.addClass('wds-match-line');
$line.html('<span class="line-num">' + contextLine.line_number + ':</span> ' + match.highlighted);
} else {
$line.html('<span class="line-num">' + contextLine.line_number + ':</span> ' + WDSSearch.escapeHtml(contextLine.line));
}
$contextDiv.append($line);
});
$matchItem.append($contextDiv);
} else {
// Just show the highlighted line
$matchItem.append('<div class="wds-match-line">' + match.highlighted + '</div>');
}
$matchesDiv.append($matchItem);
});
$fileDiv.append($matchesDiv);
// Add expand/collapse functionality
$header.on('click', function() {
$matchesDiv.slideToggle();
$(this).toggleClass('collapsed');
});
return $fileDiv;
},
createMatchItem: function(match) {
var template = document.getElementById('wds-match-template');
var $clone = $(template.content.cloneNode(true));
// Set row ID
if (match.row_id) {
$clone.find('.row-id-value').text(match.row_id);
} else {
$clone.find('.wds-row-id').hide();
}
// Add matched columns
var $columnsContainer = $clone.find('.wds-match-columns');
$columnsContainer.empty();
match.matched_columns.forEach(function(col) {
var $colDiv = $('<div class="wds-matched-column">');
$colDiv.append('<strong>' + col.column + ':</strong> ');
$colDiv.append($('<span>').html(col.value));
$columnsContainer.append($colDiv);
});
// Add row data to details
if (match.row_data && Object.keys(match.row_data).length > 0) {
var $dataTable = $clone.find('.wds-data-table');
$dataTable.empty();
for (var key in match.row_data) {
var $row = $('<tr>');
$row.append('<td>' + key + '</td>');
$row.append('<td>' + this.escapeHtml(match.row_data[key]) + '</td>');
$dataTable.append($row);
}
} else {
$clone.find('.wds-row-data').hide();
}
// Add relationships
if (match.relationships && match.relationships.length > 0) {
var $relationList = $clone.find('.wds-relation-list');
$relationList.empty();
match.relationships.forEach(function(rel) {
var $li = $('<li>');
$li.text(rel.table + ' (' + rel.column + ' = ' + rel.value + ')');
$relationList.append($li);
});
} else {
$clone.find('.wds-relationships').hide();
}
return $clone;
},
toggleDetails: function(e) {
e.preventDefault();
var $btn = $(this);
var $details = $btn.closest('.wds-match-item').find('.wds-match-details');
var $icon = $btn.find('.dashicons');
if ($details.is(':visible')) {
$details.slideUp();
$icon.removeClass('dashicons-arrow-up').addClass('dashicons-arrow-down');
} else {
$details.slideDown();
$icon.removeClass('dashicons-arrow-down').addClass('dashicons-arrow-up');
}
},
updateCharCount: function() {
var length = $('#wds-search-input').val().length;
$('.wds-char-count').text(length + ' / 200');
if (length < 5) {
$('.wds-char-count').css('color', '#999');
} else if (length > 190) {
$('.wds-char-count').css('color', '#d32f2f');
} else {
$('.wds-char-count').css('color', '#4caf50');
}
},
showLoading: function(message) {
$('.wds-search-status-bar').show();
$('.wds-search-status-bar').text(message || wds_ajax.strings.searching || 'Searching...');
$('.wds-results-summary').hide();
$('#wds-search-results').css('opacity', '0.5');
},
hideLoading: function() {
$('.wds-search-status-bar').hide();
$('#wds-search-results').css('opacity', '1');
},
showNoResults: function() {
$('.wds-results-summary').hide();
$('#wds-search-results').empty();
},
showError: function(message) {
this.hideLoading();
$('#wds-search-results').html(
'<div class="notice notice-error"><p>' + message + '</p></div>'
);
},
clearResults: function() {
$('#wds-search-results').empty();
$('.wds-results-summary').hide();
this.lastSearch = '';
},
formatNumber: function(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
},
formatBytes: function(bytes) {
if (bytes === 0) return '0 Bytes';
var k = 1024;
var sizes = ['Bytes', 'KB', 'MB', 'GB'];
var i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
},
escapeHtml: function(text) {
if (text === null || text === undefined) {
return '';
}
var map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.toString().replace(/[&<>"']/g, function(m) {
return map[m];
});
}
};
// Initialize when document is ready
$(document).ready(function() {
WDSSearch.init();
});
// Export for global use
window.WDSSearch = WDSSearch;
})(jQuery);