/************************************************************************ @name : xlstablefilter - jquery plugin @type : jquery ui @revison : 1.0.1 @date : 08/30/2013 @author : jkelley - (www.myjqueryplugins.com - www.alpixel.fr) @license : open source - mit license : http://www.opensource.org/licenses/mit-license.php *************************************************************************/ /** * * @description create an excel style filter dialog on a table containing headers * * @example $('table').xlstablefilter(); * @desc create a simple xlstablefilter interface. * * @example $('table').xlstablefilter({ ignorecolumns: [0, 3, 5] }); * @desc create an xlstablefilter interface and but do not make the first, fourth, and sixth column headers filterable. * * @example $('table').tablesorter({ checkstyle: "custom", rowsdisplay: "filterdisplay" }); * @desc create an xlstablefilter interface and use custom checkboxes defined in the xlstablefilter css style sheet. print * the number of rows displayed in an html element with the id "filterdisplay". * * * @param object * settings an object literal containing key/value pairs to provide * optional settings. * * * @option integer width (optional) an integer setting the width of the filter dialog. default: 400. * * @option integer height (optional) an integer setting the height of the filter dialog. default: 550. * * @option integer maxheight (optional) an integer setting the maximum height of the filter dialog. default: window height. * * @option boolean ignorecase (optional) a boolean setting whether the filter should ignore case. default: true. * * @option string checkstyle (optional) a string defining whether the dialog should use html checkboxes or * custom on/off images. "default" will use html checkboxes. "custom" will use images. default: default. * * @option array ignorecolumns (optional) an array containing zero-based column indexes that will not have filters * assigned. default: empty. * * @option array onlycolumns (optional) an array containing zero-based column indexes that will always have filters * assigned. overrides ignorecolumns. if set, then only columns in this array will be assigned filters. default: null. * * @option string or object rowsdisplay (optional) an element to print the number of rows displayed in. if a string is * specified, the element with that id will be used. default: "xlstablefilterrowsdisplay". * * **/ /** xlstablefilter plugin **/ ;(function($) { $.widget("ui.xlstablefilter", { /************** * options **************/ options: { width: 400, height: 550, maxheight: $(window).height(), ignorecase: true, checkstyle: "default", ignorecolumns: [], onlycolumns: null, rowsdisplay: "xlstablefilterrowsdisplay", }, /* object stores current filter settings */ filters: {}, /* id of the element the plugin was called on */ elid: null, /***************** * constructor method *****************/ _create: function() { /* vars **/ var self = this, el = self.element,//表格对象 //headers = $(el).find("th"); headers = $('table.datatable thead th i');//获取图标点击对象 /* set up the filters storage for this element */ self.elid = el.prop("id");//存储表格对象id到elid属性 self.filters[self.elid] = {}; /* add filter method to table headers 遍历图标对象*/ $.each(headers, function(i, h) { //console.log(headers); var filterable = ((self.options.onlycolumns == null && jquery.inarray(i, self.options.ignorecolumns) == -1) || jquery.inarray(i, self.options.onlycolumns) !== -1 ? true : false); if (filterable == true) { $(this).parent().addclass("xlsfilterheader");//给表头th对象添加类 $(this).click(function(e) { self._openfilter($(this));//图标点击事件,调用打开筛选框方法,传递i标签图标对象 }); } else { $(this).parent().addclass("xlsnofilterheader"); } }); self._printrowsdisplayed(); }, /**************************** * xlstablefilter methods below ****************************/ /* open the filter dialog 打开筛选框方法*/ _openfilter: function(header) { var self = this; var colnum = ( number(header.attr('name')) + 1); var filtercontent = this._getfiltercontent(header); var filterdiv = this._createdialogdiv("divxlsfilter", "filter - " + header.text(), filtercontent); this._setupfilter(); $(filterdiv).dialog({ resizable: false, autoopen: true, width: self.options.width, height: self.options.height, maxheight: self.options.maxheight, modal: true, show: 400, hide: 400, buttons: { "filter": function () { self._filtertable(colnum); $(this).dialog("close"); }, "cancel": function () { $(this).dialog("close"); return false; } }, close: function() { $( this ).dialog( "destroy" ); $(this).remove(); } }); }, /* build the html content of the filter dialog */ _getfiltercontent: function(header) { var self = this; var colnum = ( number(header.attr('name'))+1); var vals = new array; $.each($(self.element).find("tr td:nth-of-type(" + colnum + ")"), function(i, el) { vals[vals.length] = $(el).text(); }); vals = this.sortunique(vals); var filter = '
'; filter = filter + '
text search
'; filter = filter + '
all | none
'; filter = filter + '
'; $.each(vals, function (i, val) { filter = filter + self._addfilterrow(val, colnum); }); filter = filter + '
'; return filter; }, /* add the select and search methods to the filter dialog */ _setupfilter: function() { var self = this; $("#xlsfilterall").click(function() { $.each($("div.xlsfilterrow"), function() { self.checkrow($(this), true); }); }); $("#xlsfilternone").click(function() { $.each($("div.xlsfilterrow"), function() { self.checkrow($(this), false); }); }); $("div.xlsfilterrow input").on('click', function (e) { e.stoppropagation(); }); $("div.xlsfilterrow").click(function() { self.checkrow($(this)); }); $("#filtersearch").blur(self._filterbysearchfield); $("#filtersearch").focus(self._filterbysearchfield); $("#filtersearch").keyup(self._filterbysearchfield); }, /* add a checkbox value row to the filter dialog */ _addfilterrow: function(val, colnum) { var text = (val.length == 0 ? "<blank>" : val); val = this._adjustcase(val);//判断是否转换为小写 if (this.filters[this.elid]["col" + colnum]) { var checked = (jquery.inarray(val, this.filters[this.elid]["col" + colnum]) == -1 ? false : true); } else { var checked = true; } //console.log(val); var row = '
' + (this.options.checkstyle == "default" ? '' : '
') + '' + text + '
'; return row; }, /* check or uncheck a value row in the filter dialog */ checkrow: function(row, check) { var checkbox = $(row).find("input"); check = (arguments.length == 2 ? check : (checkbox.prop("checked") == true ? false : true)); checkbox.prop("checked", check); if (this.options.checkstyle == "custom") { var checkdiv = row.find(".xlsfiltercheck"); checkdiv.addclass(check == true ? "xlsfiltercheckon" : "xlsfiltercheckoff"); checkdiv.removeclass(check == true ? "xlsfiltercheckoff" : "xlsfiltercheckon"); } }, /* search for matching value row in the filter dialog */ _filterbysearchfield: function() { if ($("#filtersearch").val().length == 0) { $("div.xlsfilterrow").show(); } else { $.each($("div.xlsfilterrow input"), function() { if ($(this).val().tolowercase().indexof($("#filtersearch").val().tolowercase()) === -1) { $(this).parent().hide(); } else { $(this).parent().show(); } }); } }, /* create the filter dialog div */ _createdialogdiv: function(divid, title, contents) { if ($("#" + divid).length > 0) { $("#" + divid).html(contents).attr("title", title); } else { $("body").append('"); } return $("#" + divid); }, /* filter the table based on the selected settings */ _filtertable: function(colnum) { var self = this; var filterrow = "col" + colnum self.filters[self.elid][filterrow] = new array; $.each($("div.xlsfilterrow input:checked"), function() { self.filters[self.elid][filterrow][self.filters[self.elid][filterrow].length] = $(this).val(); }); if ($("div.xlsfilterrow input").not(":checked").length === 0) { self.element.find("thead th:nth-of-type(" + colnum + ")").removeclass("xlsfilteredcolumn"); } else { self.element.find("thead th:nth-of-type(" + colnum + ")").addclass("xlsfilteredcolumn"); } $.each(self.element.find("tbody tr"), function() { var $row = $(this); var visible = true; $row.show(); $.each(self.filters[self.elid], function(key, val) { var i = key.substr(3); if (visible == true) { if (jquery.inarray(self._adjustcase($row.children("td:nth-of-type(" + i + ")").text()), val) == -1) { $row.hide(); return false; } } }); }); self._printrowsdisplayed(); }, _printrowsdisplayed: function() { if (this.options.rowsdisplay !== false) { var visiblecount = this.element.find("tbody tr:visible").length; var totalrows = this.element.find("tbody tr").length; var rowdisplay = (typeof(this.options.rowsdisplay) == "object" ? this.options.rowsdisplay : $("#" + this.options.rowsdisplay)); rowdisplay.html('displaying ' + visiblecount + (visiblecount != totalrows ? ' of ' + totalrows + ' row' + (totalrows == 1 ? '' : 's') : ' row' + (visiblecount == 1 ? '' : 's')) + '.'); } }, /* adjust the case of a string based on the ignorecase option */ _adjustcase: function(val) { return (this.options.ignorecase == true ? val.tolowercase() : val); }, /* sort through column values for unique strings */ sortunique: function(arr) { var self = this; arr.sort(function(a, b){ a = self._adjustcase(a); b = self._adjustcase(b); if (a == b) return 0; return a > b ? 1 : -1; }); var ret = [arr[0]]; for (var i = 1; i < arr.length; i++) { // start loop at 1 as element 0 can never be a duplicate if (self._adjustcase(arr[i-1]) !== self._adjustcase(arr[i])) { ret.push(arr[i]); } } return ret; }, /* set an xlstablefilter option */ _setoption: function( key, value ) { options.key = value; }, }); })(jquery);