backgrid-orderable-columns.js 8.8 KB

1
  1. !function(a,b){"object"==typeof exports?module.exports=b(require("underscore"),require("backgrid"),require("jquery")):"function"==typeof define&&define.amd?define(["underscore","backgrid","jquery"],b):b(a._,a.Backgrid,a.jQuery)}(this,function(a,b,c){"use strict";b.Extension.OrderableColumns=Backbone.View.extend({dragHooks:{},initialize:function(b){this.sizeAbleColumns=b.sizeAbleColumns,this.grid=this.sizeAbleColumns.grid,this.columns=this.grid.columns,this.header=this.grid.header,this.collection=this.grid.collection,this.moveThreshold=b.moveThreshold||10,this.orderAlignTop=b.orderAlignTop,this.attachEvents(),this.setHeaderElements(),this.mouseMoveHandler=a.bind(this.mouseMoveHandler,this),this.mouseUpHandler=a.bind(this.mouseUpHandler,this)},render:function(){var b=this;b.$el.empty(),b.addIndicators();var c=b.header.headerRows||[b.header.row];return a.each(c,function(c){a.each(c.cells,function(c){var d=c.column,e=!1;e=d.get("childColumns")?a.some(d.get("childColumns"),function(a){var b=a.column;return"undefined"==typeof b.get("orderable")||b.get("orderable")}):"undefined"==typeof d.get("orderable")||d.get("orderable"),e&&c.$el.on("mousedown",a.bind(b.mouseDownHandler,{view:b,cell:c,column:d}))})}),b.updateIndicatorPosition(),this},dragState:{dragIntention:!1,dragging:!1,$dragElement:null,$activeIndicator:null,column:null,cell:null,coordinateElementStartX:null,coordinatePointerStartX:null,oldFirstDisplayOrderValue:null,oldLastDisplayOrderValue:null,newDisplayOrderValue:null,orderPrevented:null},mouseDownHandler:function(b){var d=this.view,e=this.cell,f=this.column,g=c(e.$el);1===b.which&&(d._stopEvent(b),d.dragState.dragIntention=!0,d.dragState.column=f,d.dragState.cell=e,d.dragState.coordinatePointerStartX=b.pageX,d.dragState.coordinateElementStartX=g.position().left,f.get("childColumns")?(d.dragState.oldFirstDisplayOrderValue=a.first(f.get("childColumns")).column.get("displayOrder"),d.dragState.newDisplayOrderValue=a.first(f.get("childColumns")).column.get("displayOrder"),d.dragState.oldLastDisplayOrderValue=a.last(f.get("childColumns")).column.get("displayOrder")):(d.dragState.oldFirstDisplayOrderValue=f.get("displayOrder"),d.dragState.newDisplayOrderValue=f.get("displayOrder"),d.dragState.oldLastDisplayOrderValue=f.get("displayOrder")),d.dragState.$dragElement=c("<div/>").addClass("orderable-draggable").hide().appendTo(d.$el).width(g.outerWidth()).height(g.outerHeight()).css({left:g.position().left,top:g.position().top}),c(document).on("mousemove",d.mouseMoveHandler),c(document).on("mouseup",d.mouseUpHandler))},mouseMoveHandler:function(a){var b=this,c=a.pageX,d=b.dragState.coordinateElementStartX+(c-b.dragState.coordinatePointerStartX);b._stopEvent(a);var e=Math.abs(c-b.dragState.coordinatePointerStartX);b.dragState.dragging?(b.calculateDropPosition(d,a),b.dragHookInvoke("dragMove",b.dragState.$dragElement,a,b.dragState.column),b.dragState.$dragElement.css({left:d})):e>=b.moveThreshold&&!b.dragState.dragging&&(b.dragState.cell.$el.addClass("orderable-ordering"),b.dragState.dragging=!0,b.dragHookInvoke("dragStart",a,b.dragState.column),b.dragState.$dragElement.css({left:d}).show())},mouseUpHandler:function(a){var b=this;c(document).off("mousemove",b.mouseMoveHandler),c(document).off("mouseup",b.mouseUpHandler),b.dragHookInvoke("dragEnd",a,b.dragState.column),b.dragState.orderPrevented||b.dragState.oldFirstDisplayOrderValue===b.dragState.newDisplayOrderValue||(b.updateDisplayOrders(),b.columns.trigger("ordered"),b.columns.sort()),b.resetDragState()},calculateDropPosition:function(b,c){var d=this,e=null,f=null;a.each(d.indicatorPositions,function(a,c){(null==e||Math.abs(a.x-b)<Math.abs(e-b)&&(c<=d.dragState.oldFirstDisplayOrderValue||c>d.dragState.oldLastDisplayOrderValue+1))&&(e=a.x,f=a.$el)}),f!==d.dragState.$activeIndicator&&d.dragState.$activeIndicator&&d.dragState.$activeIndicator.removeClass("orderable-indicator-active"),d.dragHookPreventOrder(d.dragState.$dragElement,c,d.dragState.column)?d.dragState.orderPrevented=!0:(f!==d.dragState.$activeIndicator&&(d.dragState.$activeIndicator&&d.dragState.$activeIndicator.removeClass("orderable-indicator-active"),d.dragState.$activeIndicator=f,f.addClass("orderable-indicator-active"),d.dragState.newDisplayOrderValue=f.data("column-displayOrder")),d.dragState.orderPrevented=!1)},updateDisplayOrders:function(){var a=this,b=a.dragState.oldFirstDisplayOrderValue,c=a.dragState.oldLastDisplayOrderValue,d=a.dragState.newDisplayOrderValue,e=b<d,f=c-b+1,g=e?d-b-f:b-d;a.columns.each(function(a){var h=a.get("displayOrder"),i=h;e?h>c&&h<d?i=h-f:h>=b&&h<=c&&(i=h+g):h>=d&&h<b?i=h+f:h>=b&&h<=c&&(i=h-g),h!==i&&a.set("displayOrder",i,{silent:!0})})},resetDragState:function(){this.dragState.dragging=!1,this.dragState.dragIntention=!1,this.dragState.cell&&(this.dragState.cell.$el.removeClass("orderable-ordering"),this.dragState.cell=null),this.dragState.$dragElement&&(this.dragState.$dragElement.remove(),this.dragState.$dragElement=null),this.dragState.$activeIndicator&&this.dragState.$activeIndicator.removeClass("orderable-indicator-active"),this.dragState.$activeIndicator=null,this.dragState.column=null,this.dragState.coordinateElementStartX=null,this.dragState.coordinatePointerStartX=null,this.dragState.orderPrevented=null},addIndicators:function(){var b=this;b.indicators=[];var c=!1,d=0,e=0;a.each(b.headerCells,function(a){var f=a.column;if(c||f.get("orderable")){var g=f.get("displayOrder");c||(d=e=g-1),b.orderAlignTop||g===d+1||d!==e||(g=d+1),b.$el.append(b.createIndicator(g,a)),c=!0,d=g,e=f.get("displayOrder")}}),!a.isEmpty(b.headerCells)&&a.last(b.headerCells).column.get("orderable")&&b.$el.append(b.createIndicator(a.last(b.headerCells).column.get("displayOrder")+1,null)),b.setIndicatorHeight(b.grid.header.$el.height())},createIndicator:function(a,b){var d=this,e=c("<div></div>").addClass("orderable-indicator").data("column-cell",b).data("column-displayOrder",a);return d.indicators.push(e),e},updateIndicatorPosition:function(){var b=this;b.indicatorPositions={},a.each(b.indicators,function(a,c){var d,e=a.data("column-cell"),f=a.data("column-displayOrder");if(e)d=e.$el.position().left;else{var g=b.indicators[c-1].data("column-cell");d=g.$el.position().left+g.$el.width()}b.indicatorPositions[f]={x:d,$el:a},a.css("left",d)}),b.setIndicatorHeight()},setIndicatorHeight:function(){this.$el.children().height(this.grid.header.$el.height())},attachEvents:function(){var b=this;b.listenTo(b.columns,"resize",b.handleColumnResize),b.listenTo(b.columns,"remove",b.handleColumnRemove),b.listenTo(b.columns,"sort",b.handleColumnSort),b.listenTo(b.grid.collection,"backgrid:colgroup:updated",b.updateIndicatorPosition),b.listenTo(b.grid.collection,"backgrid:colgroup:changed",b.handleHeaderRender),b.resizeEvtHandler=a.debounce(a.bind(b.updateIndicatorPosition,b),250),c(window).on("resize",b.resizeEvtHandler)},handleColumnResize:function(){var a=this;a.updateIndicatorPosition(),a.setIndicatorHeight()},handleHeaderRender:function(){var b=this;a.defer(function(){b.setHeaderElements(),b.render(),b.updateIndicatorPosition()})},handleColumnRemove:function(a,b){var c=a.get("displayOrder");b.each(function(a){a.get("displayOrder")>c&&a.set("displayOrder",a.get("displayOrder")-1,{silent:!0})})},handleColumnSort:function(){this.grid.body.refresh()},setHeaderElements:function(){var b=this,c=b.header.headerRows||[b.header.row];b.headerCells=[],a.each(c,function(c){a.each(c.cells,function(c){var d=b.columns.get({cid:c.column.cid});a.isEmpty(d)||b.headerCells.push({$el:c.$el,el:c.el,column:d})})});var d=a.sortBy(b.headerCells,function(a){return b.columns.indexOf(a.column)});b.headerCells=a.filter(d,function(a){return a.column.get("renderable")===!0||"undefined"==typeof a.column.get("renderable")}),b.headerElements=a.map(b.headerCells,function(a){return a.el})},addDragHook:function(a,b){this.dragHooks[a]=b},removeDragHook:function(a){this.dragHooks.hasOwnProperty(a)&&delete this.dragHooks[a]},dragHookInvoke:function(b){var c=[].slice.apply(arguments);c.shift(),a.each(this.dragHooks,function(a){"function"==typeof a[b]&&a[b].apply(a,c)})},dragHookPreventOrder:function(){var b=!1;return a.each(this.dragHooks,function(a){"function"==typeof a.preventOrder&&(b|=a.preventOrder())}),b},_stopEvent:function(a){a.stopPropagation&&a.stopPropagation(),a.preventDefault&&a.preventDefault(),a.cancelBubble=!0,a.returnValue=!1},remove:function(){c(window).off("resize",this.resizeEvtHandler),Backbone.View.prototype.remove.call(this)}});var d=b.Extension.OrderableDragHook=function(){this.initialize.apply(this,arguments)};a.extend(d.prototype,{initialize:function(){},dragStart:function(){},dragMove:function(){},dragEnd:function(){},preventOrder:function(){}}),b.Extension.OrderableColumns.orderableColumnCollection=b.Columns.extend({sortKey:"displayOrder",comparator:function(a){return a.get(this.sortKey)||1e6},setPositions:function(){return a.each(this.models,function(a,b){a.set("displayOrder",a.get("displayOrder")||b+1,{silent:!0})}),this}})});