[ Disclaimer, Create new user --- Wiki markup help, Install P99 ]
Difference between revisions of "MediaWiki:HuntingGuide.js"
From Project 1999 Wiki
| Line 144: | Line 144: | ||
var zoneFilterHandler = function(e) { | var zoneFilterHandler = function(e) { | ||
var zone = $('#zoneFilter').val().toLowerCase(); | var zone = $('#zoneFilter').val().toLowerCase(); | ||
| − | filterSpots( | + | filterSpots('#zoneFilterLabel, filterByZone, zone); |
} | } | ||
| Line 169: | Line 169: | ||
*/ | */ | ||
var selectFilter = function (target) { | var selectFilter = function (target) { | ||
| − | $('.filterLink, .monsterFilterLink, #levelFilterLabel').css({textDecoration: ''}); | + | $('.filterLink, .monsterFilterLink, #levelFilterLabel, #zoneFilterLabel').css({textDecoration: ''}); |
$(target).css({textDecoration: 'underline'}); | $(target).css({textDecoration: 'underline'}); | ||
} | } | ||
Revision as of 19:35, 14 November 2019
// Basic DOM manipulation onReady (since the wiki won't let us add <input> tags in the wiki text
$('#levelFilterPlaceholder').replaceWith('<input id="levelFilter" style="width:30px"/>');
$('#zoneFilterPlaceholder').replaceWith('<input id="zoneFilter" style="width:50em"/>');
// Create filter results table
var $filterResults = $('table.eoTable3.wikitable.sortable').eq(0).clone().hide();
var $headerRow = $('.hunting-guide-row:first').clone();
var clearFilterResults = function() {
return $filterResults.empty()
.append($headerRow);
};
clearFilterResults();
$('h4:contains("Hunting Spots 1-4")').before($filterResults);
// Get jQuery object of every row in the hunting guide (because all of the filter functions need it)
var $rows = $('.wikitable tbody tr');
/**
* Build a in-memory data object with the data parsed from each row (which will tell us which
* levels/classes should be shown for any filter).
* @example a "spot" created by this function for critters in Butcherblock Mountains: {
* soloLevel: '04-06',
* groupLevel: '03-05',
* zone: 'Butcherblock Mountains',
* area: 'Greater Faydark zoneline',
* monsters: 'Assorted Critters ',
* xpMod: '100%',
* notes: '',
* $tr: *a jQuery object pointing to the <tr> that all this data originally came from*
* }
*/
var spots = [];
$rows.each(function (i, el) {
var groupLevel = $(el).children('td:eq(1)').text();
groupLevel = groupLevel.trim() === '-' ? null : groupLevel;
var $tr = $(el);
if ($tr.children('th').length) return; // Header row
spots.push({
soloLevel: $tr.children('td:eq(0)').text(),
groupLevel,
zone: $tr.children('td:eq(2)').text(),
area: $tr.children('td:eq(3)').text(),
monsters: $tr.children('td:eq(4)').text(),
xpMod: $tr.children('td:eq(5)').text(),
era: $tr.children('td:eq(6)').text(),
image: $tr.children('td:eq(7)').text(),
notes: $tr.children('td:eq(8)').text(),
$tr:$tr
});
});
// Clear garbage entries (wish I had ES6 filter ..)
var cleanedSpots = [];
$.each(spots, function (i, spot) {
if (spot.soloLevel && spot.zone) cleanedSpots.push(spot);
});
$('#numSpots').text(cleanedSpots.length);
var filterSpots = function(filterLabel, filter, filterData) {
var showUnfiltered = !filter;
$('h4, .wikitable').toggle(showUnfiltered);
$filterResults.toggle(!showUnfiltered);
if (showUnfiltered) {
$('#levelFilter').val('');
} else {
var filteredSpots = cleanedSpots.filter(function(spot) { return filter(spot, filterData); });
var rows = filteredSpots.map(function(spot) { return spot.$tr; });
var $resultsTbody = clearFilterResults();
$.each(rows, function(i, row) {
var $rowClone = $(row).clone();
$resultsTbody.append($rowClone);
});
}
selectFilter(filterLabel);
};
var filterByClass = function(spot, eqClass) {
var lowerCaseNotes = spot.notes.toLowerCase();
var goodForPattern = new RegExp('good for [^\\.;]*?' + eqClass.toLowerCase());
var greatForPattern = new RegExp('great for [^\\.;]*?' + eqClass.toLowerCase());
var isGood = lowerCaseNotes.match(goodForPattern);
var isGreat = lowerCaseNotes.match(greatForPattern);
return isGood || isGreat;
};
var filterByLevel = function(spot, level) {
var levelRangeText = spot.$tr.children('td:first').text();
var splitLevelRanges = levelRangeText.split('-');
var minLevel = parseInt(splitLevelRanges[0], 10);
var maxLevel = parseInt(splitLevelRanges[1] || splitLevelRanges[0], 10);
return minLevel <= level && maxLevel >= level;
};
var filterByMonster = function(spot, monsterType) {
var monsterPattern = new RegExp(monsterType);
var lowerCaseMonsters = spot.monsters.toLowerCase();
var lowerCaseNotes = spot.notes.toLowerCase();
return lowerCaseMonsters.match(monsterPattern) ||
lowerCaseNotes.match(monsterPattern);
};
var filterByZone = function(spot, zone) {
var lowerCaseZone = spot.zone.toLowerCase();
var zonePattern = new RegExp(zone.toLowerCase());
return lowerCaseZone.match(zonePattern);
};
/**
* Filters out (hides) rows which aren't specifically "good for" the clicked class; also handles
* the "no filter" case (TODO: Make a separate handler/event binding for it)
*/
var classFilterHandler = function(e) {
var eqClass = $(e.target).text();
if (eqClass.trim().toLowerCase() === "no filter") filterSpots(e.target, null);
else filterSpots(e.target, filterByClass, eqClass);
}
/**
* Filter out (hides) rows which aren't for the level the user entered
*/
var levelFilterHandler = function () {
var level = parseInt($('#levelFilter').val(), 10);
filterSpots('#levelFilterLabel', level && filterByLevel, level);
};
/**
* Filters out (hides) rows which don't involve the specified monster type
*/
var monsterFilterHandler = function(e) {
var monsterType = $(e.target).text().toLowerCase();
filterSpots(e.target, filterByMonster, monsterType);
}
/**
* Filters out (hides) rows which don't involve the specified zone
*/
var zoneFilterHandler = function(e) {
var zone = $('#zoneFilter').val().toLowerCase();
filterSpots('#zoneFilterLabel, filterByZone, zone);
}
/**
* Hides the table headers and level range headings for level ranges that have been completely
* filtered out
*/
var hideHeaders = function () {
// If anything got hidden by previous filters, show it (because this filter might not hide it)
$('.wikitable, h4').show();
// Hide the tables
$('.wikitable').each(function(i, table) {
var $table = $(table);
if (!$table.find('tbody').children('tr:visible').length) $table.hide();
});
// Hide the headings
$('h4').hide();
// Hide level range headers
$('h4:first').next('.wikitable').show().find('tr:first').show();
}
/**
* Visually marks the currently-used filter with an underline
*/
var selectFilter = function (target) {
$('.filterLink, .monsterFilterLink, #levelFilterLabel, #zoneFilterLabel').css({textDecoration: ''});
$(target).css({textDecoration: 'underline'});
}
// Bind event handlers
$('.filterLink').click(classFilterHandler);
$('.monsterFilterLink').click(monsterFilterHandler);
$('#levelFilter').change(levelFilterHandler);
$('#zoneFilter').change(zoneFilterHandler);