backgrid.js 26 KB

1
  1. !function(a,b){"function"==typeof define&&define.amd?define(["underscore","backbone"],function(c,d){return a.Backgrid=b(c,d)}):"object"==typeof exports?module.exports=b(require("underscore"),require("backbone")):a.Backgrid=b(a._,a.Backbone)}(this,function(a,b){"use strict";function c(a,b,c){var d=b-(a+"").length;d=d<0?0:d;for(var e="",f=0;f<d;f++)e+=c;return e+a}var d="\t\n\v\f\r   ᠎              \u2028\u2029\ufeff";if(!String.prototype.trim||d.trim()){d="["+d+"]";var e=new RegExp("^"+d+d+"*"),f=new RegExp(d+d+"*$");String.prototype.trim=function(){if(void 0===this||null===this)throw new TypeError("can't convert "+this+" to object");return String(this).replace(e,"").replace(f,"")}}var g=b.$,h={Extension:{},resolveNameToClass:function(b,c){if(a.isString(b)){var d=a.map(b.split("-"),function(a){return a.slice(0,1).toUpperCase()+a.slice(1)}).join("")+c,e=h[d]||h.Extension[d];if(a.isUndefined(e))throw new ReferenceError("Class '"+d+"' not found");return e}return b},callByNeed:function(){var b=arguments[0];if(!a.isFunction(b))return b;var c=arguments[1],d=[].slice.call(arguments,2);return b.apply(c,d+""?d:[])}};a.extend(h,b.Events);var i=h.Command=function(b){a.extend(this,{altKey:!!b.altKey,char:b.char,charCode:b.charCode,ctrlKey:!!b.ctrlKey,key:b.key,keyCode:b.keyCode,locale:b.locale,location:b.location,metaKey:!!b.metaKey,repeat:!!b.repeat,shiftKey:!!b.shiftKey,which:b.which})};a.extend(i.prototype,{moveUp:function(){return 38==this.keyCode},moveDown:function(){return 40===this.keyCode},moveLeft:function(){return this.shiftKey&&9===this.keyCode},moveRight:function(){return!this.shiftKey&&9===this.keyCode},save:function(){return 13===this.keyCode},cancel:function(){return 27===this.keyCode},passThru:function(){return!(this.moveUp()||this.moveDown()||this.moveLeft()||this.moveRight()||this.save()||this.cancel())}});var j=h.CellFormatter=function(){};a.extend(j.prototype,{fromRaw:function(a,b){return a},toRaw:function(a,b){return a}});var k=h.NumberFormatter=function(b){if(a.extend(this,this.defaults,b||{}),this.decimals<0||this.decimals>20)throw new RangeError("decimals must be between 0 and 20")};k.prototype=new j,a.extend(k.prototype,{defaults:{decimals:2,decimalSeparator:".",orderSeparator:","},HUMANIZED_NUM_RE:/(\d)(?=(?:\d{3})+$)/g,fromRaw:function(b,c){if(a.isNull(b)||a.isUndefined(b))return"";b=parseFloat(b).toFixed(~~this.decimals);var d=b.split("."),e=d[0],f=d[1]?(this.decimalSeparator||".")+d[1]:"";return e.replace(this.HUMANIZED_NUM_RE,"$1"+this.orderSeparator)+f},toRaw:function(b,c){if(b=b.trim(),""===b)return null;for(var d="",e=b.split(this.orderSeparator),f=0;f<e.length;f++)d+=e[f];var g=d.split(this.decimalSeparator);d="";for(var f=0;f<g.length;f++)d=d+g[f]+".";"."===d[d.length-1]&&(d=d.slice(0,d.length-1));var h=1*(1*d).toFixed(~~this.decimals);return a.isNumber(h)&&!a.isNaN(h)?h:void 0}});var l=h.PercentFormatter=function(){h.NumberFormatter.apply(this,arguments)};l.prototype=new h.NumberFormatter,a.extend(l.prototype,{defaults:a.extend({},k.prototype.defaults,{multiplier:1,symbol:"%"}),fromRaw:function(a,b){var c=[].slice.call(arguments,1);return c.unshift(a*this.multiplier),(k.prototype.fromRaw.apply(this,c)||"0")+this.symbol},toRaw:function(b,c){var d=b.split(this.symbol);if(d&&d[0]&&""===d[1]||null==d[1]){var e=k.prototype.toRaw.call(this,d[0]);return a.isUndefined(e)?e:e/this.multiplier}}});var m=h.DatetimeFormatter=function(b){if(a.extend(this,this.defaults,b||{}),!this.includeDate&&!this.includeTime)throw new Error("Either includeDate or includeTime must be true")};m.prototype=new j,a.extend(m.prototype,{defaults:{includeDate:!0,includeTime:!0,includeMilli:!1},DATE_RE:/^([+\-]?\d{4})-(\d{2})-(\d{2})$/,TIME_RE:/^(\d{2}):(\d{2}):(\d{2})(\.(\d{3}))?$/,ISO_SPLITTER_RE:/T|Z| +/,_convert:function(b,d){if(""===(b+"").trim())return null;var e,f=null;if(a.isNumber(b)){var g=new Date(b);e=c(g.getUTCFullYear(),4,0)+"-"+c(g.getUTCMonth()+1,2,0)+"-"+c(g.getUTCDate(),2,0),f=c(g.getUTCHours(),2,0)+":"+c(g.getUTCMinutes(),2,0)+":"+c(g.getUTCSeconds(),2,0)}else{b=b.trim();var h=b.split(this.ISO_SPLITTER_RE)||[];e=this.DATE_RE.test(h[0])?h[0]:"",f=e&&h[1]?h[1]:this.TIME_RE.test(h[0])?h[0]:""}var i=this.DATE_RE.exec(e)||[],j=this.TIME_RE.exec(f)||[];if(d){if(this.includeDate&&a.isUndefined(i[0]))return;if(this.includeTime&&a.isUndefined(j[0]))return;if(!this.includeDate&&e)return;if(!this.includeTime&&f)return}var g=new Date(Date.UTC(1*i[1]||0,1*i[2]-1||0,1*i[3]||0,1*j[1]||null,1*j[2]||null,1*j[3]||null,1*j[5]||null)),k="";return this.includeDate&&(k=c(g.getUTCFullYear(),4,0)+"-"+c(g.getUTCMonth()+1,2,0)+"-"+c(g.getUTCDate(),2,0)),this.includeTime&&(k=k+(this.includeDate?"T":"")+c(g.getUTCHours(),2,0)+":"+c(g.getUTCMinutes(),2,0)+":"+c(g.getUTCSeconds(),2,0),this.includeMilli&&(k=k+"."+c(g.getUTCMilliseconds(),3,0))),this.includeDate&&this.includeTime&&(k+="Z"),k},fromRaw:function(b,c){return a.isNull(b)||a.isUndefined(b)?"":this._convert(b)},toRaw:function(a,b){return this._convert(a,!0)}});var n=h.StringFormatter=function(){};n.prototype=new j,a.extend(n.prototype,{fromRaw:function(b,c){return a.isUndefined(b)||a.isNull(b)?"":b+""}});var o=h.EmailFormatter=function(){};o.prototype=new j,a.extend(o.prototype,{toRaw:function(b,c){var d=b.trim().split("@");if(2===d.length&&a.all(d))return b}});var p=h.SelectFormatter=function(){};p.prototype=new j,a.extend(p.prototype,{fromRaw:function(b,c){return a.isArray(b)?b:null!=b?[b]:[]}});var q=h.CellEditor=b.View.extend({initialize:function(a){this.formatter=a.formatter,this.column=a.column,this.column instanceof B||(this.column=new B(this.column)),this.listenTo(this.model,"backgrid:editing",this.postRender)},postRender:function(a,b){return null!=b&&b.get("name")!=this.column.get("name")||this.$el.focus(),this}}),r=h.InputCellEditor=q.extend({tagName:"input",attributes:{type:"text"},events:{blur:"saveOrCancel",keydown:"saveOrCancel"},initialize:function(a){r.__super__.initialize.apply(this,arguments),a.placeholder&&this.$el.attr("placeholder",a.placeholder)},render:function(){var a=this.model;return this.$el.val(this.formatter.fromRaw(a.get(this.column.get("name")),a)),this},saveOrCancel:function(b){var c=this.formatter,d=this.model,e=this.column,f=new i(b),g="blur"===b.type;if(f.moveUp()||f.moveDown()||f.moveLeft()||f.moveRight()||f.save()||g){b.preventDefault(),b.stopPropagation();var h=this.$el.val(),j=c.toRaw(h,d);a.isUndefined(j)?d.trigger("backgrid:error",d,e,h):(d.set(e.get("name"),j),d.trigger("backgrid:edited",d,e,f))}else f.cancel()&&(b.stopPropagation(),d.trigger("backgrid:edited",d,e,f))},postRender:function(a,b){if(null==b||b.get("name")==this.column.get("name"))if("right"===this.$el.css("text-align")){var c=this.$el.val();this.$el.focus().val(null).val(c)}else this.$el.focus();return this}}),s=h.Cell=b.View.extend({tagName:"td",formatter:j,editor:r,events:{click:"enterEditMode"},initialize:function(b){this.column=b.column,this.column instanceof B||(this.column=new B(this.column));var c=this.column,d=this.model,e=this.$el,f=h.resolveNameToClass(c.get("formatter")||this.formatter,"Formatter");a.isFunction(f.fromRaw)||a.isFunction(f.toRaw)||(f=new f),this.formatter=f,this.editor=h.resolveNameToClass(this.editor,"CellEditor"),this.listenTo(d,"change:"+c.get("name"),function(){e.hasClass("editor")||this.render()}),this.listenTo(d,"backgrid:error",this.renderError),this.listenTo(c,"change:editable change:sortable change:renderable",function(a){var b=a.changedAttributes();for(var c in b)b.hasOwnProperty(c)&&e.toggleClass(c,b[c])}),this.updateStateClassesMaybe()},updateStateClassesMaybe:function(){var a=this.model,b=this.column,c=this.$el;c.toggleClass("editable",h.callByNeed(b.editable(),b,a)),c.toggleClass("sortable",h.callByNeed(b.sortable(),b,a)),c.toggleClass("renderable",h.callByNeed(b.renderable(),b,a))},render:function(){var a=this.$el;a.empty();var b=this.model,c=this.column.get("name");return a.text(this.formatter.fromRaw(b.get(c),b)),a.addClass(c),this.updateStateClassesMaybe(),this.delegateEvents(),this},enterEditMode:function(){var a=this.model,b=this.column,c=h.callByNeed(b.editable(),b,a);c&&(this.currentEditor=new this.editor({column:this.column,model:this.model,formatter:this.formatter}),a.trigger("backgrid:edit",a,b,this,this.currentEditor),this.undelegateEvents(),this.$el.empty(),this.$el.append(this.currentEditor.$el),this.currentEditor.render(),this.$el.addClass("editor"),a.trigger("backgrid:editing",a,b,this,this.currentEditor))},renderError:function(a,b){null!=b&&b.get("name")!=this.column.get("name")||this.$el.addClass("error")},exitEditMode:function(){this.$el.removeClass("error"),this.currentEditor.remove(),this.stopListening(this.currentEditor),delete this.currentEditor,this.$el.removeClass("editor"),this.render()},remove:function(){return this.currentEditor&&(this.currentEditor.remove.apply(this.currentEditor,arguments),delete this.currentEditor),s.__super__.remove.apply(this,arguments)}}),t=h.StringCell=s.extend({className:"string-cell",formatter:n}),u=h.UriCell=s.extend({className:"uri-cell",title:null,target:"_blank",initialize:function(a){u.__super__.initialize.apply(this,arguments),this.title=a.title||this.title,this.target=a.target||this.target},render:function(){this.$el.empty();var a=this.model.get(this.column.get("name")),b=this.formatter.fromRaw(a,this.model);return this.$el.append(g("<a>",{tabIndex:-1,href:a,title:this.title||b,target:this.target}).text(b)),this.delegateEvents(),this}}),v=(h.EmailCell=t.extend({className:"email-cell",formatter:o,render:function(){this.$el.empty();var a=this.model,b=this.formatter.fromRaw(a.get(this.column.get("name")),a);return this.$el.append(g("<a>",{tabIndex:-1,href:"mailto:"+b,title:b}).text(b)),this.delegateEvents(),this}}),h.NumberCell=s.extend({className:"number-cell",decimals:k.prototype.defaults.decimals,decimalSeparator:k.prototype.defaults.decimalSeparator,orderSeparator:k.prototype.defaults.orderSeparator,formatter:k,initialize:function(a){v.__super__.initialize.apply(this,arguments);var b=this.formatter;b.decimals=this.decimals,b.decimalSeparator=this.decimalSeparator,b.orderSeparator=this.orderSeparator}})),w=(h.IntegerCell=v.extend({className:"integer-cell",decimals:0}),h.PercentCell=v.extend({className:"percent-cell",multiplier:l.prototype.defaults.multiplier,symbol:l.prototype.defaults.symbol,formatter:l,initialize:function(){w.__super__.initialize.apply(this,arguments);var a=this.formatter;a.multiplier=this.multiplier,a.symbol=this.symbol}})),x=h.DatetimeCell=s.extend({className:"datetime-cell",includeDate:m.prototype.defaults.includeDate,includeTime:m.prototype.defaults.includeTime,includeMilli:m.prototype.defaults.includeMilli,formatter:m,initialize:function(b){x.__super__.initialize.apply(this,arguments);var c=this.formatter;c.includeDate=this.includeDate,c.includeTime=this.includeTime,c.includeMilli=this.includeMilli;var d=this.includeDate?"YYYY-MM-DD":"";d+=this.includeDate&&this.includeTime?"T":"",d+=this.includeTime?"HH:mm:ss":"",d+=this.includeTime&&this.includeMilli?".SSS":"",this.editor=this.editor.extend({attributes:a.extend({},this.editor.prototype.attributes,this.editor.attributes,{placeholder:d})})}}),y=(h.DateCell=x.extend({className:"date-cell",includeTime:!1}),h.TimeCell=x.extend({className:"time-cell",includeDate:!1}),h.BooleanCellEditor=q.extend({tagName:"input",attributes:{tabIndex:-1,type:"checkbox"},events:{mousedown:function(){this.mouseDown=!0},blur:"enterOrExitEditMode",mouseup:function(){this.mouseDown=!1},change:"saveOrCancel",keydown:"saveOrCancel"},render:function(){var a=this.model,b=this.formatter.fromRaw(a.get(this.column.get("name")),a);return this.$el.prop("checked",b),this},enterOrExitEditMode:function(a){if(!this.mouseDown){var b=this.model;b.trigger("backgrid:edited",b,this.column,new i(a))}},saveOrCancel:function(a){var b=this.model,c=this.column,d=this.formatter,e=new i(a);if(e.passThru()&&"change"!=a.type)return!0;e.cancel()&&(a.stopPropagation(),b.trigger("backgrid:edited",b,c,e));var f=this.$el;if(e.save()||e.moveLeft()||e.moveRight()||e.moveUp()||e.moveDown()){a.preventDefault(),a.stopPropagation();var g=d.toRaw(f.prop("checked"),b);b.set(c.get("name"),g),b.trigger("backgrid:edited",b,c,e)}else if("change"==a.type){var g=d.toRaw(f.prop("checked"),b);b.set(c.get("name"),g),f.focus()}}})),z=(h.BooleanCell=s.extend({className:"boolean-cell",editor:y,events:{click:"enterEditMode"},render:function(){this.$el.empty();var a=this.model,b=this.column,c=h.callByNeed(b.editable(),b,a);return this.$el.append(g("<input>",{tabIndex:-1,type:"checkbox",checked:this.formatter.fromRaw(a.get(b.get("name")),a),disabled:!c})),this.delegateEvents(),this}}),h.SelectCellEditor=q.extend({tagName:"select",events:{change:"save",blur:"close",keydown:"close"},template:a.template('<option value="<%- value %>" <%= selected ? \'selected="selected"\' : "" %>><%- text %></option>',null,{variable:null,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g}),setOptionValues:function(b){this.optionValues=b,this.optionValues=a.result(this,"optionValues")},setMultiple:function(a){this.multiple=a,this.$el.prop("multiple",a)},_renderOptions:function(b,c){for(var d="",e=0;e<b.length;e++)d+=this.template({text:b[e][0],value:b[e][1],selected:a.indexOf(c,b[e][1])>-1});return d},render:function(){this.$el.empty();var b=a.result(this,"optionValues"),c=this.model,d=this.formatter.fromRaw(c.get(this.column.get("name")),c);if(!a.isArray(b))throw new TypeError("optionValues must be an array");for(var e=null,f=null,e=null,h=null,i=null,j=0;j<b.length;j++){var e=b[j];if(a.isArray(e))f=e[0],e=e[1],this.$el.append(this.template({text:f,value:e,selected:a.indexOf(d,e)>-1}));else{if(!a.isObject(e))throw new TypeError("optionValues elements must be a name-value pair or an object hash of { name: 'optgroup label', value: [option name-value pairs] }");h=e.name,i=g("<optgroup></optgroup>",{label:h}),i.append(this._renderOptions.call(this,e.values,d)),this.$el.append(i)}}return this.delegateEvents(),this},save:function(a){var b=this.model,c=this.column;b.set(c.get("name"),this.formatter.toRaw(this.$el.val(),b))},close:function(a){var b=this.model,c=this.column,d=new i(a);d.cancel()?(a.stopPropagation(),b.trigger("backgrid:edited",b,c,new i(a))):(d.save()||d.moveLeft()||d.moveRight()||d.moveUp()||d.moveDown()||"blur"==a.type)&&(a.preventDefault(),a.stopPropagation(),this.save(a),b.trigger("backgrid:edited",b,c,new i(a)))}})),A=h.SelectCell=s.extend({className:"select-cell",editor:z,multiple:!1,formatter:p,optionValues:void 0,delimiter:", ",initialize:function(a){A.__super__.initialize.apply(this,arguments),this.listenTo(this.model,"backgrid:edit",function(a,b,c,d){b.get("name")==this.column.get("name")&&(d.setOptionValues(this.optionValues),d.setMultiple(this.multiple))})},render:function(){this.$el.empty();var b=a.result(this,"optionValues"),c=this.model,d=this.formatter.fromRaw(c.get(this.column.get("name")),c),e=[];try{if(!a.isArray(b)||a.isEmpty(b))throw new TypeError;for(var f=0;f<d.length;f++)for(var g=d[f],h=0;h<b.length;h++){var i=b[h];if(a.isArray(i)){var j=i[0],i=i[1];i==g&&e.push(j)}else{if(!a.isObject(i))throw new TypeError;for(var k=i.values,l=0;l<k.length;l++){var m=k[l];m[1]==g&&e.push(m[0])}}}this.$el.append(e.join(this.delimiter))}catch(a){if(a instanceof TypeError)throw new TypeError("'optionValues' must be of type {Array.<Array>|Array.<{name: string, values: Array.<Array>}>}");throw a}return this.delegateEvents(),this}}),B=h.Column=b.Model.extend({defaults:{name:void 0,label:void 0,sortable:!0,editable:!0,renderable:!0,formatter:void 0,sortType:"cycle",sortValue:void 0,direction:null,cell:void 0,headerCell:void 0},initialize:function(){this.has("label")||this.set({label:this.get("name")},{silent:!0});var a=h.resolveNameToClass(this.get("headerCell"),"HeaderCell"),b=h.resolveNameToClass(this.get("cell"),"Cell");this.set({cell:b,headerCell:a},{silent:!0})},sortValue:function(){var b=this.get("sortValue");return a.isString(b)?this[b]:a.isFunction(b)?b:function(a,b){return a.get(b)}}});a.each(["sortable","renderable","editable"],function(b){B.prototype[b]=function(){var c=this.get(b);return a.isString(c)?this[c]:a.isFunction(c)?c:!!c}});var C=h.Columns=b.Collection.extend({model:B}),D=h.Row=b.View.extend({tagName:"tr",initialize:function(a){var c=this.columns=a.columns;c instanceof b.Collection||(c=this.columns=new C(c));for(var d=this.cells=[],e=0;e<c.length;e++)d.push(this.makeCell(c.at(e),a));this.listenTo(c,"add",function(b,c){var e=c.indexOf(b),f=this.makeCell(b,a);d.splice(e,0,f);var g=this.$el;0===e?g.prepend(f.render().$el):e===c.length-1?g.append(f.render().$el):g.children().eq(e).before(f.render().$el)}),this.listenTo(c,"remove",function(a,b,c){d[c.index].remove(),d.splice(c.index,1)})},makeCell:function(a){return new(a.get("cell"))({column:a,model:this.model})},render:function(){this.$el.empty();for(var a=document.createDocumentFragment(),b=0;b<this.cells.length;b++)a.appendChild(this.cells[b].render().el);return this.el.appendChild(a),this.delegateEvents(),this},remove:function(){for(var a=0;a<this.cells.length;a++){var c=this.cells[a];c.remove.apply(c,arguments)}return b.View.prototype.remove.apply(this,arguments)}}),E=h.EmptyRow=b.View.extend({tagName:"tr",emptyText:null,initialize:function(a){this.emptyText=a.emptyText,this.columns=a.columns},render:function(){this.$el.empty();var b=document.createElement("td");b.setAttribute("colspan",this.columns.length);var c=document.createElement("span");return c.innerHTML=a.result(this,"emptyText"),b.appendChild(c),this.el.className="empty",this.el.appendChild(b),this}}),F=h.HeaderCell=b.View.extend({tagName:"th",events:{"click button":"onClick"},initialize:function(a){this.column=a.column,this.column instanceof B||(this.column=new B(this.column));var b=this.column,c=this.collection,d=this.$el;this.listenTo(b,"change:editable change:sortable change:renderable",function(a){var b=a.changedAttributes();for(var c in b)b.hasOwnProperty(c)&&d.toggleClass(c,b[c])}),this.listenTo(b,"change:direction",this.setCellDirection),this.listenTo(b,"change:name change:label",this.render),h.callByNeed(b.editable(),b,c)&&d.addClass("editable"),h.callByNeed(b.sortable(),b,c)&&d.addClass("sortable"),h.callByNeed(b.renderable(),b,c)&&d.addClass("renderable"),this.listenTo(c.fullCollection||c,"backgrid:sorted",this.removeCellDirection)},removeCellDirection:function(){this.$el.removeClass("ascending").removeClass("descending"),this.column.set("direction",null)},setCellDirection:function(a,b){this.$el.removeClass("ascending").removeClass("descending"),a.cid==this.column.cid&&this.$el.addClass(b)},onClick:function(a){function b(a,b){"ascending"===d.get("direction")?e.trigger(f,b,"descending"):"descending"===d.get("direction")?e.trigger(f,b,null):e.trigger(f,b,"ascending")}function c(a,b){"ascending"===d.get("direction")?e.trigger(f,b,"descending"):e.trigger(f,b,"ascending")}a.preventDefault();var d=this.column,e=this.collection,f="backgrid:sort",g=h.callByNeed(d.sortable(),d,this.collection);if(g){var i=d.get("sortType");"toggle"===i?c(this,d):b(this,d)}},render:function(){this.$el.empty();var a,b=this.column,c=h.callByNeed(b.sortable(),b,this.collection);return a=c?g("<button>").text(b.get("label")).append("<span class='sort-caret' aria-hidden='true'></span>"):document.createTextNode(b.get("label")),this.$el.append(a),this.$el.addClass(b.get("name")),this.$el.addClass(b.get("direction")),this.delegateEvents(),this}}),G=(h.HeaderRow=h.Row.extend({initialize:function(){h.Row.prototype.initialize.apply(this,arguments)},makeCell:function(a,b){var c=a.get("headerCell")||b.headerCell||F;return c=new c({column:a,collection:this.collection})}}),h.Header=b.View.extend({tagName:"thead",initialize:function(a){this.columns=a.columns,this.columns instanceof b.Collection||(this.columns=new C(this.columns)),this.row=new h.HeaderRow({columns:this.columns,collection:this.collection})},render:function(){return this.$el.append(this.row.render().$el),this.delegateEvents(),this},remove:function(){return this.row.remove.apply(this.row,arguments),b.View.prototype.remove.apply(this,arguments)}})),H=h.Body=b.View.extend({tagName:"tbody",initialize:function(a){this.columns=a.columns,this.columns instanceof b.Collection||(this.columns=new C(this.columns)),this.row=a.row||this.row||D,this.rows=this.collection.map(function(a){var b=new this.row({columns:this.columns,model:a});return b},this),this.emptyText=a.emptyText,this._unshiftEmptyRowMayBe();var c=this.collection;this.listenTo(c,"add",this.insertRow),this.listenTo(c,"remove",this.removeRow),this.listenTo(c,"sort",this.refresh),this.listenTo(c,"reset",this.refresh),this.listenTo(c,"backgrid:sort",this.sort),this.listenTo(c,"backgrid:edited",this.moveToNextCell),this.listenTo(this.columns,"add remove",this.updateEmptyRow)},_unshiftEmptyRowMayBe:function(){if(0===this.rows.length&&null!=this.emptyText)return this.emptyRow=new E({emptyText:this.emptyText,columns:this.columns}),this.rows.unshift(this.emptyRow),!0},insertRow:function(a,c,d){if(this.rows[0]instanceof E&&this.rows.pop().remove(),!(c instanceof b.Collection||d))return void this.collection.add(a,d=c);var e=new this.row({columns:this.columns,model:a}),f=c.indexOf(a);this.rows.splice(f,0,e);var g=this.$el,h=g.children(),i=e.render().$el;return f>=h.length?g.append(i):h.eq(f).before(i),this},removeRow:function(b,c,d){return d?((a.isUndefined(d.render)||d.render)&&this.rows[d.index].remove(),this.rows.splice(d.index,1),this._unshiftEmptyRowMayBe()&&this.render(),this):(this.collection.remove(b,d=c),void(this._unshiftEmptyRowMayBe()&&this.render()))},updateEmptyRow:function(){null!=this.emptyRow&&this.emptyRow.render()},refresh:function(){for(var a=0;a<this.rows.length;a++)this.rows[a].remove();return this.rows=this.collection.map(function(a){var b=new this.row({columns:this.columns,model:a});return b},this),this._unshiftEmptyRowMayBe(),this.render(),this.collection.trigger("backgrid:refresh",this),this},render:function(){this.$el.empty();for(var a=document.createDocumentFragment(),b=0;b<this.rows.length;b++){var c=this.rows[b];a.appendChild(c.render().el)}return this.el.appendChild(a),this.delegateEvents(),this},remove:function(){for(var a=0;a<this.rows.length;a++){var c=this.rows[a];c.remove.apply(c,arguments)}return b.View.prototype.remove.apply(this,arguments)},sort:function(c,d){if(!a.contains(["ascending","descending",null],d))throw new RangeError('direction must be one of "ascending", "descending" or `null`');a.isString(c)&&(c=this.columns.findWhere({name:c}));var e,f=this.collection;e="ascending"===d?-1:"descending"===d?1:null;var g=this.makeComparator(c.get("name"),e,e?c.sortValue():function(a){return 1*a.cid.replace("c","")});return b.PageableCollection&&f instanceof b.PageableCollection?(f.setSorting(e&&c.get("name"),e,{sortValue:c.sortValue()}),f.fullCollection?(null==f.fullCollection.comparator&&(f.fullCollection.comparator=g),f.fullCollection.sort(),f.trigger("backgrid:sorted",c,d,f),c.set("direction",d)):f.fetch({reset:!0,success:function(){f.trigger("backgrid:sorted",c,d,f),c.set("direction",d)}})):(f.comparator=g,f.sort(),f.trigger("backgrid:sorted",c,d,f),c.set("direction",d)),this},makeComparator:function(a,b,c){return function(d,e){var f,g=c(d,a),h=c(e,a);return 1===b&&(f=g,g=h,h=f),g===h?0:g<h?-1:1}},moveToNextCell:function(a,b,c){var d,e,f,g,i,j=this.collection.indexOf(a),k=this.columns.indexOf(b);if(k===-1)return this;if(this.rows[j].cells[k].exitEditMode(),c.moveUp()||c.moveDown()||c.moveLeft()||c.moveRight()||c.save()){var l=this.columns.length,m=l*this.collection.length;if(c.moveUp()||c.moveDown()){g=j+(c.moveUp()?-1:1);var n=this.rows[g];n?(d=n.cells[k],h.callByNeed(d.column.editable(),d.column,a)&&(d.enterEditMode(),a.trigger("backgrid:next",g,k,!1))):a.trigger("backgrid:next",g,k,!0)}else if(c.moveLeft()||c.moveRight()){for(var o=c.moveRight(),p=j*l+k+(o?1:-1);p>=0&&p<m;o?p++:p--)if(g=~~(p/l),i=p-g*l,d=this.rows[g].cells[i],e=h.callByNeed(d.column.renderable(),d.column,d.model),f=h.callByNeed(d.column.editable(),d.column,a),e&&f){d.enterEditMode(),a.trigger("backgrid:next",g,i,!1);break}p==m&&a.trigger("backgrid:next",~~(p/l),p-g*l,!0)}}return this}});h.Footer=b.View.extend({tagName:"tfoot",initialize:function(a){this.columns=a.columns,this.columns instanceof b.Collection||(this.columns=new h.Columns(this.columns))}}),h.Grid=b.View.extend({tagName:"table",className:"backgrid",header:G,body:H,footer:null,initialize:function(c){c.columns instanceof b.Collection||(c.columns=new C(c.columns||this.columns)),this.columns=c.columns,this.caption=c.caption;var d=a.omit(c,["el","id","attributes","className","tagName","events"]);this.body=c.body||this.body,this.body=new this.body(d),this.header=c.header||this.header,this.header&&(this.header=new this.header(d)),this.footer=c.footer||this.footer,this.footer&&(this.footer=new this.footer(d)),this.listenTo(this.columns,"reset",function(){this.header&&(this.header=new(this.header.remove().constructor)(d)),this.body=new(this.body.remove().constructor)(d),this.footer&&(this.footer=new(this.footer.remove().constructor)(d)),this.render()})},insertRow:function(){return this.body.insertRow.apply(this.body,arguments),this},removeRow:function(){return this.body.removeRow.apply(this.body,arguments),this},insertColumn:function(){return this.columns.add.apply(this.columns,arguments),this},removeColumn:function(){return this.columns.remove.apply(this.columns,arguments),this},sort:function(){return this.body.sort.apply(this.body,arguments),this},render:function(){return this.$el.empty(),this.caption&&this.$el.append(g("<caption>").text(this.caption)),this.header&&this.$el.append(this.header.render().$el),this.footer&&this.$el.append(this.footer.render().$el),this.$el.append(this.body.render().$el),this.delegateEvents(),this.trigger("backgrid:rendered",this),this},remove:function(){return this.header&&this.header.remove.apply(this.header,arguments),this.body.remove.apply(this.body,arguments),this.footer&&this.footer.remove.apply(this.footer,arguments),b.View.prototype.remove.apply(this,arguments)}});return h});