MediaWiki:Gadget-Filterable.js
跳到导航
跳到搜索
注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
- Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
- Internet Explorer / Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
- Opera:按 Ctrl-F5。
/* experimental filterable table function */ (function(mw, $) { 'use strict'; var filterIdCounter = 0; var filterButtons = []; var filterInputs = []; var fb = new AttrData('filterable'); var fbh = new AttrData('filterable-head'); var fbb = new AttrData('filterable-button'); var fbi = new AttrData('filterable-input'); var fbig = new AttrData('filterable-input-group'); function AttrData(name) { this.name = name; this.classSelector = '.' + name; this.activeClass = name + '-active'; this.idPrefix = name + '-'; this.idSelectorPrefix = '#' + name + '-'; } function FilterButton($filterHead, filterid) { this.id = filterid; var $filterbutton = $('<span title="筛选" id="' + fbb.idPrefix + this.id + '" class="' + fbb.name + '"><i class="fa fa-filter" aria-hidden="true"></i></span>'); $filterHead.append($filterbutton); $filterbutton.click(this.id, function(event) { event.stopPropagation(); var filterinputid = $(this).attr('id').replace(fbb.idPrefix, fbi.idPrefix); for (var i = 0; i <= filterIdCounter; i++) { if (fbi.idPrefix + i === filterinputid) { continue; } if ($(fbi.idSelectorPrefix + i).css('display') !== 'none') { $(fbi.idSelectorPrefix + i).fadeToggle(); } } $('#' + filterinputid).fadeToggle(200); updateFilterableInputPosition(event.data); }); } function FilterInput(filterid) { this.id = filterid; var index = $(fbb.idSelectorPrefix + filterid).parent('th,td').index(); var filterItems = new Set(); var filterInputItemsPart = ''; $(fbb.idSelectorPrefix + filterid).parent('td,th').parent('tr').parent('thead,tbody,tfoot').parent(fb.classSelector).children('tbody').children('tr').each(function() { if ($(this).children('td,th').eq(index).text() && !$(this).children('td,th').eq(index).hasClass(fbh.name)) { filterItems.add($(this).children('td,th').eq(index).text()); } }); if (filterItems.size > 0) { filterInputItemsPart += '<li role="separator"class="divider"></li><li class="dropdown-header">项目筛选:</li><li class="dropdown-content"><div class="btn-group btn-group-justified"role="group"><div class="btn-group btn-group-sm"role="group"><button type="button"class="btn btn-success checkbox-select-all">全选</button></div><div class="btn-group btn-group-sm"role="group"><button type="button"class="btn btn-warning checkbox-clear-all">全清</button></div></div></li><li class="dropdown-content"><div class="checkbox-group list-group">'; filterItems.forEach(function(value) { filterInputItemsPart += '<div class="list-group-item"><input type="checkbox" checked="true" value="' + value + '" /><span title="' + value + '">' + value + '</span></div>'; }); filterInputItemsPart += '</div></li>' } var $filterinput = $('<ul id="' + fbi.idPrefix + filterid + '"class="' + fbig.name + ' dropdown-menu"><li class="dropdown-header">字段筛选:</li><li class="dropdown-content"><div class="input-group input-group-sm"><input type="text"class="' + fbi.name + ' form-control"placeholder="输入筛选字段"/><span class="input-group-btn"><button class="btn btn-warning btn-sm"type="button">清除</button></span></div></li>' + filterInputItemsPart + '</ul>'); $(document.body).append($filterinput); $filterinput.find('.input-group input').keyup(function(event) { var filterid = $(this).parent('.input-group').parent('.dropdown-content').parent(fbig.classSelector).attr('id').match(/[0-9]+/); updateFilterButtonState(filterid); filterTable($(fbb.idSelectorPrefix + filterid).parent('td,th').parent('tr').parent('thead,tbody,tfoot').parent(fb.classSelector)); }); $filterinput.click(function(event) { event.stopPropagation(); }); $filterinput.find('.input-group-btn').click(function(event) { var filterid = $(this).parent('.input-group').parent('.dropdown-content').parent(fbig.classSelector).attr('id').match(/[0-9]+/); $(this).prev().val(''); updateFilterButtonState(filterid); filterTable($(fbb.idSelectorPrefix + filterid).parent('td,th').parent('tr').parent('thead,tbody,tfoot').parent(fb.classSelector)); }); $filterinput.find('.checkbox-group input').click(function(event) { var filterid = $(this).parent('.list-group-item').parent('.checkbox-group').parent('.dropdown-content').parent(fbig.classSelector).attr('id').match(/[0-9]+/); updateFilterButtonState(filterid); filterTable($(fbb.idSelectorPrefix + filterid).parent('td,th').parent('tr').parent('thead,tbody,tfoot').parent(fb.classSelector)); }); $filterinput.find('.checkbox-select-all').click(function(event) { var filterid = $(this).parent('.btn-group').parent('.btn-group').parent('.dropdown-content').parent(fbig.classSelector).attr('id').match(/[0-9]+/); $(fbi.idSelectorPrefix + filterid + ' .checkbox-group input').prop('checked', true); updateFilterButtonState(filterid); filterTable($(fbb.idSelectorPrefix + filterid).parent('td,th').parent('tr').parent('thead,tbody,tfoot').parent(fb.classSelector)); }); $filterinput.find('.checkbox-clear-all').click(function(event) { var filterid = $(this).parent('.btn-group').parent('.btn-group').parent('.dropdown-content').parent(fbig.classSelector).attr('id').match(/[0-9]+/); $(fbi.idSelectorPrefix + filterid + ' .checkbox-group input').prop('checked', false); updateFilterButtonState(filterid); filterTable($(fbb.idSelectorPrefix + filterid).parent('td,th').parent('tr').parent('thead,tbody,tfoot').parent(fb.classSelector)); }); } function updateFilterButtonState(id) { var keyword = $(fbi.idSelectorPrefix + id + ' .input-group input').val(); var items = $(fbi.idSelectorPrefix + id + ' .checkbox-group input:not(:checked)'); if (keyword || items.length) { $(fbb.idSelectorPrefix + id).addClass(fbb.activeClass); } else { $(fbb.idSelectorPrefix + id).removeClass(fbb.activeClass); } } function setupFilterable($filterable) { $filterable.children('thead,tbody,tfoot').children('tr').children(fbh.classSelector).each(function() { filterButtons.push(new FilterButton($(this),filterIdCounter)); filterInputs.push(new FilterInput(filterIdCounter)); filterIdCounter++; }); } function updateFilterableInputPosition(id) { var $filterinput = $(fbi.idSelectorPrefix + id); var $filtericon = $(fbb.idSelectorPrefix + id); var offset = $filtericon.offset(); var top = offset.top + $filtericon.height(); var left = offset.left - ($filterinput.width() / 2); var right = left + $filterinput.width(); var bottom = top + $filterinput.height(); if (left < 0) { left = 0; } else if (right > $(document).width()) { left = $(document).width() - $filterinput.width(); } if (bottom > $(document).height()) { top = $(document).height() - $filterinput.height(); } $filterinput.offset({ top: top, left: left, }); } function filterTable($filterabletable) { if (window.filterTimeoutId) { window.clearTimeout(window.filterTimeoutId); window.filterTimeoutId = null ; } window.filterTimeoutId = window.setTimeout(function() { var filters = {}; $filterabletable.children('thead,tbody,tfoot').children('tr').children('th,td').children(fbb.classSelector).each(function() { var index = $(this).parent('th,td').index(); filters[index] = {}; var $filterInput = $('#' + $(this).attr('id').replace(fbb.idPrefix, fbi.idPrefix)); filters[index].items = []; $filterInput.find('.checkbox-group input:not(:checked)').each(function() { filters[index].items.push($(this).val()); }); filters[index].keyword = $filterInput.find('.input-group input').val().replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); }); $filterabletable.children('tbody').children('tr').each(function() { for (var col in filters) { if (filters.hasOwnProperty(col)) { var $cell = $(this).children('td,th').eq(col); if ($cell.length === 0) { console.log('Filterable: Cannot find target cell(colspan?), skipping...') return; } if ($cell.hasClass(fbh.name)) { return; } var keywordRegex = new RegExp(filters[col].keyword,'i'); if (!keywordRegex.test($cell.text())) { $(this).hide(); return; } for (var item in filters[col].items) { if (filters[col].items[item] == $cell.text()) { $(this).hide(); return; } } } } $(this).show(); }); }, 500); } $(document).ready(function() { if ($(fb.classSelector).length === 0) { return; } console.log('Filterable: Loading module...'); $(fb.classSelector).each(function() { if ($(this).prop('tagName') !== 'TABLE') { console.log('Filterable: Invalid tag found, skipping...'); return; } setupFilterable($(this)); }); $(window).resize(function(event) { for (var i = 0; i <= filterIdCounter; i++) { updateFilterableInputPosition(i); } }); $(window).click(function() { for (var i = 0; i <= filterIdCounter; i++) { if ($(fbi.idSelectorPrefix + i).css('display') !== 'none') { $(fbi.idSelectorPrefix + i).fadeToggle(); } } }); }); }(mediaWiki, jQuery));