MediaWiki:Gadget-listFilter.js

From Another Eden Wiki

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
mw.loader.using( 'oojs-ui-core' ).done( function () {
	$(document).ready(function() {
		// Render search text field elements. See [[Template:Search]]
		var searchContainers = document.getElementsByClassName('search-text-container');
		
		// It's possible for the Search template to be used multiple times
		// So get all search text containers and loop through each of them.
		for (var i = 0; i < searchContainers.length; i++) {
			var dataKey = searchContainers[i].attributes['data-key'].value.toLowerCase();
			var placeholder = searchContainers[i].attributes['data-placeholder'].value;
			var search = new OO.ui.SearchInputWidget( {
				placeholder: placeholder
			} );
			
			$( search.$element ).children("input").addClass( "search-text" );
			$( search.$element ).children("input").attr( "data-key", dataKey );
			// Hacky way to update the HTML value
			$( search.$element ).children("input").keyup(function() {
                $(this).attr('value', $(this).val());
            } );
			$( searchContainers[i] ).html( search.$element );
		}
		
		// Get the filters and search text fields on the page
		var filterButtons = document.getElementsByClassName('filter-button');
		var searchFields = document.getElementsByClassName('search-text');

		// Add the event listeners to the filters and search text fields
		for (var i = 0; i < filterButtons.length; i++) {
			filterButtons[i].addEventListener("click", function(e) {
				//check if its reset button
				if (this.classList.contains('filter-reset')) {
					var listSelected = document.getElementsByClassName('filter-button-selected');
					var deafultSelected = document.getElementsByClassName('default-selected');
					for (var i = 0; i < listSelected.length; i++) 
					while(listSelected.length > 0) {
						listSelected[0].classList.remove('filter-button-selected');
					} 
					for (var i = 0; i < deafultSelected.length; i++) {
						deafultSelected[i].classList.add('filter-button-selected');
					}
				} else {
				    // Toggle the select class
					if (this.classList.contains('filter-button-selected')) {
						this.classList.remove('filter-button-selected');
					} else {
						this.classList.add('filter-button-selected');
					}
				}
				filter();
			});
		}
		filter();
		
		for (var i = 0; i < searchFields.length; i++) {
			searchFields[i].addEventListener("keyup", function(e) {
				filter();	
			});
		}
		
		function filter() {
			//Get all filter groups on the page
			//var filterGroupsN = document.getElementsByClassName('mw-ui-button-group');
			var filterGroupsN = document.querySelectorAll('[class*="filter-group-"]');
			//filterGroups=Array.prototype.slice.call(filterGroupsN,0);
			filterGroups=Array.prototype.slice.call(filterGroupsN,0).filter(function (el) {
				return !(el.classList.contains('group-strict'));
    		});
    		filterGroupsStrict=Array.prototype.slice.call(filterGroupsN,0).filter(function (el) {
				return (el.classList.contains('group-strict'));
    		});
			
			var searchFields = document.getElementsByClassName('search-text');
			
			//Get filter list
			var list = document.getElementsByClassName('filter-element');
			for (var i = 0; i < list.length; i++) {
				list[i].style.display = 'none';
			}
			
			//Loop through all filter groups
			var isFilterStrict = false;
			for (var i = 0; i < filterGroups.length; i++) {
				var selectedFilters = filterGroups[i].getElementsByClassName('filter-button-selected');
				list = filterList(selectedFilters, list, isFilterStrict);
			}
			//Loop through AND filter "role" groups
			var selectedFiltersStrict=[];
			for (var i = 0; i < filterGroupsStrict.length; i++) {
				isFilterStrict = true;
				var selectedFilterStrict = filterGroupsStrict[i].getElementsByClassName('filter-button-selected');
				  for (var j=0; j < selectedFilterStrict.length; j++) {
				  	selectedFiltersStrict.push(selectedFilterStrict[j]);
				  }
			}
			list = filterList(selectedFiltersStrict, list, isFilterStrict);
			
			// Loop through all the searches
			for (var i = 0; i < searchFields.length; i++) {
				list = searchList(searchFields[i], list);
			}
			
			// Go through and display the elements still in the filtered list
			for (var i = 0; i < list.length; i++) {
				list[i].style.display = '';	
			}
		}
		
		function filterList(selectedFilters, list, strict) {
			if (!list.length || !selectedFilters.length) {
				return list;
			}
			
			var dataKey = '';
			var selectedFilterValues = [];
			
			for (var i = 0; i < selectedFilters.length; i++) {
				var dataKey = selectedFilters[i].attributes['data-key'].value;
				var filterValue = String(selectedFilters[i].dataset.value).toLowerCase();
				selectedFilterValues.push(filterValue);
			}
			
			var filteredList = [];
			
			for (var i = 0; i < list.length; i++) {
				var elementDataValue = String(list[i].dataset[dataKey]).toLowerCase();
				if (strict) {
					console.log("Strict-Roles:",elementDataValue);
					console.log("Strict-Filters:",selectedFilterValues);
					//new code - check each DataValue for each searchValue (strict filter)
					var containsAllFilters = false; //by default result is disabled
					var dataValues = elementDataValue.split(',');
					for (var dataCount = 0; dataCount < dataValues.length; dataCount++) {
					    var dataValue = dataValues[dataCount].trim();
					    var allFiltersFoundInDataValue = true; //default enabled, dissable on any failed search
					    
					    for (var filterCount = 0; filterCount < selectedFilterValues.length; filterCount++) {
					        var filterValue = selectedFilterValues[filterCount];
					        console.log(filterValue,' in dataValue=',dataValue,'; Results',dataValue.includes(filterValue));
							//If current dataValue has no filterValue - dissable and skip to next dataValue
					        if (!dataValue.includes(filterValue)) {
					            allFiltersFoundInDataValue = false;
					            break;
					        }
					    }
					    //If any DataValue had all filtersValues and is still enabled - enable main element
					    //and skip all next DataValues checks
					    if (allFiltersFoundInDataValue) {
					        containsAllFilters = true;
					        break;
					    }
					}
					//if enabled add element to resulting List
					console.log(containsAllFilters);
					if (containsAllFilters) {
						filteredList.push(list[i]);	
					}
				} else if (elementDataValue.includes(',')) {
					//old code - find any value inside filter group
					for (var count = 0; count < selectedFilterValues.length; count++) {
						if (elementDataValue.includes(selectedFilterValues[count])) {
							filteredList.push(list[i]);
							continue;
						}
					}
				} else {
					if (selectedFilterValues.includes(elementDataValue)) {
						filteredList.push(list[i]);
					}	
				}
			}

			return filteredList;
		}
		
		function searchList(searchField, list) {
			var dataKey = searchField.attributes['data-key'].value;
			var searchText = searchField.value.toLowerCase();
			
			if (searchText.length <= 0) {
				return list;
			}
			
			var filteredList = [];
			
			for (var i = 0; i < list.length; i++) {
				var elementDataValue = String(list[i].dataset[dataKey]).toLowerCase();
				if (elementDataValue.includes(searchText)) {
					filteredList.push(list[i]);	
				}
			}
			
			return filteredList;
		}
	} );
} );