tablesorter/js/widgets/widget-filter-formatter-select2.js
Rob Garrison 2668e0e773 Filter: Add namespacing to filter-formatter listeners
Needed to prevent JS error when a "resetToLoadState" is triggered
and the "filterFomatterUpdate" bindings are still firing.
2017-06-29 22:21:54 -05:00

172 lines
5.4 KiB
JavaScript

/*! Widget: filter, select2 formatter function - updated 7/11/2016 (v2.26.6) *//*
* requires: jQuery 1.7.2+, tableSorter (FORK) 2.16+, filter widget 2.16+
and select2 v3.4.6+ plugin (this code is NOT compatible with select2 v4+)
*/
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
'use strict';
var ts = $.tablesorter || {};
ts.filterFormatter = ts.filterFormatter || {};
/************************\
Select2 Filter Formatter
\************************/
ts.filterFormatter.select2 = function($cell, indx, select2Def) {
var o = $.extend({
// select2 filter formatter options
cellText : '', // Text (wrapped in a label element)
match : true, // adds 'filter-match' to header
value : '',
// include ANY select2 options below
multiple : true,
width : '100%'
}, select2Def ),
arry, data,
// add class to $cell since it may point to a removed DOM node
// after a "refreshWidgets"; see #1237
c = $cell.addClass('select2col' + indx).closest('table')[0].config,
wo = c.widgetOptions,
// Add a hidden input to hold the range values
$input = $('<input class="filter" type="hidden">')
.appendTo($cell)
// hidden filter update namespace trigger by filter widget
.bind('change' + c.namespace + 'filter', function(){
var val = convertRegex(this.value);
c.$table.find('.select2col' + indx + ' .select2').select2('val', val);
updateSelect2();
}),
$header = c.$headerIndexed[indx],
onlyAvail = $header.hasClass(wo.filter_onlyAvail),
matchPrefix = o.match ? '' : '^',
matchSuffix = o.match ? '' : '$',
flags = wo.filter_ignoreCase ? 'i' : '',
convertRegex = function(val) {
// value = '/(^x$|^y$)/' => ['x','y']
return val
.replace(/^\/\(\^?/, '')
.replace(/\$\|\^/g, '|')
.replace(/\$?\)\/i?$/g, '')
// unescape special regex characters
.replace(/\\/g, '')
.split('|');
},
// this function updates the hidden input and adds the current values to the header cell text
updateSelect2 = function() {
var arry = false,
v = c.$table.find('.select2col' + indx + ' .select2').select2('val') || o.value || '';
// convert array to string
if ($.isArray(v)) {
arry = true;
v = v.join('\u0000');
}
// escape special regex characters (http://stackoverflow.com/a/9310752/145346)
v = v.replace(/[-[\]{}()*+?.,/\\^$|#\s]/g, '\\$&');
// convert string back into an array
if (arry) {
v = v.split('\u0000');
}
if (!ts.isEmptyObject($input.find('.select2').data())) {
$input
// add regex, so we filter exact numbers
.val(
$.isArray(v) && v.length && v.join('') !== '' ?
'/(' + matchPrefix + (v || []).join(matchSuffix + '|' + matchPrefix) + matchSuffix + ')/' + flags :
''
)
.trigger('search').end()
.find('.select2').select2('val', v);
// update sticky header cell
if (c.widgetOptions.$sticky) {
c.widgetOptions.$sticky.find('.select2col' + indx + ' .select2').select2('val', v);
}
}
},
// get options from table cell content or filter_selectSource (v2.16)
updateOptions = function(){
data = [];
arry = ts.filter.getOptionSource(c.$table[0], indx, onlyAvail) || [];
// build select2 data option
$.each(arry, function(i, v){
// getOptionSource returns { parsed: "value", text: "value" } in v2.24.4
data.push({ id: '' + v.parsed, text: v.text });
});
o.data = data;
};
// get filter-match class from option
$header.toggleClass('filter-match', o.match);
if (o.cellText) {
$cell.prepend('<label>' + o.cellText + '</label>');
}
// don't add default in table options if either ajax or
// data options are already defined
if (!(o.ajax && !$.isEmptyObject(o.ajax)) && !o.data) {
updateOptions();
c.$table.bind('filterEnd', function(){
updateOptions();
c.$table
.find('.select2col' + indx)
.add(c.widgetOptions.$sticky && c.widgetOptions.$sticky.find('.select2col' + indx))
.find('.select2').select2(o);
});
}
// add a select2 hidden input!
$('<input class="select2 select2-' + indx + '" type="hidden" />')
.val(o.value)
.appendTo($cell)
.select2(o)
.bind('change', function(){
updateSelect2();
});
// update select2 from filter hidden input, in case of saved filters
c.$table.bind('filterFomatterUpdate', function() {
// value = '/(^x$|^y$)/' => 'x,y'
var val = convertRegex(c.$table.data('lastSearch')[indx] || '');
$cell = c.$table.find('.select2col' + indx);
$cell.find('.select2').select2('val', val);
updateSelect2();
ts.filter.formatterUpdated($cell, indx);
});
// has sticky headers?
c.$table.bind('stickyHeadersInit', function(){
var $shcell = c.widgetOptions.$sticky.find('.select2col' + indx).empty();
// add a select2!
$('<input class="select2 select2-' + indx + '" type="hidden">')
.val(o.value)
.appendTo($shcell)
.select2(o)
.bind('change', function(){
c.$table.find('.select2col' + indx)
.find('.select2')
.select2('val', c.widgetOptions.$sticky.find('.select2col' + indx + ' .select2').select2('val') );
updateSelect2();
});
if (o.cellText) {
$shcell.prepend('<label>' + o.cellText + '</label>');
}
});
// on reset
c.$table.bind('filterReset', function(){
c.$table.find('.select2col' + indx).find('.select2').select2('val', o.value || '');
setTimeout(function(){
updateSelect2();
}, 0);
});
updateSelect2();
return $input;
};
})(jQuery);