mirror of
https://github.com/koalyptus/TableFilter.git
synced 2024-05-21 15:56:40 +02:00
277 lines
8.8 KiB
JavaScript
277 lines
8.8 KiB
JavaScript
import {Feature} from './feature';
|
|
import Types from '../types';
|
|
import Dom from '../dom';
|
|
import Event from '../event';
|
|
|
|
export class PopupFilter extends Feature{
|
|
|
|
/**
|
|
* Pop-up filter component
|
|
* @param {Object} tf TableFilter instance
|
|
*/
|
|
constructor(tf){
|
|
super(tf, 'popupFilters');
|
|
|
|
// Configuration object
|
|
var f = this.config;
|
|
|
|
// Enable external filters
|
|
tf.isExternalFlt = true;
|
|
tf.externalFltTgtIds = [];
|
|
|
|
//filter icon path
|
|
this.popUpImgFlt = f.popup_filters_image ||
|
|
tf.themesPath+'icn_filter.gif';
|
|
//active filter icon path
|
|
this.popUpImgFltActive = f.popup_filters_image_active ||
|
|
tf.themesPath+'icn_filterActive.gif';
|
|
this.popUpImgFltHtml = f.popup_filters_image_html ||
|
|
'<img src="'+ this.popUpImgFlt +'" alt="Column filter" />';
|
|
//defines css class for popup div containing filter
|
|
this.popUpDivCssClass = f.popup_div_css_class || 'popUpFilter';
|
|
//callback function before popup filtes is opened
|
|
this.onBeforePopUpOpen = Types.isFn(f.on_before_popup_filter_open) ?
|
|
f.on_before_popup_filter_open : null;
|
|
//callback function after popup filtes is opened
|
|
this.onAfterPopUpOpen = Types.isFn(f.on_after_popup_filter_open) ?
|
|
f.on_after_popup_filter_open : null;
|
|
//callback function before popup filtes is closed
|
|
this.onBeforePopUpClose =
|
|
Types.isFn(f.on_before_popup_filter_close) ?
|
|
f.on_before_popup_filter_close : null;
|
|
//callback function after popup filtes is closed
|
|
this.onAfterPopUpClose = Types.isFn(f.on_after_popup_filter_close) ?
|
|
f.on_after_popup_filter_close : null;
|
|
|
|
//stores filters spans
|
|
this.popUpFltSpans = [];
|
|
//stores filters icons
|
|
this.popUpFltImgs = [];
|
|
//stores filters containers
|
|
this.popUpFltElms = this.popUpFltElmCache || [];
|
|
this.popUpFltAdjustToContainer = true;
|
|
|
|
//id prefix for pop-up filter span
|
|
this.prfxPopUpSpan = 'popUpSpan_';
|
|
//id prefix for pop-up div containing filter
|
|
this.prfxPopUpDiv = 'popUpDiv_';
|
|
}
|
|
|
|
onClick(e){
|
|
var evt = e || global.event,
|
|
elm = evt.target.parentNode,
|
|
colIndex = parseInt(elm.getAttribute('ci'), 10);
|
|
|
|
this.closeAll(colIndex);
|
|
this.toggle(colIndex);
|
|
|
|
if(this.popUpFltAdjustToContainer){
|
|
var popUpDiv = this.popUpFltElms[colIndex],
|
|
header = this.tf.getHeaderElement(colIndex),
|
|
headerWidth = header.clientWidth * 0.95;
|
|
popUpDiv.style.width = parseInt(headerWidth, 10) + 'px';
|
|
}
|
|
Event.cancel(evt);
|
|
Event.stop(evt);
|
|
}
|
|
|
|
/**
|
|
* Initialize DOM elements
|
|
*/
|
|
init(){
|
|
if(this.initialized){
|
|
return;
|
|
}
|
|
|
|
var tf = this.tf;
|
|
|
|
// Override headers row index if no grouped headers
|
|
if(tf.headersRow <= 1){
|
|
tf.headersRow = 0;
|
|
}
|
|
|
|
for(var i=0; i<tf.nbCells; i++){
|
|
if(tf.getFilterType(i) === tf.fltTypeNone){
|
|
continue;
|
|
}
|
|
var popUpSpan = Dom.create(
|
|
'span',
|
|
['id', this.prfxPopUpSpan+tf.id+'_'+i],
|
|
['ci', i]
|
|
);
|
|
popUpSpan.innerHTML = this.popUpImgFltHtml;
|
|
var header = tf.getHeaderElement(i);
|
|
header.appendChild(popUpSpan);
|
|
Event.add(popUpSpan, 'click', (evt) => { this.onClick(evt); });
|
|
this.popUpFltSpans[i] = popUpSpan;
|
|
this.popUpFltImgs[i] = popUpSpan.firstChild;
|
|
}
|
|
|
|
// subscribe to events
|
|
this.emitter.on(['before-filtering'], ()=> this.buildIcons());
|
|
this.emitter.on(['after-filtering'], ()=> this.closeAll());
|
|
this.emitter.on(['cell-processed'],
|
|
(tf, cellIndex)=> this.buildIcon(cellIndex, true));
|
|
this.emitter.on(['filters-row-inserted'], ()=> this.tf.headersRow++);
|
|
this.emitter.on(['before-filter-init'],
|
|
(tf, colIndex)=> this.build(colIndex));
|
|
|
|
this.initialized = true;
|
|
}
|
|
|
|
/**
|
|
* Reset previously destroyed feature
|
|
*/
|
|
reset(){
|
|
this.enable();
|
|
this.init();
|
|
this.buildAll();
|
|
}
|
|
|
|
/**
|
|
* Build all pop-up filters elements
|
|
*/
|
|
buildAll(){
|
|
for(var i=0; i<this.popUpFltElmCache.length; i++){
|
|
this.build(i, this.popUpFltElmCache[i]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build a specified pop-up filter elements
|
|
* @param {Number} colIndex Column index
|
|
* @param {Object} div Optional container DOM element
|
|
*/
|
|
build(colIndex, div){
|
|
var tf = this.tf;
|
|
var popUpDiv = !div ?
|
|
Dom.create('div', ['id', this.prfxPopUpDiv+tf.id+'_'+colIndex]) :
|
|
div;
|
|
popUpDiv.className = this.popUpDivCssClass;
|
|
tf.externalFltTgtIds.push(popUpDiv.id);
|
|
var header = tf.getHeaderElement(colIndex);
|
|
header.insertBefore(popUpDiv, header.firstChild);
|
|
Event.add(popUpDiv, 'click', (evt) => { Event.stop(evt); });
|
|
this.popUpFltElms[colIndex] = popUpDiv;
|
|
}
|
|
|
|
/**
|
|
* Toogle visibility of specified filter
|
|
* @param {Number} colIndex Column index
|
|
*/
|
|
toggle(colIndex){
|
|
var tf = this.tf,
|
|
popUpFltElm = this.popUpFltElms[colIndex];
|
|
|
|
if(popUpFltElm.style.display === 'none' ||
|
|
popUpFltElm.style.display === ''){
|
|
if(this.onBeforePopUpOpen){
|
|
this.onBeforePopUpOpen.call(
|
|
null, this, this.popUpFltElms[colIndex], colIndex);
|
|
}
|
|
popUpFltElm.style.display = 'block';
|
|
if(tf.getFilterType(colIndex) === tf.fltTypeInp){
|
|
var flt = tf.getFilterElement(colIndex);
|
|
if(flt){
|
|
flt.focus();
|
|
}
|
|
}
|
|
if(this.onAfterPopUpOpen){
|
|
this.onAfterPopUpOpen.call(
|
|
null, this, this.popUpFltElms[colIndex], colIndex);
|
|
}
|
|
} else {
|
|
if(this.onBeforePopUpClose){
|
|
this.onBeforePopUpClose.call(
|
|
null, this, this.popUpFltElms[colIndex], colIndex);
|
|
}
|
|
popUpFltElm.style.display = 'none';
|
|
if(this.onAfterPopUpClose){
|
|
this.onAfterPopUpClose.call(
|
|
null, this, this.popUpFltElms[colIndex], colIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close all filters excepted for the specified one if any
|
|
* @param {Number} exceptIdx Column index of the filter to not close
|
|
*/
|
|
closeAll(exceptIdx){
|
|
for(var i=0; i<this.popUpFltElms.length; i++){
|
|
if(i === exceptIdx){
|
|
continue;
|
|
}
|
|
var popUpFltElm = this.popUpFltElms[i];
|
|
if(popUpFltElm){
|
|
popUpFltElm.style.display = 'none';
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build all the icons representing the pop-up filters
|
|
*/
|
|
buildIcons(){
|
|
for(var i=0; i<this.popUpFltImgs.length; i++){
|
|
this.buildIcon(i, false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply specified icon state
|
|
* @param {Number} colIndex Column index
|
|
* @param {Boolean} active Apply active state
|
|
*/
|
|
buildIcon(colIndex, active){
|
|
if(this.popUpFltImgs[colIndex]){
|
|
this.popUpFltImgs[colIndex].src = active ?
|
|
this.popUpImgFltActive : this.popUpImgFlt;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove pop-up filters
|
|
*/
|
|
destroy(){
|
|
if(!this.initialized){
|
|
return;
|
|
}
|
|
|
|
this.popUpFltElmCache = [];
|
|
for(var i=0; i<this.popUpFltElms.length; i++){
|
|
var popUpFltElm = this.popUpFltElms[i],
|
|
popUpFltSpan = this.popUpFltSpans[i],
|
|
popUpFltImg = this.popUpFltImgs[i];
|
|
if(popUpFltElm){
|
|
Dom.remove(popUpFltElm);
|
|
this.popUpFltElmCache[i] = popUpFltElm;
|
|
}
|
|
popUpFltElm = null;
|
|
if(popUpFltSpan){
|
|
Dom.remove(popUpFltSpan);
|
|
}
|
|
popUpFltSpan = null;
|
|
if(popUpFltImg){
|
|
Dom.remove(popUpFltImg);
|
|
}
|
|
popUpFltImg = null;
|
|
}
|
|
this.popUpFltElms = [];
|
|
this.popUpFltSpans = [];
|
|
this.popUpFltImgs = [];
|
|
|
|
// unsubscribe to events
|
|
this.emitter.off(['before-filtering'], ()=> this.buildIcons());
|
|
this.emitter.off(['after-filtering'], ()=> this.closeAll());
|
|
this.emitter.off(['cell-processed'],
|
|
(tf, cellIndex)=> this.buildIcon(cellIndex, true));
|
|
this.emitter.off(['filters-row-inserted'], ()=> this.tf.headersRow++);
|
|
this.emitter.off(['before-filter-init'],
|
|
(tf, colIndex)=> this.build(colIndex));
|
|
|
|
this.initialized = false;
|
|
}
|
|
|
|
}
|