Backgrid.ColumnManager.js 11 KB

1
  1. "use strict";var _=require("underscore"),$=require("jquery"),Backbone=require("backbone"),Backgrid=require("backgrid");Backgrid.Extension.ColumnManager=function(a,b,c){_.extend(this,Backbone.Events);var d={initialColumnsVisible:null,trackSize:!0,trackOrder:!0,trackVisibility:!0,stateChecking:"strict",saveState:!1,saveStateKey:"",saveStateLocation:"localStorage",loadStateOnInit:!1};if(this.options=_.extend({},d,b),this.state=[],a instanceof Backgrid.Columns){this.columns=a,a.columnManager=this,this.addManagerToColumns();var e=!!this.options.loadStateOnInit&&this.loadState();if(c&&this.checkStateValidity(c)?this.setState(c,!0):e?this.setState(e,!0):(this.setInitialColumnVisibility(),this.setState(this.getStateFromColumns())),this.options.trackVisibility||this.options.trackSize||this.options.trackOrder){var f=""+(this.options.trackVisibility?"change:renderable ":"")+(this.options.trackSize?"resize ":"")+(this.options.trackOrder?"ordered":"");this.columns.on(f,_.bind(this.stateUpdateHandler,this))}}else console.error("Backgrid.ColumnManager: options.columns is not an instance of Backgrid.Columns")},Backgrid.Extension.ColumnManager.prototype.setInitialColumnVisibility=function(){var a=this,b=a.options.initialColumnsVisible;b&&a.columns.each(function(a,c){a.set("renderable",!!a.get("alwaysVisible")||c<b)})},Backgrid.Extension.ColumnManager.prototype.addManagerToColumns=function(){var a=this;a.columns.each(function(b){b.get("headerCell")===Backgrid.Extension.ColumnManager.ColumnVisibilityHeaderCell&&b.set("headerCell",b.get("headerCell").extend({columnManager:a})),b.get("headerCell")instanceof Backgrid.Extension.ColumnManager.ColumnVisibilityHeaderCell&&(b.get("headerCell").columnManager=a)})},Backgrid.Extension.ColumnManager.prototype.getColumn=function(a){return(_.isNumber(a)||_.isString(a))&&(a=this.columns.get(a)),a instanceof Backgrid.Column&&a},Backgrid.Extension.ColumnManager.prototype.hideColumn=function(a){var b=this.getColumn(a);b&&b.set("renderable",!1)},Backgrid.Extension.ColumnManager.prototype.showColumn=function(a){var b=this.getColumn(a);b&&b.set("renderable",!0)},Backgrid.Extension.ColumnManager.prototype.toggleColumnVisibility=function(a){var b=this.getColumn(a);b&&(b.get("renderable")?this.hideColumn(b):this.showColumn(b))},Backgrid.Extension.ColumnManager.prototype.getColumnCollection=function(){return this.columns},Backgrid.Extension.ColumnManager.prototype.setState=function(a,b){var c=this;return _.filter(a,function(b){if(!_.has(b,"name"))return!1;var d=c.columns.findWhere({name:a.name});return"undefined"!=typeof d}),!(!c.checkStateValidity(a)||a===c.state)&&(c.state=a,c.trigger("state-changed",a),b?c.applyStateToColumns():c.saveState())},Backgrid.Extension.ColumnManager.prototype.getState=function(){return this.state},Backgrid.Extension.ColumnManager.prototype.checkStateValidity=function(a){function b(){return _.every(a,function(a){var b=!0;return _.has(a,"name")||(b=!1),_.has(a,"renderable")&&(_.isBoolean(a.renderable)||(b=!1)),_.has(a,"displayOrder")&&(_.isNumber(a.displayOrder)||(b=!1)),_.has(a,"width")&&(_.isNumber(a.width)||_.isString(a.width)||(b=!1)),b})}if(!_.isArray(a)&&_.isEmpty(a))return!1;if("loose"===this.options.stateChecking)return b();if(a.length!==this.columns.length&&!b())return!1;var c=this.columns.map(function(a){return a.get("name")}),d=_.map(a,function(a){return a.name});return c.sort().toString()===d.sort().toString()},Backgrid.Extension.ColumnManager.prototype.loadState=function(){var a=JSON.parse(this.getStorage().getItem(this.getStorageKey()));return!!this.checkStateValidity(a)&&a},Backgrid.Extension.ColumnManager.prototype.saveState=function(a){return!(!this.options.saveState&&!a)&&(this.getStorage().setItem(this.getStorageKey(),JSON.stringify(this.state)),this.trigger("state-saved"),!0)},Backgrid.Extension.ColumnManager.prototype.getStorage=function(){return"undefined"!=typeof Storage?"sessionStorage"===this.options.saveStateLocation?sessionStorage:localStorage:(console.error("ColMrg: No storage support detected. State won't be saved."),!1)},Backgrid.Extension.ColumnManager.prototype.getStorageKey=function(){return this.options.saveStateKey?"backgrid-colmgr-"+this.options.saveStateKey:"backgrid-colmgr"},Backgrid.Extension.ColumnManager.prototype.stateUpdateHandler=function(){var a=this.getStateFromColumns();return this.setState(a)},Backgrid.Extension.ColumnManager.prototype.getStateFromColumns=function(){var a=this;return this.columns.map(function(b){var c={name:b.get("name")};return a.options.trackVisibility&&(c.renderable=b.get("renderable")),a.options.trackOrder&&(c.displayOrder=b.get("displayOrder")),a.options.trackSize&&(c.width=b.get("width")),c})},Backgrid.Extension.ColumnManager.prototype.applyStateToColumns=function(){var a=this,b=!1;_.each(this.state,function(c){var d=a.columns.findWhere({name:c.name});if(_.has(c,"renderable")&&d.set("renderable",c.renderable),_.has(c,"width")){var e=d.get("width");d.set("width",c.width,{silent:!0}),e!==c.width&&d.trigger("resize",d,c.width,e)}_.has(c,"displayOrder")&&(c.displayOrder!==d.get("displayOrder")&&(b=!0),d.set("displayOrder",c.displayOrder,{silent:!0}))}),b&&(a.columns.sort(),a.columns.trigger("ordered"))};var DropDownItemView=Backbone.View.extend({className:"columnmanager-dropdown-item",tagName:"li",initialize:function(a){this.columnManager=a.columnManager,this.column=a.column,this.template=a.template,_.bindAll(this,"render","toggleVisibility"),this.column.on("change:renderable",this.render,this),this.el.addEventListener("click",this.toggleVisibility,!0)},render:function(){return this.$el.empty(),this.$el.append(this.template({label:this.column.get("label")})),this.column.get("renderable")?this.$el.addClass(this.column.get("renderable")?"visible":null):this.$el.removeClass("visible"),this},toggleVisibility:function(a){a&&this.stopPropagation(a),this.columnManager.toggleColumnVisibility(this.column)},stopPropagation:function(a){a.stopPropagation(),a.stopImmediatePropagation(),a.preventDefault()}}),DropDownView=Backbone.View.extend({className:"columnmanager-dropdown-container",initialize:function(a){this.options=a,this.columnManager=a.columnManager,this.ItemView=a.DropdownItemView instanceof Backbone.View?a.DropdownItemView:DropDownItemView,this.$dropdownButton=a.$dropdownButton,this.on("dropdown:opened",this.open,this),this.on("dropdown:closed",this.close,this),this.columnManager.columns.on("add remove",this.render,this)},render:function(){var a=this;return a.$el.empty(),this.columnManager.columns.each(function(b){b.get("alwaysVisible")||a.$el.append(new a.ItemView({column:b,columnManager:a.columnManager,template:a.options.dropdownItemTemplate}).render().el)}),this},open:function(){this.$el.addClass("open");var a,b=this.$dropdownButton;if("auto"===this.options.align){var c=document.body.clientWidth||document.body.clientWidth;a=b.offset().left+this.$el.outerWidth()>c?"left":"right"}else a="left"===this.options.align||"right"===this.options.align?"right"===this.options.align?"right":"left":"right";var d;"left"===a?(d=b.offset().left+b.outerWidth()-this.$el.outerWidth(),this.$el.css("left",d+"px")):(d=b.offset().left,this.$el.css("left",d+"px"));var e=b.offset().top+b.outerHeight();this.$el.css("top",e+"px")},close:function(){this.$el.removeClass("open")}});Backgrid.Extension.ColumnManagerVisibilityControl=Backbone.View.extend({tagName:"div",className:"columnmanager-visibilitycontrol",defaultEvents:{click:"stopPropagation"},defaultOpts:{width:null,closeOnEsc:!0,closeOnClick:!0,openOnInit:!1,columnManager:null,buttonTemplate:_.template("<button class='dropdown-button'>...</button>"),DropdownView:DropDownView,dropdownAlign:"auto",DropdownItemView:DropDownItemView,dropdownItemTemplate:_.template("<span class='indicator'></span><span class='column-label'><%= label %></span>")},initialize:function(a){this.options=_.extend({},this.defaultOpts,a),this.events=_.extend({},this.defaultEvents,this.events||{}),this.columnManager=a.columnManager,!this.columnManager instanceof Backgrid.Extension.ColumnManager&&console.error("Backgrid.ColumnManager: options.columns is not an instance of Backgrid.Columns"),_.bindAll(this,"deferClose","stopDeferClose","closeOnEsc","toggle","render"),document.body.addEventListener("click",this.deferClose,!0),this.el.addEventListener("click",this.stopDeferClose,!0),this.options.closeOnEsc&&document.body.addEventListener("keyup",this.closeOnEsc,!1),this.el.addEventListener("click",this.toggle,!1),this.setup(),this.view.on("dropdown:close",this.close,this),this.view.on("dropdown:open",this.open,this)},delayStart:function(){clearTimeout(this.closeTimeout),this.delayTimeout=setTimeout(this.open.bind(this),this.options.delay)},delayEnd:function(){clearTimeout(this.delayTimeout),this.closeTimeout=setTimeout(this.close.bind(this),300)},setup:function(){this.options.width&&this.$el.width(this.options.width+"px"),this.$dropdownButton=$(this.options.buttonTemplate());var a={columnManager:this.columnManager,DropdownItemView:this.options.DropdownItemView,dropdownItemTemplate:this.options.dropdownItemTemplate,align:this.options.dropdownAlign,$dropdownButton:this.$dropdownButton};this.view=this.options.DropdownView instanceof Backbone.View?new this.options.DropdownView(a):new DropDownView(a)},render:function(){return this.$el.empty(),this.$el.append(this.$dropdownButton),this.view.render(),$(document.body).append(this.view.el),this},stopPropagation:function(a){a.stopPropagation(),a.stopImmediatePropagation(),a.preventDefault()},toggle:function(a){this.isOpen!==!0?this.open(a):this.close(a)},open:function(a){clearTimeout(this.closeTimeout),clearTimeout(this.deferCloseTimeout),a&&(a.stopPropagation&&a.stopPropagation(),a.preventDefault&&a.preventDefault(),a.cancelBubble=!0),this.isOpen||(this.isOpen=!0,this.$el.addClass("open"),this.trigger("dropdown:opened"),this.view.trigger("dropdown:opened"))},close:function(a){this.isOpen&&(this.isOpen=!1,this.$el.removeClass("open"),this.trigger("dropdown:closed"),this.view.trigger("dropdown:closed"))},closeOnEsc:function(a){27===a.which&&this.deferClose()},deferClose:function(){this.deferCloseTimeout=setTimeout(this.close.bind(this),0)},stopDeferClose:function(a){clearTimeout(this.deferCloseTimeout)},remove:function(){return document.body.removeEventListener("click",this.deferClose),this.el.removeEventListener("click",this.stopDeferClose),this.options.closeOnEsc&&document.body.removeEventListener("keyup",this.closeOnEsc),this.el.removeEventListener("click",this.toggle),$(this.view.el).remove(),Backbone.View.prototype.remove.apply(this,arguments)}}),Backgrid.Extension.ColumnManager.ColumnVisibilityHeaderCell=Backgrid.HeaderCell.extend({initialize:function(a){Backgrid.HeaderCell.prototype.initialize.apply(this,arguments),this.$el.addClass(this.column.get("name"))},render:function(){this.$el.empty();var a=this.colVisibilityControl=new Backgrid.Extension.ColumnManagerVisibilityControl({columnManager:this.columnManager});return this.$el.html(a.render().el),this.delegateEvents(),this},remove:function(){return this.colVisibilityControl.remove(),Backgrid.HeaderCell.__super__.remove.apply(this,arguments)}});