Difference between revisions of "MediaWiki:Common.js"
From Fellrnr.com, Running tips
User:Fellrnr (User talk:Fellrnr | contribs) (Created page with "→Any JavaScript here will be loaded for all users on every page load.: /* You might have multiple filterable tables in the same page. It works fine. You can use filterable...") |
User:Fellrnr (User talk:Fellrnr | contribs) |
||
Line 12: | Line 12: | ||
|} | |} | ||
*/ | */ | ||
+ | // Run this function that calls the filterTable() function. | ||
$(function() { | $(function() { | ||
filterTable(); | filterTable(); | ||
Line 18: | Line 19: | ||
function filterTable(){ | function filterTable(){ | ||
+ | // Select any table with the class of filterable and run the following function on each of them | ||
$("table.filterable").each(function(){ | $("table.filterable").each(function(){ | ||
+ | // Initilize a counter i and an empty variable rows | ||
var i=0; | var i=0; | ||
− | var | + | var rows; |
+ | // $(this) is the current table. Find the first child element of each table row, and the data of that child | ||
$(this).find("tr:first-child th, tr:first-child td").each(function(){ | $(this).find("tr:first-child th, tr:first-child td").each(function(){ | ||
+ | // If the selected child has the unfilterable class do nothing | ||
if (!$(this).hasClass("unfilterable")){ | if (!$(this).hasClass("unfilterable")){ | ||
− | + | // Set rows to an empty array | |
+ | rows=[]; | ||
+ | // From the selected child traverse up the DOM to find the closest table element, then find the data from the nth child of that table and run a function on it. | ||
$(this).closest("table").find("tr td:nth-child("+(i+1)+")").each(function(){ | $(this).closest("table").find("tr td:nth-child("+(i+1)+")").each(function(){ | ||
− | + | // Add the data from the nth child to the rows array. | |
+ | rows.push($(this).text()); | ||
}); | }); | ||
− | + | // Remove any duplicates from the array | |
+ | rows = arrayUnique(rows); | ||
+ | // Create a new counter | ||
l=0; | l=0; | ||
− | for (j=0; j< | + | // Iterate over the rows array to find the longest element, set that length to l |
− | t=charLength( | + | for (j=0; j<rows.length; j++){ |
+ | t=charLength(rows[j]); | ||
if (l<t) l=t; | if (l<t) l=t; | ||
} | } | ||
+ | // Edit the HTML of the header to add a show/hide for the filter menu | ||
$(this).css("position","relative"); | $(this).css("position","relative"); | ||
$(this).html('<a href="javascript:void(0)" class="showFilterMenu">'+$(this).html()+'▼</a>'); | $(this).html('<a href="javascript:void(0)" class="showFilterMenu">'+$(this).html()+'▼</a>'); | ||
+ | // Add a HTML div for the menu to the DOM | ||
$(this).append($('<div class="filterMenu" style="position:absolute;top:'+$(this).height()+'px;left:0;width:'+(22+l*7)+'px;text-align:left;padding:5px;border:1px #000 solid;background:#ddd;z-index:1;display:none"></div>')); | $(this).append($('<div class="filterMenu" style="position:absolute;top:'+$(this).height()+'px;left:0;width:'+(22+l*7)+'px;text-align:left;padding:5px;border:1px #000 solid;background:#ddd;z-index:1;display:none"></div>')); | ||
− | for (j=0; j< | + | // Add a button to clear all the checkboxes |
− | $(this).find(".filterMenu").append('<div><input type="checkbox" value="'+ | + | $(this).find(".filterMenu").append('<div><input type="button" value="Clear" col="'+(i+1)+'" class="filterClear"></div>') |
+ | // Iterate over the rows array to add each item to the menu | ||
+ | for (j=0; j<rows.length; j++){ | ||
+ | $(this).find(".filterMenu").append('<div><input type="checkbox" value="'+rows[j]+'" col="'+(i+1)+'" class="filterOption" checked>'+rows[j]+'</div>') | ||
} | } | ||
} | } | ||
+ | // Iterate so the function is called on the next column | ||
i++; | i++; | ||
}); | }); | ||
+ | // Add an attribute to each row called condition that is set to 0 | ||
$(this).find("tr:nth-child(n+1)").attr("condition", 0); | $(this).find("tr:nth-child(n+1)").attr("condition", 0); | ||
}); | }); | ||
+ | |||
+ | // When an item with the class showFilterMenu is clicked run the following funciton | ||
$(".showFilterMenu").click(function(){ | $(".showFilterMenu").click(function(){ | ||
+ | // Check if the filter menu is currently visible, hide if it is visible, show if it is not, while hiding any other open filter menus | ||
if ($(this).parent().find(".filterMenu:visible").length){ | if ($(this).parent().find(".filterMenu:visible").length){ | ||
$(".filterMenu").slideUp(150); | $(".filterMenu").slideUp(150); | ||
Line 52: | Line 73: | ||
} | } | ||
}); | }); | ||
+ | |||
+ | // If a mouse click is released anywhere else on the edocument hide the filter menu | ||
$(document).mouseup(function(e){ | $(document).mouseup(function(e){ | ||
var container = $(".filterMenu"); | var container = $(".filterMenu"); | ||
Line 58: | Line 81: | ||
} | } | ||
}); | }); | ||
+ | |||
+ | // When a filter option is clicked in the menu run a function | ||
$(".filterOption").click(function(){ | $(".filterOption").click(function(){ | ||
+ | // Set the column that the filter goes to | ||
col=$(this).attr("col"); | col=$(this).attr("col"); | ||
+ | // Get the value of the checkbox that was changed | ||
val=$(this).val(); | val=$(this).val(); | ||
+ | // If the checkbox is checked we use positive 1, otherwise use negative 1 (0=show, -1=clear) | ||
if ($(this).is(":checked")) chg=1; else chg=-1; | if ($(this).is(":checked")) chg=1; else chg=-1; | ||
+ | // Find the children of the table (Aka rows) | ||
$(this).closest("table").find("tr:nth-child(n+1)").each(function(){ | $(this).closest("table").find("tr:nth-child(n+1)").each(function(){ | ||
+ | // Check if the data in the column related to the menu is the same as the box that was changed | ||
if ($(this).find("td:nth-child("+col+")").text()==val){ | if ($(this).find("td:nth-child("+col+")").text()==val){ | ||
+ | // Find the condition of the row and add chg to that value | ||
var cond=$(this).attr("condition"); | var cond=$(this).attr("condition"); | ||
cond=Number(cond)+chg; | cond=Number(cond)+chg; | ||
+ | // Set the condition to the new value | ||
$(this).attr("condition", cond); | $(this).attr("condition", cond); | ||
+ | // If the condition is 0 then show the row, else hide the row | ||
if (cond==0) $(this).show(); | if (cond==0) $(this).show(); | ||
else $(this).hide(); | else $(this).hide(); | ||
} | } | ||
+ | }); | ||
+ | }); | ||
+ | |||
+ | // When the clear button is clicked clear all checkboxes and hide all rows | ||
+ | $(".filterClear").click(function(){ | ||
+ | // Find all the rows of the table other than the header and hide them | ||
+ | $(this).closest("table").find("tr:not(:first)").each(function(){ | ||
+ | // Find the condition of the row | ||
+ | $(this).attr("condition", -1); //override previous values (checked or not) | ||
+ | $(this).hide(); | ||
+ | }); | ||
+ | // Get all the checkboxes in the current menu and clear the check | ||
+ | $(this).closest(".filterMenu").find(".filterOption").each(function(){ | ||
+ | $(this).removeAttr("checked"); | ||
}); | }); | ||
}); | }); | ||
} | } | ||
+ | |||
+ | |||
+ | |||
+ | // Takes an array and returns a new array with only unique values | ||
function arrayUnique(a) { | function arrayUnique(a) { | ||
return a.reduce(function(p, c) { | return a.reduce(function(p, c) { | ||
Line 79: | Line 130: | ||
}, []); | }, []); | ||
}; | }; | ||
+ | |||
+ | // Gets the number of chars in a string and returns that number. | ||
function charLength(s){ | function charLength(s){ | ||
return s.length+(encodeURI(s).split(/%..|./).length-1-s.length)/2; | return s.length+(encodeURI(s).split(/%..|./).length-1-s.length)/2; | ||
} | } |
Latest revision as of 14:01, 8 June 2017
/* Any JavaScript here will be loaded for all users on every page load. */ /* You might have multiple filterable tables in the same page. It works fine. You can use filterable with sortable as a combo. However, you CANNOT have a column with both filtering and ordering functions. You have to turn off either one (or both) function in your code like this: {|class="filterable sortable" |- !class="unfilterable"|Unique IDs !class="unfilterable unsortable"|Name !class="unsortable"|Type !Damage Value <!-- This line doesn't work! --> ///Some table content inside/// |} */ // Run this function that calls the filterTable() function. $(function() { filterTable(); } ); function filterTable(){ // Select any table with the class of filterable and run the following function on each of them $("table.filterable").each(function(){ // Initilize a counter i and an empty variable rows var i=0; var rows; // $(this) is the current table. Find the first child element of each table row, and the data of that child $(this).find("tr:first-child th, tr:first-child td").each(function(){ // If the selected child has the unfilterable class do nothing if (!$(this).hasClass("unfilterable")){ // Set rows to an empty array rows=[]; // From the selected child traverse up the DOM to find the closest table element, then find the data from the nth child of that table and run a function on it. $(this).closest("table").find("tr td:nth-child("+(i+1)+")").each(function(){ // Add the data from the nth child to the rows array. rows.push($(this).text()); }); // Remove any duplicates from the array rows = arrayUnique(rows); // Create a new counter l=0; // Iterate over the rows array to find the longest element, set that length to l for (j=0; j<rows.length; j++){ t=charLength(rows[j]); if (l<t) l=t; } // Edit the HTML of the header to add a show/hide for the filter menu $(this).css("position","relative"); $(this).html('<a href="javascript:void(0)" class="showFilterMenu">'+$(this).html()+'▼</a>'); // Add a HTML div for the menu to the DOM $(this).append($('<div class="filterMenu" style="position:absolute;top:'+$(this).height()+'px;left:0;width:'+(22+l*7)+'px;text-align:left;padding:5px;border:1px #000 solid;background:#ddd;z-index:1;display:none"></div>')); // Add a button to clear all the checkboxes $(this).find(".filterMenu").append('<div><input type="button" value="Clear" col="'+(i+1)+'" class="filterClear"></div>') // Iterate over the rows array to add each item to the menu for (j=0; j<rows.length; j++){ $(this).find(".filterMenu").append('<div><input type="checkbox" value="'+rows[j]+'" col="'+(i+1)+'" class="filterOption" checked>'+rows[j]+'</div>') } } // Iterate so the function is called on the next column i++; }); // Add an attribute to each row called condition that is set to 0 $(this).find("tr:nth-child(n+1)").attr("condition", 0); }); // When an item with the class showFilterMenu is clicked run the following funciton $(".showFilterMenu").click(function(){ // Check if the filter menu is currently visible, hide if it is visible, show if it is not, while hiding any other open filter menus if ($(this).parent().find(".filterMenu:visible").length){ $(".filterMenu").slideUp(150); }else{ $(".filterMenu").slideUp(150); $(this).parent().find(".filterMenu").slideDown(150); } }); // If a mouse click is released anywhere else on the edocument hide the filter menu $(document).mouseup(function(e){ var container = $(".filterMenu"); if (!container.is(e.target) && container.has(e.target).length === 0){ container.slideUp(150); } }); // When a filter option is clicked in the menu run a function $(".filterOption").click(function(){ // Set the column that the filter goes to col=$(this).attr("col"); // Get the value of the checkbox that was changed val=$(this).val(); // If the checkbox is checked we use positive 1, otherwise use negative 1 (0=show, -1=clear) if ($(this).is(":checked")) chg=1; else chg=-1; // Find the children of the table (Aka rows) $(this).closest("table").find("tr:nth-child(n+1)").each(function(){ // Check if the data in the column related to the menu is the same as the box that was changed if ($(this).find("td:nth-child("+col+")").text()==val){ // Find the condition of the row and add chg to that value var cond=$(this).attr("condition"); cond=Number(cond)+chg; // Set the condition to the new value $(this).attr("condition", cond); // If the condition is 0 then show the row, else hide the row if (cond==0) $(this).show(); else $(this).hide(); } }); }); // When the clear button is clicked clear all checkboxes and hide all rows $(".filterClear").click(function(){ // Find all the rows of the table other than the header and hide them $(this).closest("table").find("tr:not(:first)").each(function(){ // Find the condition of the row $(this).attr("condition", -1); //override previous values (checked or not) $(this).hide(); }); // Get all the checkboxes in the current menu and clear the check $(this).closest(".filterMenu").find(".filterOption").each(function(){ $(this).removeAttr("checked"); }); }); } // Takes an array and returns a new array with only unique values function arrayUnique(a) { return a.reduce(function(p, c) { if (p.indexOf(c) < 0) p.push(c); return p; }, []); }; // Gets the number of chars in a string and returns that number. function charLength(s){ return s.length+(encodeURI(s).split(/%..|./).length-1-s.length)/2; }