import {Dom} from '../../dom'; import {Types} from '../../types'; import {Event} from '../../event'; import {Helpers} from '../../helpers'; import {Arr} from '../../array'; export default class ColsVisibility{ /** * Columns Visibility extension * @param {Object} tf TableFilter instance */ constructor( tf, ext={ name:'colsVisibility', description:'Columns visibility manager' }){ // Configuration object var f = ext; var cfg = tf.config(); this.initialized = false; this.extName = f.name; this.extDesc = f.description; //show/hide cols span element this.spanEl = null; //show/hide cols button element this.btnEl = null; //show/hide cols container div element this.contEl = null; //tick to hide or show column this.tickToHide = f.tick_to_hide===false ? false : true; //enables/disables cols manager generation this.manager = f.manager===false ? false : true; //only if external headers this.headersTbl = f.headers_table || false; //only if external headers this.headersIndex = f.headers_index || 1; //id of container element this.contElTgtId = f.container_target_id || null; //alternative headers text this.headersText = f.headers_text || null; //id of button container element this.btnTgtId = f.btn_target_id || null; //defines show/hide cols text this.btnText = f.btn_text || 'Columns▼'; //defines show/hide cols button innerHtml this.btnHtml = f.btn_html || null; //defines css class for show/hide cols button this.btnCssClass = f.btn_css_class || 'colVis'; //defines close link text this.btnCloseText = f.btn_close_text || 'Close'; //defines close button innerHtml this.btnCloseHtml = f.btn_close_html || null; //defines css class for close button this.btnCloseCssClass = f.btn_close_css_class || this.btnCssClass; this.path = f.path || tf.extensionsPath + 'colsVisibility/'; this.stylesheet = f.stylesheet || 'colsVisibility.css'; //span containing show/hide cols button this.prfx = 'colVis_'; //defines css class span containing show/hide cols this.spanCssClass = f.span_css_class || 'colVisSpan'; this.prfxCont = this.prfx + 'Cont_'; //defines css class div containing show/hide cols this.contCssClass = f.cont_css_class || 'colVisCont'; //defines css class for cols list (ul) this.listCssClass = cfg.list_css_class ||'cols_checklist'; //defines css class for list item (li) this.listItemCssClass = cfg.checklist_item_css_class || 'cols_checklist_item'; //defines css class for selected list item (li) this.listSlcItemCssClass = cfg.checklist_selected_item_css_class || 'cols_checklist_slc_item'; //text preceding columns list this.text = f.text || (this.tickToHide ? 'Hide: ' : 'Show: '); this.atStart = f.at_start || null; this.enableHover = Boolean(f.enable_hover); //enables select all option this.enableTickAll = Boolean(f.enable_tick_all); //text preceding columns list this.tickAllText = f.tick_all_text || 'Select all:'; //array containing hidden columns indexes this.hiddenCols = []; this.tblHasColTag = (Dom.tag(tf.tbl,'col').length > 0); //callback invoked just after cols manager is loaded this.onLoaded = Types.isFn(f.on_loaded) ? f.on_loaded : null; //calls function before cols manager is opened this.onBeforeOpen = Types.isFn(f.on_before_open) ? f.on_before_open : null; //calls function after cols manager is opened this.onAfterOpen = Types.isFn(f.on_after_open) ? f.on_after_open : null; //calls function before cols manager is closed this.onBeforeClose = Types.isFn(f.on_before_close) ? f.on_before_close : null; //calls function after cols manager is closed this.onAfterClose = Types.isFn(f.on_after_close) ? f.on_after_close : null; //calls function before col is hidden this.onBeforeColHidden = Types.isFn(f.on_before_col_hidden) ? f.on_before_col_hidden : null; //calls function after col is hidden this.onAfterColHidden = Types.isFn(f.on_after_col_hidden) ? f.on_after_col_hidden : null; //calls function before col is displayed this.onBeforeColDisplayed = Types.isFn(f.on_before_col_displayed) ? f.on_before_col_displayed : null; //calls function after col is displayed this.onAfterColDisplayed = Types.isFn(f.on_after_col_displayed) ? f.on_after_col_displayed : null; //Grid layout compatibility if(tf.gridLayout){ this.headersTbl = tf.Cpt.gridLayout.headTbl; //headers table this.headersIndex = 0; //headers index this.onAfterColDisplayed = function(){}; this.onAfterColHidden = function(){}; } //Loads extension stylesheet // tf.import( // f.name+'Style', this.path +'/'+ this.stylesheet, null, 'link'); tf.import( f.name+'Style', tf.basePath + this.stylesheet, null, 'link'); this.tf = tf; } toggle(){ var contDisplay = this.contEl.style.display; var onBeforeOpen = this.onBeforeOpen; var onBeforeClose = this.onBeforeClose; var onAfterOpen = this.onAfterOpen; var onAfterClose = this.onAfterClose; if(onBeforeOpen && contDisplay !== 'inline'){ onBeforeOpen.call(null, this); } if(onBeforeClose && contDisplay === 'inline'){ onBeforeClose.call(null, this); } this.contEl.style.display = contDisplay === 'inline' ? 'none' : 'inline'; if(onAfterOpen && contDisplay !== 'inline'){ onAfterOpen.call(null, this); } if(onAfterClose && contDisplay === 'inline'){ onAfterClose.call(null, this); } } checkItem(lbl){ var li = lbl.parentNode; if(!li || !lbl){ return; } var isChecked = lbl.firstChild.checked; var colIndex = lbl.firstChild.getAttribute('id').split('_')[1]; colIndex = parseInt(colIndex, 10); if(isChecked){ Dom.addClass(li, this.listSlcItemCssClass); } else { Dom.removeClass(li, this.listSlcItemCssClass); } var hide = false; if((this.tickToHide && isChecked) || (!this.tickToHide && !isChecked)){ hide = true; } this.setHidden(colIndex, hide); } init(){ if(!this.manager){ return; } this.buildBtn(); this.buildManager(); this.initialized = true; } /** * Build main button UI */ buildBtn(){ if(this.btnEl){ return; } var tf = this.tf; var span = Dom.create('span', ['id', this.prfx+tf.id]); span.className = this.spanCssClass; //Container element (rdiv or custom element) if(!this.btnTgtId){ tf.setToolbar(); } var targetEl = !this.btnTgtId ? tf.rDiv : Dom.id(this.btnTgtId); if(!this.btnTgtId){ var firstChild = targetEl.firstChild; firstChild.parentNode.insertBefore(span, firstChild); } else { targetEl.appendChild(span); } if(!this.btnHtml){ var btn = Dom.create('a', ['href','javascript:;']); btn.className = this.btnCssClass; btn.title = this.extDesc; btn.innerHTML = this.btnText; span.appendChild(btn); if(!this.enableHover){ Event.add(btn, 'click', (evt)=> { this.toggle(evt); }); } else { Event.add(btn, 'mouseover', (evt)=> { this.toggle(evt); }); } } else { //Custom html span.innerHTML = this.btnHtml; var colVisEl = span.firstChild; if(!this.enableHover){ Event.add(colVisEl, 'click', (evt)=> { this.toggle(evt); }); } else { Event.add(colVisEl, 'mouseover', (evt)=> { this.toggle(evt); }); } } this.spanEl = span; this.btnEl = this.spanEl.firstChild; if(this.onLoaded){ this.onLoaded.call(null, this); } } /** * Build columns manager UI */ buildManager(){ var tf = this.tf; var container = !this.contElTgtId ? Dom.create('div', ['id', this.prfxCont+tf.id]) : Dom.id(this.contElTgtId); container.className = this.contCssClass; //Extension description var extNameLabel = Dom.create('p'); extNameLabel.innerHTML = this.text; container.appendChild(extNameLabel); //Headers list var ul = Dom.create('ul' ,['id', 'ul'+this.extName+'_'+tf.id]); ul.className = this.listCssClass; var tbl = this.headersTbl ? this.headersTbl : tf.tbl; var headerIndex = this.headersTbl ? this.headersIndex : tf.getHeadersRowIndex(); var headerRow = tbl.rows[headerIndex]; //Tick all option if(this.enableTickAll){ var li = Dom.createCheckItem( 'col__'+tf.id, this.tickAllText, this.tickAllText); Dom.addClass(li, this.listItemCssClass); ul.appendChild(li); li.check.checked = !this.tickToHide; Event.add(li.check, 'click', ()=> { for(var h = 0; h < headerRow.cells.length; h++){ var itm = Dom.id('col_'+h+'_'+tf.id); if(itm && li.check.checked !== itm.checked){ itm.click(); itm.checked = li.check.checked; } } }); } for(var i = 0; i < headerRow.cells.length; i++){ var cell = headerRow.cells[i]; var cellText = this.headersText && this.headersText[i] ? this.headersText[i] : this._getHeaderText(cell); var liElm = Dom.createCheckItem( 'col_'+i+'_'+tf.id, cellText, cellText); Dom.addClass(liElm, this.listItemCssClass); if(!this.tickToHide){ Dom.addClass(liElm, this.listSlcItemCssClass); } ul.appendChild(liElm); if(!this.tickToHide){ liElm.check.checked = true; } Event.add(liElm.check, 'click', (evt)=> { var elm = Event.target(evt); var lbl = elm.parentNode; this.checkItem(lbl); }); } //separator var p = Dom.create('p', ['align','center']); var btn; //Close link if(!this.btnCloseHtml){ btn = Dom.create('a', ['href','javascript:;']); btn.className = this.btnCloseCssClass; btn.innerHTML = this.btnCloseText; Event.add(btn, 'click', (evt)=> { this.toggle(evt); }); p.appendChild(btn); } else { p.innerHTML = this.btnCloseHtml; btn = p.firstChild; Event.add(btn, 'click', (evt)=> { this.toggle(evt); }); } container.appendChild(ul); container.appendChild(p); this.btnEl.parentNode.insertBefore(container, this.btnEl); this.contEl = container; if(this.atStart){ var a = this.atStart; for(var k=0; k