Difference between revisions of "MediaWiki:Common.js"

From Fellrnr.com, Running tips
Jump to: navigation, search
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 cols;
+
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")){
cols=[];
+
// 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(){
cols.push($(this).text());
+
// Add the data from the nth child to the rows array.
 +
rows.push($(this).text());
 
});
 
});
cols = arrayUnique(cols);
+
// Remove any duplicates from the array
 +
rows = arrayUnique(rows);
 +
// Create a new counter
 
l=0;
 
l=0;
for (j=0; j<cols.length; j++){
+
// Iterate over the rows array to find the longest element, set that length to l
t=charLength(cols[j]);
+
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<cols.length; j++){
+
// Add a button to clear all the checkboxes
$(this).find(".filterMenu").append('<div><input type="checkbox" value="'+cols[j]+'" col="'+(i+1)+'" class="filterOption" checked>'+cols[j]+'</div>')
+
$(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;
}