diff --git a/features/columnSearchField/dataTables.colsearch.js b/features/columnSearchField/dataTables.colsearch.js new file mode 100644 index 0000000..babdabe --- /dev/null +++ b/features/columnSearchField/dataTables.colsearch.js @@ -0,0 +1,268 @@ +/*The MIT License (MIT) + +Copyright (c) 2015 Paul Zepernick + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + + +/** + * @author Paul Zepernick http://www.paulzepernick.com + * @summary DtServerColSearch + * @description Add Server Side Column Search fields + * + */ +(function(window, document, undefined) { + var factory = function( $, DataTable ) { + "use strict"; + + /** + * Function: DtServerColSearch + * Purpose: Automatically create text boxes and selects for column based server side searching + * Returns: object: DtServerColSearch - must be called with 'new' + * Inputs: mixed:mTable - target table + * @param {object} dt DataTables instance or HTML table node. With DataTables + * 1.10 this can also be a jQuery collection (with just a single table in its + * result set), a jQuery selector, DataTables API instance or settings + * object. + * @param {object} Initialisation settings, with the following properties + * string:placement - 'head', 'foot' (default 'head') + * bool:placeholders - Add placeholders to the search inputs? (default true) + * string:controlClass - Class / Classes to apply to each control + * array:select - select settings object + * mixed:name - String or int referencing the column data string, column name, or columnum index + * mixed:options - String Array. The value / display of the option can be separated with a | char. Elements with no pipe will use the same value for the option value and display + * OR + * function(jqSelObj) jQuery object of the select being created is passed in. This can then have the options appended to it. + * bool:header - Should a header entry be generated for the select? (default true) + * + * The following properties are read from the DataTable settings: + * bool:columns.searchable - used to determine if the column should receive a input for searching + * int:searchDelay - used to determine the amount of time to wait before not receiving user input for searching. Default is 500 if not specified + * + */ + var DtServerColSearch = function(dt, opts) { + if ( ! this instanceof DtServerColSearch ) { + alert( "DtServerColSearch warning: DtServerColSearch must be initialised with the 'new' keyword." ); + return; + } + + var defaults = { + placement: "head", + + select: [], + + placeholders: true, + + controlClass: "form-control" + }; + + var mergedOpts = $.extend({}, defaults, opts); + + //return the options for this plugin + this.getOptions = function() { + return mergedOpts; + }; + + var selectDefaults = { + header: true + }; + //default options describing a select + this.getSelectDefaults = function() { + return selectDefaults; + }; + + this._delayCall = (function(){ + var timer = 0; + return function(ms, callback){ + clearTimeout (timer); + timer = setTimeout(callback, ms); + }; + })(); + + var dtsettings = $.fn.dataTable.Api ? + new $.fn.dataTable.Api( dt ).settings()[0] : + dt.fnSettings(); + + this.init(dt, dtsettings, mergedOpts); + }; + + DtServerColSearch.prototype = { + dtapi : {}, + dtsettings: {}, + + //init the extension and build the search fields + init : function(dtapi, dtsettings, opts) { + + if(this.getOptions().placement !== "head" && this.getOptions().placement !== "foot") { + alert("[DtServerColSearch] placement option must be one of these ['head', 'foot']"); + return; + } + + dtsettings.searchDelay = dtsettings.searchDelay || 500; + this.dtapi = dtapi; + this.dtsettings = dtsettings; + //console.log(dtsettings); + + var tr = $("").addClass("dataTable_colSearchBar"); + + var cols = dtsettings.aoColumns; + var colLen = cols.length; + //console.info(cols); + for(var i = 0; i < colLen; i++) { + if(cols[i].bVisible === false) { + continue; + } + + if(cols[i].bSearchable === false) { + tr.append($("")); + continue; + } + + var name = cols[i].data || cols[i].mData; + var input = this._getSearchCtrl(name, i).addClass(this.getOptions().controlClass); + var td = $("").append(input); + tr.append(td); + + } + + var parent; + if(this.getOptions().placement === "head") { + parent = $(dtapi.table().header()); + } else { + parent = $(dtapi.table().footer()); + //build a footer if the table does not have one + if(parent.length === 0) { + parent = $(""); + $(dtapi.table().node()).append(parent); + } + } + + + parent.prepend(tr); + + //listen for columns being hidden and make sure we hide the column in the search bar too + $(dtapi.table().node()).on("column-visibility.dt", function(e, settings, column, state) { + tr.children().eq(column).toggle(state); + }); + + }, + + //private method to build the text or select box for the searching + _getSearchCtrl : function(name, index) { + + var selects = this.getOptions().select; + var len = selects.length; + for(var i = 0; i < len; i++) { + var s = $.extend({}, this.getSelectDefaults(), selects[i]); + if(s.name === name || s.name === index) { + return this._buildSelect(index, s); + } + } + + return this._buildText(index); + }, + + //private method to build a select control and hook a change listener to it + _buildSelect : function(index, sObj) { + var plugin = this; + var select = $("") + .attr("type", "text") + .keyup(function() { + var input = $(this); + plugin._delayCall(plugin.dtsettings.searchDelay, function() { + plugin._doSearch(input, index); + }); + }); + + if(plugin.getOptions().placeholders === true) { + var hTxt = $(plugin.dtapi.column(index).header()).text(); + input.attr("placeholder", hTxt + " Search..."); + } + + return input; + }, + + _doSearch : function(input, index) { + //console.log(input); + this.dtapi + .columns(index) + .search(input.val()) + .draw(); + } + }; + + + $.fn.dataTable.DtServerColSearch = DtServerColSearch; + $.fn.DataTable.DtServerColSearch = DtServerColSearch; + + + + + return DtServerColSearch; + }; + + + // Define as an AMD module if possible + if ( typeof define === 'function' && define.amd ) { + define( ['jquery', 'datatables'], factory ); + } + else if ( typeof exports === 'object' ) { + // Node/CommonJS + factory( require('jquery'), require('datatables') ); + } + else if ( jQuery && !jQuery.fn.dataTable.DtServerColSearch ) { + // Otherwise simply initialise as normal, stopping multiple evaluation + factory( jQuery, jQuery.fn.dataTable ); + } + + + +})(window, document); \ No newline at end of file diff --git a/features/columnSearchField/dataTables.colsearch.md b/features/columnSearchField/dataTables.colsearch.md new file mode 100644 index 0000000..e40e380 --- /dev/null +++ b/features/columnSearchField/dataTables.colsearch.md @@ -0,0 +1,26 @@ +This is a plugin I wrote that will add inputs / selects to the grids header or footer for searching. It will automatically fire the search for the columns on the keyup for inputs and change for selects. + +There is a delay on the keyup on the input that utilizes the `searchDelay` option on the DataTable. The default is 500ms if it has not been specified. The search fields are automatically omitted for a column if `columns.searchable` is FALSE. + +Here are the plugin options: +* `placement` - String: "head' or "foot" (default "head") +* `select` - Array of objects: define which columns should search via dropdown. Object properties specified below. + + * `name` - int or string: column index, `columns.data` as a string, `columns.name` + * `options` - Array of Strings or a function `function(select)`: The function will be responsible for appending the `