1
0
Fork 0
mirror of https://github.com/koalyptus/TableFilter.git synced 2024-05-05 08:03:17 +02:00
TableFilter/src/modules/popupFilter.js
2016-05-08 15:26:52 +10:00

277 lines
8.8 KiB
JavaScript

import {Feature} from './feature';
import Types from '../types';
import Dom from '../dom';
import Event from '../event';
import {INPUT, NONE} from '../const';
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(evt){
var elm = Event.target(evt).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) === NONE){
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) === INPUT){
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;
}
}