diff --git a/build/ReactTable.js b/build/ReactTable.js index 5b566c7..d376138 100644 --- a/build/ReactTable.js +++ b/build/ReactTable.js @@ -173,7 +173,7 @@ var ReactTable = React.createClass({displayName: 'ReactTable', var totalHeight = target.find("tbody").height(); if( scrolled / (totalHeight-scrolledHeight) > .8 ){ this.setState({ - rowMultiplier: this.state.rowMultiplier + 1 + rows: this.addMoreRows(true) }); } }, @@ -208,25 +208,36 @@ var ReactTable = React.createClass({displayName: 'ReactTable', adjustHeaders.call(this); bindHeadersToMenu($(this.getDOMNode())); }, - addMoreRows: function(){ + addMoreRows: function(calledFromScroll){ + if( this.props.justAdded ){ + console.log("just added"); + this.props.justAdded = false; + return this.state.rows; + } + console.log("rasterizing"); var rasterizedData = rasterizeTree({ node: this.state.rootNode, firstColumn: this.state.columnDefs[0], selectedDetailRows: this.state.selectedDetailRows }); + if( !calledFromScroll ) + this.props.rowMultiplier = this.props.rowMultiplier ? this.props.rowMultiplier : 0; + else + this.props.rowMultiplier = (this.props.rowMultiplier === undefined ? 0 : this.props.rowMultiplier + 1); - var upperBound = (this.state.rowMultiplier + 1) * this.state.itemsPerScroll; + var upperBound = (this.props.rowMultiplier + 1) * this.state.itemsPerScroll; var rowsToDisplay = []; - if( this.state.rows.length < upperBound && this.state.rows.length < rasterizedData.length ) { - var lowerBound = this.state.rowMultiplier * this.state.itemsPerScroll; + if( calledFromScroll && this.state.rows.length < upperBound && this.state.rows.length < rasterizedData.length ) { + var lowerBound = this.state.rows.length; rowsToDisplay = rasterizedData.slice(lowerBound, upperBound); - this.state.rows = this.state.rows.concat(rowsToDisplay.map(rowMapper, this)); + this.props.justAdded = true; + return this.state.rows.concat(rowsToDisplay.map(rowMapper, this)) } else { rowsToDisplay = rasterizedData.slice(0, upperBound); - this.state.rows = rowsToDisplay.map(rowMapper, this); + return rowsToDisplay.map(rowMapper, this) } }, render: function () { @@ -244,7 +255,7 @@ var ReactTable = React.createClass({displayName: 'ReactTable', this.state.rows = rowsToDisplay.map(rowMapper, this); } else{ - this.addMoreRows(); + this.state.rows = this.addMoreRows(); } var headers = buildHeaders(this); diff --git a/build/ReactTableEventHandlers.js b/build/ReactTableEventHandlers.js index e8fc04a..df03909 100644 --- a/build/ReactTableEventHandlers.js +++ b/build/ReactTableEventHandlers.js @@ -13,7 +13,6 @@ function ReactTableGetInitialState() { firstColumnLabel: _construct1StColumnLabel(this), extraStyle: {}, rows: [], - rowMultiplier: 0, hasMoreRows: false, itemsPerScroll: this.props.itemsPerScroll ? this.props.itemsPerScroll : 100 }; diff --git a/dist/react-table.js b/dist/react-table.js index 281f2c3..f7043cc 100644 --- a/dist/react-table.js +++ b/dist/react-table.js @@ -887,7 +887,7 @@ var ReactTable = React.createClass({displayName: 'ReactTable', var totalHeight = target.find("tbody").height(); if( scrolled / (totalHeight-scrolledHeight) > .8 ){ this.setState({ - rowMultiplier: this.state.rowMultiplier + 1 + rows: this.addMoreRows(true) }); } }, @@ -922,25 +922,36 @@ var ReactTable = React.createClass({displayName: 'ReactTable', adjustHeaders.call(this); bindHeadersToMenu($(this.getDOMNode())); }, - addMoreRows: function(){ + addMoreRows: function(calledFromScroll){ + if( this.props.justAdded ){ + console.log("just added"); + this.props.justAdded = false; + return this.state.rows; + } + console.log("rasterizing"); var rasterizedData = rasterizeTree({ node: this.state.rootNode, firstColumn: this.state.columnDefs[0], selectedDetailRows: this.state.selectedDetailRows }); + if( !calledFromScroll ) + this.props.rowMultiplier = this.props.rowMultiplier ? this.props.rowMultiplier : 0; + else + this.props.rowMultiplier = (this.props.rowMultiplier === undefined ? 0 : this.props.rowMultiplier + 1); - var upperBound = (this.state.rowMultiplier + 1) * this.state.itemsPerScroll; + var upperBound = (this.props.rowMultiplier + 1) * this.state.itemsPerScroll; var rowsToDisplay = []; - if( this.state.rows.length < upperBound && this.state.rows.length < rasterizedData.length ) { - var lowerBound = this.state.rowMultiplier * this.state.itemsPerScroll; + if( calledFromScroll && this.state.rows.length < upperBound && this.state.rows.length < rasterizedData.length ) { + var lowerBound = this.state.rows.length; rowsToDisplay = rasterizedData.slice(lowerBound, upperBound); - this.state.rows = this.state.rows.concat(rowsToDisplay.map(rowMapper, this)); + this.props.justAdded = true; + return this.state.rows.concat(rowsToDisplay.map(rowMapper, this)) } else { rowsToDisplay = rasterizedData.slice(0, upperBound); - this.state.rows = rowsToDisplay.map(rowMapper, this); + return rowsToDisplay.map(rowMapper, this) } }, render: function () { @@ -958,7 +969,7 @@ var ReactTable = React.createClass({displayName: 'ReactTable', this.state.rows = rowsToDisplay.map(rowMapper, this); } else{ - this.addMoreRows(); + this.state.rows = this.addMoreRows(); } var headers = buildHeaders(this); @@ -1288,7 +1299,6 @@ function _computePageDisplayRange(currentPage, maxDisplayedPages) { firstColumnLabel: _construct1StColumnLabel(this), extraStyle: {}, rows: [], - rowMultiplier: 0, hasMoreRows: false, itemsPerScroll: this.props.itemsPerScroll ? this.props.itemsPerScroll : 100 }; diff --git a/dist/react-table.min.js b/dist/react-table.min.js index f822829..28eeb0e 100644 --- a/dist/react-table.min.js +++ b/dist/react-table.min.js @@ -1,2 +1,2 @@ -/*! react-table 21-05-2015 Author: Erfang Chen */ -function buildLAFConfigObject(a){var b=a.formatInstructions,c={multiplier:1,roundTo:2,unit:null,alignment:getColumnAlignment(a)};if(!b)return c;for(var d=b.split(/\s+/),e=0;e5?"right":"left",h={};for(var i in d)h[i]=d[i];h[g]="100%",c.push(React.DOM.div({style:{position:"relative"},className:"menu-item menu-item-hoverable"},React.DOM.div(null,e),React.DOM.div({className:"menu-item-input",style:h},React.DOM.div({style:{display:"block"}},b[a.props.customMenuItems[e][f]]))))}return c}function buildMenu(a){var b=a.table,c=a.columnDef,d=a.style,e=a.isFirstColumn,f={};"right"==d.textAlign?f.right="0%":f.left="0%";var g=[],h={sort:[React.DOM.div({className:"menu-item",onClick:b.handleSort.bind(null,c,!0)},"Sort Asc"),React.DOM.div({className:"menu-item",onClick:b.handleSort.bind(null,c,!1)},"Sort Dsc")],summarize:[SummarizeControl({table:b,columnDef:c}),React.DOM.div({className:"menu-item",onClick:b.handleGroupBy.bind(null,null)},"Clear Summary")],remove:[React.DOM.div({className:"menu-item",onClick:b.handleRemove.bind(null,c)},"Remove Column")]};if(b.props.defaultMenuItems)for(var i=0;i0&&!a.props.disablePagination?PageNavigator({items:b.allPages.slice(b.pageDisplayRange.start,b.pageDisplayRange.end),activeItem:a.state.currentPage,numPages:b.pageEnd,handleClick:a.handlePageClick}):null}function getSectorName(a,b){var c="",d=null;if("number"==b.format||"currency"==b.format){var e=_resolveNumericSectorName(b,a);c=e.sectorName,d=e.sortIndex}else c=a[b.colTag];return{sectorName:c||"Other",sortIndex:d}}function aggregateSector(a,b,c){for(var d={},e=1;eb.count||d===b.count&&a.data[c].aggregationTiebreaker>a.data[b.index].aggregationTiebreaker)&&(b.count=d,b.index=c)}return-1==b.index?"":a.data[b.index][a.columnDef.colTag]}function exportToExcel(a){var b="";$.each(a.headers,function(a,c){b+=""}),b+="";var c=1;$.each(a.data,function(a,d){if(d.length>0&&d[0].match("Grand Total"))return void c++;b+="";var e=0;$.each(d,function(a,c){b+="",e++}),c++,b+=""}),b+="
"+parseString(c)+"
"+parseString(c)+"
";var d="";d+="",d+="",d+="",d+="",d+=b,d+="",d+="";var e=window.navigator.userAgent,f=e.indexOf("MSIE ");if(f>0||navigator.userAgent.match(/Trident.*rv\:11\./)){var g=$("").css("display","none").attr("id","ieExcelFrame").appendTo("body");ieExcelFrame.document.open("txt/html","replace"),ieExcelFrame.document.write(d),ieExcelFrame.document.close(),ieExcelFrame.focus(),ieExcelFrame.document.execCommand("SaveAs",!0,"exportData.xls"),g.remove()}else{var h="base64,"+$.base64.encode(d);window.open("data:application/vnd.ms-excel;filename=exportData.doc;"+h)}}function exportToPDF(a){var b={separator:",",ignoreColumn:[],tableName:"yourTableName",pdfFontSize:6,pdfLeftMargin:20},c=new jsPDF("l","pt","letter",!0),d=[],e=b.pdfLeftMargin;$.each(a.headers,function(a,b){var c=4.5*parseString(b).length;(!d[a]||d[a]0&&b[0].match("Grand Total")||$.each(b,function(a,b){var c=4.5*parseString(b).length;(!d[a]||d[a]752){var g=752/f;c.setFontSize(g*b.pdfFontSize);for(var h=0;hd?b+c:b},e);c.text(f,20,parseString(b))});var i=20,j=1,k=0,l=1;$.each(a.data,function(a,b){b.length>0&&b[0].match("Grand Total")||(l++,l%50==0&&(c.addPage(),j++,l=1),k=i+10*l,$.each(b,function(a,b){var f=d.reduce(function(b,c,d){return a>d?b+c:b},e);c.text(f,k,parseString(b))}))}),c.output("save","AMI-table.pdf")}function parseString(a){if("string"!=typeof a){if(!a||!a.toString)return"";a=a.toString()}var b=a.trim();return b=b.replace(/[^\x00-\x7F]/g,""),b=b.substr(0,20)}function topPosition(a){return a?a.offsetTop+topPosition(a.offsetParent):0}function generateSectorKey(a){return null==a?"":a.join(SECTOR_SEPARATOR)}function generateRowKey(a,b){var c;return c=a.isDetail?b?a[b]:a.rowCount:generateSectorKey(a.sectorPath)}function rowMapper(a){var b=this.props.rowKey,c=generateRowKey(a,b);return Row({key:c,data:a,extraStyle:_getExtraStyle(c,this.state.extraStyle),isSelected:_isRowSelected(a,this.props.rowKey,this.state.selectedDetailRows,this.state.selectedSummaryRows),onSelect:this.handleSelect,onRightClick:this.props.onRightClick,toggleHide:this.handleToggleHide,columnDefs:this.state.columnDefs})}function adjustHeaders(a){var b=this.state.uniqueId;a>=0||(a=0);var c=0,d=$("#"+b+" .rt-headers-container"),e=parseInt(d.first().find(".rt-header-element").css("padding-left"));e+=parseInt(d.first().find(".rt-header-element").css("padding-right"));var f=!1;if(d.each(function(){var a=$(this),g=$("#"+b+" .rt-table tr:last td:eq("+c+")").outerWidth()-1;0==c&&1==parseInt(d.first().css("border-right"))&&(g+=1);var h=a.find(".rt-header-anchor-text").width()+e;a.width()>0&&h>a.width()+1&&(a.css("width",h+"px"),$("#"+b).find("tr").find("td:eq("+c+")").css("min-width",h+"px"),f=!0),g!==a.width()&&(a.width(g),f=!0),c++}),f){var g=d.find(".rt-downward-caret").removeClass("rt-downward-caret"),h=d.find(".rt-upward-caret").removeClass("rt-upward-caret");setTimeout(function(){g.addClass("rt-downward-caret"),h.addClass("rt-upward-caret")},0),5>=a&&adjustHeaders.call(this,++a)}}function bindHeadersToMenu(a){a.find(".rt-headers-container").each(function(){var a=this;$(a).hover(function(){var b=$(a).position();b.left&&$(a).find(".rt-header-menu").css("left",b.left+"px"),b.right&&$(a).find(".rt-header-menu").css("right",b.right+"px")})})}function uniqueId(a){var b=++idCounter+"";return a?a+b:b}function _isRowSelected(a,b,c,d){return null!=b?null!=c[a[b]]||!a.isDetail&&null!=d[generateSectorKey(a.sectorPath)]:void 0}function _getExtraStyle(a,b){return a&&b?b[a]:null}function _getPageArithmetics(a,b){var c={};if(a.props.disablePagination)c.lowerVisualBound=0,c.upperVisualBound=b.length;else{c.pageSize=a.props.pageSize||50,c.maxDisplayedPages=a.props.maxDisplayedPages||10,c.pageStart=1,c.pageEnd=Math.ceil(b.length/c.pageSize),c.allPages=[];for(var d=c.pageStart;d<=c.pageEnd;d++)c.allPages.push(d);c.pageDisplayRange=_computePageDisplayRange(a.state.currentPage,c.maxDisplayedPages),c.lowerVisualBound=(a.state.currentPage-1)*c.pageSize,c.upperVisualBound=Math.min(a.state.currentPage*c.pageSize-1,b.length)}return c}function _computePageDisplayRange(a,b){var c=b,d=Math.min(Math.floor(c/2),a-1),e=c-d;return{start:a-d-1,end:a+e-1}}function ReactTableGetInitialState(){var a=createTree(this.props),b=_getInitialSelections(this.props.selectedRows,this.props.selectedSummaryRows);return{rootNode:a,uniqueId:uniqueId("table"),currentPage:1,height:this.props.height,columnDefs:this.props.columnDefs,selectedDetailRows:b.selectedDetailRows,selectedSummaryRows:b.selectedSummaryRows,firstColumnLabel:_construct1StColumnLabel(this),extraStyle:{},rows:[],rowMultiplier:0,hasMoreRows:!1,itemsPerScroll:this.props.itemsPerScroll?this.props.itemsPerScroll:100}}function ReactTableHandleSelect(a){var b,c=this.props.rowKey;null!=c&&(null!=a.isDetail&1==a.isDetail?(b=this.toggleSelectDetailRow(a[c]),this.props.onSelectCallback(a,b)):(b=this.toggleSelectSummaryRow(generateSectorKey(a.sectorPath)),this.props.onSummarySelectCallback(a,b)))}function ReactTableHandleSort(a,b){var c=getSortFunction(a).bind(a),d=getReverseSortFunction(a).bind(a);this.state.rootNode.sortChildren({sortFn:c,reverseSortFn:d,recursive:!0,sortAsc:b}),this.setState({rootNode:this.state.rootNode,sortAsc:b,columnDefSorted:a})}function ReactTableHandleGroupBy(a,b){null!=b&&""!=b&&a&&(a.groupByRange=_createFloatBuckets(b)),null!=a?(this.props.groupBy=this.props.groupBy||[],this.props.groupBy.push(a)):this.props.groupBy=null;var c=createTree(this.props);this.setState({rootNode:c,currentPage:1,firstColumnLabel:_construct1StColumnLabel(this)})}function ReactTableHandleAdd(){this.props.beforeColumnAdd&&this.props.beforeColumnAdd(this)}function ReactTableHandleRemove(a){for(var b=this.state.columnDefs.indexOf(a),c=[],d=0;db[this.colTag]&&(c=1):c=-1:c=1,c}function genericValueBasedReverseSorter(a,b){var c=0;return a[this.colTag]||0===a[this.colTag]&&!this.formatConfig.showZeroAsBlank||!b[this.colTag]?!a[this.colTag]||b[this.colTag]||0===b[this.colTag]&&!this.formatConfig.showZeroAsBlank?a[this.colTag]b[this.colTag]&&(c=-1):c=-1:c=1,c}function dateDetailSort(a,b){var c=new Date(a[this.colTag])-new Date(b[this.colTag]);return c}function dateDetailReverseSort(a,b){var c=new Date(b[this.colTag])-new Date(a[this.colTag]);return c}function getSortFunction(a){var b=a.format||"";if(a.sort)return a.sort;switch(b.toLowerCase()){case"date":return dateDetailSort;default:return genericValueBasedSorter}}function getReverseSortFunction(a){var b=a.format||"";if(a.reverseSort)return a.reverseSort;if(a.sort)return function(b,c){return-1*a.sort.bind(this)(b,c)};if(!a.sort)switch(b.toLowerCase()){case"date":return dateDetailReverseSort;default:return genericValueBasedReverseSorter}}function createTree(a){if(null!=a.rootNode)return a.rootNode;var b=buildTreeSkeleton(a);return recursivelyAggregateNodes(b,a),b.sortRecursivelyBySortIndex(),b.foldSubTree(),b}function buildTreeSkeleton(a){var b,c=new TreeNode("Grand Total",null),d=a.data;for(a.disableGrandTotal&&(c.display=!1),b=0;b0)for(var c=0;c0?_rasterizeChildren(d,a):_rasterizeDetailRows(b,d)),d}function _rasterizeChildren(a,b){var c,d,e,f=b.node,g=b.firstColumn;for(c=0;c.8&&this.setState({rowMultiplier:this.state.rowMultiplier+1})},componentDidMount:function(){$(this.getDOMNode()).find(".rt-scrollable").get(0).addEventListener("scroll",this.handleScroll),setTimeout(function(){adjustHeaders.call(this)}.bind(this),0),setTimeout(function(){adjustHeaders.call(this)}.bind(this),500),document.addEventListener("click",adjustHeaders.bind(this)),window.addEventListener("resize",adjustHeaders.bind(this));var a=$(this.getDOMNode());a.find(".rt-scrollable").bind("scroll",function(){a.find(".rt-headers").css({overflow:"auto"}).scrollLeft($(this).scrollLeft()),a.find(".rt-headers").css({overflow:"hidden"})}),bindHeadersToMenu(a);var b=this;setTimeout(function(){b.redoPresort()})},componentWillUnmount:function(){window.removeEventListener("resize",adjustHeaders.bind(this)),$(this.getDOMNode()).find(".rt-scrollable").get(0).removeEventListener("scroll",this.handleScroll)},componentDidUpdate:function(){adjustHeaders.call(this),bindHeadersToMenu($(this.getDOMNode()))},addMoreRows:function(){var a=rasterizeTree({node:this.state.rootNode,firstColumn:this.state.columnDefs[0],selectedDetailRows:this.state.selectedDetailRows}),b=(this.state.rowMultiplier+1)*this.state.itemsPerScroll,c=[];if(this.state.rows.length0&&(f.height=this.state.height),this.props.disableScrolling&&(f.overflowY="hidden"),React.DOM.div({id:this.state.uniqueId,className:"rt-table-container"},d,React.DOM.div({style:f,className:"rt-scrollable"},InfiniteScroll({loadMore:this.addMoreRows,hasMore:this.state.hasMore},React.DOM.table({className:"rt-table"},React.DOM.tbody(null,this.state.rows)))),this.props.disableInfiniteScrolling?e:null)}}),Row=React.createClass({displayName:"Row",render:function(){for(var a=[buildFirstCellForRow(this.props)],b=1;b=1&&this.props.handleClick(a)},render:function(){var a=this,b=React.addons.classSet,c=b({disabled:1==this.props.activeItem}),d=b({disabled:this.props.activeItem==this.props.numPages}),e=this.props.items.map(function(b){return React.DOM.li({key:b,className:a.props.activeItem==b?"active":""},React.DOM.a({onClick:a.handleClick.bind(null,b)},b))});return React.DOM.ul({className:c,className:"pagination pull-right"},React.DOM.li({className:d},React.DOM.a({className:c,onClick:this.props.handleClick.bind(null,this.props.activeItem-1)},"«")),e,React.DOM.li({className:d},React.DOM.a({className:d,onClick:this.props.handleClick.bind(null,this.props.activeItem+1)},"»")))}}),SummarizeControl=React.createClass({displayName:"SummarizeControl",getInitialState:function(){return{userInputBuckets:""}},handleChange:function(a){this.setState({userInputBuckets:a.target.value})},handleKeyPress:function(a){13==a.charCode&&(a.preventDefault(),this.props.table.handleGroupBy(this.props.columnDef,this.state.userInputBuckets))},handleClick:function(){var a=$(this.getDOMNode());a.children(".menu-item-input").children("input").focus()},render:function(){var a=this.props.table,b=this.props.columnDef,c="number"==b.format||"currency"==b.format?React.DOM.div({className:"menu-item-input",style:{position:"absolute",top:"-50%",right:"100%"}},React.DOM.label({style:{display:"block"}},"Enter Bucket(s)"),React.DOM.input({tabIndex:"1",onKeyPress:this.handleKeyPress,onChange:this.handleChange,placeholder:"ex: 1,10,15"}),React.DOM.a({tabIndex:"2",style:{display:"block"},onClick:a.handleGroupBy.bind(null,b,this.state.userInputBuckets),className:"btn-link"},"Ok")):null;return React.DOM.div({onClick:null==c?a.handleGroupBy.bind(null,b,null):this.handleClick,style:{position:"relative"},className:"menu-item menu-item-hoverable"},React.DOM.div(null,"Summarize"),c)}});TreeNode.prototype.appendUltimateChild=function(a){this.ultimateChildren.push(a)},TreeNode.prototype.collapseImmediateChildren=function(){for(var a=0;a0},TreeNode.prototype.expandRecursively=function(){var a;for(a=0;a5?"right":"left",h={};for(var i in d)h[i]=d[i];h[g]="100%",c.push(React.DOM.div({style:{position:"relative"},className:"menu-item menu-item-hoverable"},React.DOM.div(null,e),React.DOM.div({className:"menu-item-input",style:h},React.DOM.div({style:{display:"block"}},b[a.props.customMenuItems[e][f]]))))}return c}function buildMenu(a){var b=a.table,c=a.columnDef,d=a.style,e=a.isFirstColumn,f={};"right"==d.textAlign?f.right="0%":f.left="0%";var g=[],h={sort:[React.DOM.div({className:"menu-item",onClick:b.handleSort.bind(null,c,!0)},"Sort Asc"),React.DOM.div({className:"menu-item",onClick:b.handleSort.bind(null,c,!1)},"Sort Dsc")],summarize:[SummarizeControl({table:b,columnDef:c}),React.DOM.div({className:"menu-item",onClick:b.handleGroupBy.bind(null,null)},"Clear Summary")],remove:[React.DOM.div({className:"menu-item",onClick:b.handleRemove.bind(null,c)},"Remove Column")]};if(b.props.defaultMenuItems)for(var i=0;i0&&!a.props.disablePagination?PageNavigator({items:b.allPages.slice(b.pageDisplayRange.start,b.pageDisplayRange.end),activeItem:a.state.currentPage,numPages:b.pageEnd,handleClick:a.handlePageClick}):null}function getSectorName(a,b){var c="",d=null;if("number"==b.format||"currency"==b.format){var e=_resolveNumericSectorName(b,a);c=e.sectorName,d=e.sortIndex}else c=a[b.colTag];return{sectorName:c||"Other",sortIndex:d}}function aggregateSector(a,b,c){for(var d={},e=1;eb.count||d===b.count&&a.data[c].aggregationTiebreaker>a.data[b.index].aggregationTiebreaker)&&(b.count=d,b.index=c)}return-1==b.index?"":a.data[b.index][a.columnDef.colTag]}function exportToExcel(a){var b="";$.each(a.headers,function(a,c){b+=""}),b+="";var c=1;$.each(a.data,function(a,d){if(d.length>0&&d[0].match("Grand Total"))return void c++;b+="";var e=0;$.each(d,function(a,c){b+="",e++}),c++,b+=""}),b+="
"+parseString(c)+"
"+parseString(c)+"
";var d="";d+="",d+="",d+="",d+="",d+=b,d+="",d+="";var e=window.navigator.userAgent,f=e.indexOf("MSIE ");if(f>0||navigator.userAgent.match(/Trident.*rv\:11\./)){var g=$("").css("display","none").attr("id","ieExcelFrame").appendTo("body");ieExcelFrame.document.open("txt/html","replace"),ieExcelFrame.document.write(d),ieExcelFrame.document.close(),ieExcelFrame.focus(),ieExcelFrame.document.execCommand("SaveAs",!0,"exportData.xls"),g.remove()}else{var h="base64,"+$.base64.encode(d);window.open("data:application/vnd.ms-excel;filename=exportData.doc;"+h)}}function exportToPDF(a){var b={separator:",",ignoreColumn:[],tableName:"yourTableName",pdfFontSize:6,pdfLeftMargin:20},c=new jsPDF("l","pt","letter",!0),d=[],e=b.pdfLeftMargin;$.each(a.headers,function(a,b){var c=4.5*parseString(b).length;(!d[a]||d[a]0&&b[0].match("Grand Total")||$.each(b,function(a,b){var c=4.5*parseString(b).length;(!d[a]||d[a]752){var g=752/f;c.setFontSize(g*b.pdfFontSize);for(var h=0;hd?b+c:b},e);c.text(f,20,parseString(b))});var i=20,j=1,k=0,l=1;$.each(a.data,function(a,b){b.length>0&&b[0].match("Grand Total")||(l++,l%50==0&&(c.addPage(),j++,l=1),k=i+10*l,$.each(b,function(a,b){var f=d.reduce(function(b,c,d){return a>d?b+c:b},e);c.text(f,k,parseString(b))}))}),c.output("save","AMI-table.pdf")}function parseString(a){if("string"!=typeof a){if(!a||!a.toString)return"";a=a.toString()}var b=a.trim();return b=b.replace(/[^\x00-\x7F]/g,""),b=b.substr(0,20)}function topPosition(a){return a?a.offsetTop+topPosition(a.offsetParent):0}function generateSectorKey(a){return null==a?"":a.join(SECTOR_SEPARATOR)}function generateRowKey(a,b){var c;return c=a.isDetail?b?a[b]:a.rowCount:generateSectorKey(a.sectorPath)}function rowMapper(a){var b=this.props.rowKey,c=generateRowKey(a,b);return Row({key:c,data:a,extraStyle:_getExtraStyle(c,this.state.extraStyle),isSelected:_isRowSelected(a,this.props.rowKey,this.state.selectedDetailRows,this.state.selectedSummaryRows),onSelect:this.handleSelect,onRightClick:this.props.onRightClick,toggleHide:this.handleToggleHide,columnDefs:this.state.columnDefs})}function adjustHeaders(a){var b=this.state.uniqueId;a>=0||(a=0);var c=0,d=$("#"+b+" .rt-headers-container"),e=parseInt(d.first().find(".rt-header-element").css("padding-left"));e+=parseInt(d.first().find(".rt-header-element").css("padding-right"));var f=!1;if(d.each(function(){var a=$(this),g=$("#"+b+" .rt-table tr:last td:eq("+c+")").outerWidth()-1;0==c&&1==parseInt(d.first().css("border-right"))&&(g+=1);var h=a.find(".rt-header-anchor-text").width()+e;a.width()>0&&h>a.width()+1&&(a.css("width",h+"px"),$("#"+b).find("tr").find("td:eq("+c+")").css("min-width",h+"px"),f=!0),g!==a.width()&&(a.width(g),f=!0),c++}),f){var g=d.find(".rt-downward-caret").removeClass("rt-downward-caret"),h=d.find(".rt-upward-caret").removeClass("rt-upward-caret");setTimeout(function(){g.addClass("rt-downward-caret"),h.addClass("rt-upward-caret")},0),5>=a&&adjustHeaders.call(this,++a)}}function bindHeadersToMenu(a){a.find(".rt-headers-container").each(function(){var a=this;$(a).hover(function(){var b=$(a).position();b.left&&$(a).find(".rt-header-menu").css("left",b.left+"px"),b.right&&$(a).find(".rt-header-menu").css("right",b.right+"px")})})}function uniqueId(a){var b=++idCounter+"";return a?a+b:b}function _isRowSelected(a,b,c,d){return null!=b?null!=c[a[b]]||!a.isDetail&&null!=d[generateSectorKey(a.sectorPath)]:void 0}function _getExtraStyle(a,b){return a&&b?b[a]:null}function _getPageArithmetics(a,b){var c={};if(a.props.disablePagination)c.lowerVisualBound=0,c.upperVisualBound=b.length;else{c.pageSize=a.props.pageSize||50,c.maxDisplayedPages=a.props.maxDisplayedPages||10,c.pageStart=1,c.pageEnd=Math.ceil(b.length/c.pageSize),c.allPages=[];for(var d=c.pageStart;d<=c.pageEnd;d++)c.allPages.push(d);c.pageDisplayRange=_computePageDisplayRange(a.state.currentPage,c.maxDisplayedPages),c.lowerVisualBound=(a.state.currentPage-1)*c.pageSize,c.upperVisualBound=Math.min(a.state.currentPage*c.pageSize-1,b.length)}return c}function _computePageDisplayRange(a,b){var c=b,d=Math.min(Math.floor(c/2),a-1),e=c-d;return{start:a-d-1,end:a+e-1}}function ReactTableGetInitialState(){var a=createTree(this.props),b=_getInitialSelections(this.props.selectedRows,this.props.selectedSummaryRows);return{rootNode:a,uniqueId:uniqueId("table"),currentPage:1,height:this.props.height,columnDefs:this.props.columnDefs,selectedDetailRows:b.selectedDetailRows,selectedSummaryRows:b.selectedSummaryRows,firstColumnLabel:_construct1StColumnLabel(this),extraStyle:{},rows:[],hasMoreRows:!1,itemsPerScroll:this.props.itemsPerScroll?this.props.itemsPerScroll:100}}function ReactTableHandleSelect(a){var b,c=this.props.rowKey;null!=c&&(null!=a.isDetail&1==a.isDetail?(b=this.toggleSelectDetailRow(a[c]),this.props.onSelectCallback(a,b)):(b=this.toggleSelectSummaryRow(generateSectorKey(a.sectorPath)),this.props.onSummarySelectCallback(a,b)))}function ReactTableHandleSort(a,b){var c=getSortFunction(a).bind(a),d=getReverseSortFunction(a).bind(a);this.state.rootNode.sortChildren({sortFn:c,reverseSortFn:d,recursive:!0,sortAsc:b}),this.setState({rootNode:this.state.rootNode,sortAsc:b,columnDefSorted:a})}function ReactTableHandleGroupBy(a,b){null!=b&&""!=b&&a&&(a.groupByRange=_createFloatBuckets(b)),null!=a?(this.props.groupBy=this.props.groupBy||[],this.props.groupBy.push(a)):this.props.groupBy=null;var c=createTree(this.props);this.setState({rootNode:c,currentPage:1,firstColumnLabel:_construct1StColumnLabel(this)})}function ReactTableHandleAdd(){this.props.beforeColumnAdd&&this.props.beforeColumnAdd(this)}function ReactTableHandleRemove(a){for(var b=this.state.columnDefs.indexOf(a),c=[],d=0;db[this.colTag]&&(c=1):c=-1:c=1,c}function genericValueBasedReverseSorter(a,b){var c=0;return a[this.colTag]||0===a[this.colTag]&&!this.formatConfig.showZeroAsBlank||!b[this.colTag]?!a[this.colTag]||b[this.colTag]||0===b[this.colTag]&&!this.formatConfig.showZeroAsBlank?a[this.colTag]b[this.colTag]&&(c=-1):c=-1:c=1,c}function dateDetailSort(a,b){var c=new Date(a[this.colTag])-new Date(b[this.colTag]);return c}function dateDetailReverseSort(a,b){var c=new Date(b[this.colTag])-new Date(a[this.colTag]);return c}function getSortFunction(a){var b=a.format||"";if(a.sort)return a.sort;switch(b.toLowerCase()){case"date":return dateDetailSort;default:return genericValueBasedSorter}}function getReverseSortFunction(a){var b=a.format||"";if(a.reverseSort)return a.reverseSort;if(a.sort)return function(b,c){return-1*a.sort.bind(this)(b,c)};if(!a.sort)switch(b.toLowerCase()){case"date":return dateDetailReverseSort;default:return genericValueBasedReverseSorter}}function createTree(a){if(null!=a.rootNode)return a.rootNode;var b=buildTreeSkeleton(a);return recursivelyAggregateNodes(b,a),b.sortRecursivelyBySortIndex(),b.foldSubTree(),b}function buildTreeSkeleton(a){var b,c=new TreeNode("Grand Total",null),d=a.data;for(a.disableGrandTotal&&(c.display=!1),b=0;b0)for(var c=0;c0?_rasterizeChildren(d,a):_rasterizeDetailRows(b,d)),d}function _rasterizeChildren(a,b){var c,d,e,f=b.node,g=b.firstColumn;for(c=0;c.8&&this.setState({rows:this.addMoreRows(!0)})},componentDidMount:function(){$(this.getDOMNode()).find(".rt-scrollable").get(0).addEventListener("scroll",this.handleScroll),setTimeout(function(){adjustHeaders.call(this)}.bind(this),0),setTimeout(function(){adjustHeaders.call(this)}.bind(this),500),document.addEventListener("click",adjustHeaders.bind(this)),window.addEventListener("resize",adjustHeaders.bind(this));var a=$(this.getDOMNode());a.find(".rt-scrollable").bind("scroll",function(){a.find(".rt-headers").css({overflow:"auto"}).scrollLeft($(this).scrollLeft()),a.find(".rt-headers").css({overflow:"hidden"})}),bindHeadersToMenu(a);var b=this;setTimeout(function(){b.redoPresort()})},componentWillUnmount:function(){window.removeEventListener("resize",adjustHeaders.bind(this)),$(this.getDOMNode()).find(".rt-scrollable").get(0).removeEventListener("scroll",this.handleScroll)},componentDidUpdate:function(){adjustHeaders.call(this),bindHeadersToMenu($(this.getDOMNode()))},addMoreRows:function(a){if(this.props.justAdded)return console.log("just added"),this.props.justAdded=!1,this.state.rows;console.log("rasterizing");var b=rasterizeTree({node:this.state.rootNode,firstColumn:this.state.columnDefs[0],selectedDetailRows:this.state.selectedDetailRows});this.props.rowMultiplier=a?void 0===this.props.rowMultiplier?0:this.props.rowMultiplier+1:this.props.rowMultiplier?this.props.rowMultiplier:0;var c=(this.props.rowMultiplier+1)*this.state.itemsPerScroll,d=[];if(a&&this.state.rows.length0&&(f.height=this.state.height),this.props.disableScrolling&&(f.overflowY="hidden"),React.DOM.div({id:this.state.uniqueId,className:"rt-table-container"},d,React.DOM.div({style:f,className:"rt-scrollable"},InfiniteScroll({loadMore:this.addMoreRows,hasMore:this.state.hasMore},React.DOM.table({className:"rt-table"},React.DOM.tbody(null,this.state.rows)))),this.props.disableInfiniteScrolling?e:null)}}),Row=React.createClass({displayName:"Row",render:function(){for(var a=[buildFirstCellForRow(this.props)],b=1;b=1&&this.props.handleClick(a)},render:function(){var a=this,b=React.addons.classSet,c=b({disabled:1==this.props.activeItem}),d=b({disabled:this.props.activeItem==this.props.numPages}),e=this.props.items.map(function(b){return React.DOM.li({key:b,className:a.props.activeItem==b?"active":""},React.DOM.a({onClick:a.handleClick.bind(null,b)},b))});return React.DOM.ul({className:c,className:"pagination pull-right"},React.DOM.li({className:d},React.DOM.a({className:c,onClick:this.props.handleClick.bind(null,this.props.activeItem-1)},"«")),e,React.DOM.li({className:d},React.DOM.a({className:d,onClick:this.props.handleClick.bind(null,this.props.activeItem+1)},"»")))}}),SummarizeControl=React.createClass({displayName:"SummarizeControl",getInitialState:function(){return{userInputBuckets:""}},handleChange:function(a){this.setState({userInputBuckets:a.target.value})},handleKeyPress:function(a){13==a.charCode&&(a.preventDefault(),this.props.table.handleGroupBy(this.props.columnDef,this.state.userInputBuckets))},handleClick:function(){var a=$(this.getDOMNode());a.children(".menu-item-input").children("input").focus()},render:function(){var a=this.props.table,b=this.props.columnDef,c="number"==b.format||"currency"==b.format?React.DOM.div({className:"menu-item-input",style:{position:"absolute",top:"-50%",right:"100%"}},React.DOM.label({style:{display:"block"}},"Enter Bucket(s)"),React.DOM.input({tabIndex:"1",onKeyPress:this.handleKeyPress,onChange:this.handleChange,placeholder:"ex: 1,10,15"}),React.DOM.a({tabIndex:"2",style:{display:"block"},onClick:a.handleGroupBy.bind(null,b,this.state.userInputBuckets),className:"btn-link"},"Ok")):null;return React.DOM.div({onClick:null==c?a.handleGroupBy.bind(null,b,null):this.handleClick,style:{position:"relative"},className:"menu-item menu-item-hoverable"},React.DOM.div(null,"Summarize"),c)}});TreeNode.prototype.appendUltimateChild=function(a){this.ultimateChildren.push(a)},TreeNode.prototype.collapseImmediateChildren=function(){for(var a=0;a0},TreeNode.prototype.expandRecursively=function(){var a;for(a=0;a--> - + diff --git a/examples/exporting_demo.js b/examples/exporting_demo.js index 6038cf5..33d35b9 100644 --- a/examples/exporting_demo.js +++ b/examples/exporting_demo.js @@ -60,6 +60,7 @@ $(function () { //groupBy: groupBy, //disableInfiniteScrolling: true, //itemsPerScroll: 500, + pageSize: 1000, rowKey: 'id', customMenuItems: { Definition: { diff --git a/src/ReactTable.js b/src/ReactTable.js index 364f5b5..dc7f51e 100644 --- a/src/ReactTable.js +++ b/src/ReactTable.js @@ -173,7 +173,7 @@ var ReactTable = React.createClass({ var totalHeight = target.find("tbody").height(); if( scrolled / (totalHeight-scrolledHeight) > .8 ){ this.setState({ - rowMultiplier: this.state.rowMultiplier + 1 + rows: this.addMoreRows(true) }); } }, @@ -208,25 +208,36 @@ var ReactTable = React.createClass({ adjustHeaders.call(this); bindHeadersToMenu($(this.getDOMNode())); }, - addMoreRows: function(){ + addMoreRows: function(calledFromScroll){ + if( this.props.justAdded ){ + console.log("just added"); + this.props.justAdded = false; + return this.state.rows; + } + console.log("rasterizing"); var rasterizedData = rasterizeTree({ node: this.state.rootNode, firstColumn: this.state.columnDefs[0], selectedDetailRows: this.state.selectedDetailRows }); + if( !calledFromScroll ) + this.props.rowMultiplier = this.props.rowMultiplier ? this.props.rowMultiplier : 0; + else + this.props.rowMultiplier = (this.props.rowMultiplier === undefined ? 0 : this.props.rowMultiplier + 1); - var upperBound = (this.state.rowMultiplier + 1) * this.state.itemsPerScroll; + var upperBound = (this.props.rowMultiplier + 1) * this.state.itemsPerScroll; var rowsToDisplay = []; - if( this.state.rows.length < upperBound && this.state.rows.length < rasterizedData.length ) { - var lowerBound = this.state.rowMultiplier * this.state.itemsPerScroll; + if( calledFromScroll && this.state.rows.length < upperBound && this.state.rows.length < rasterizedData.length ) { + var lowerBound = this.state.rows.length; rowsToDisplay = rasterizedData.slice(lowerBound, upperBound); - this.state.rows = this.state.rows.concat(rowsToDisplay.map(rowMapper, this)); + this.props.justAdded = true; + return this.state.rows.concat(rowsToDisplay.map(rowMapper, this)) } else { rowsToDisplay = rasterizedData.slice(0, upperBound); - this.state.rows = rowsToDisplay.map(rowMapper, this); + return rowsToDisplay.map(rowMapper, this) } }, render: function () { @@ -244,7 +255,7 @@ var ReactTable = React.createClass({ this.state.rows = rowsToDisplay.map(rowMapper, this); } else{ - this.addMoreRows(); + this.state.rows = this.addMoreRows(); } var headers = buildHeaders(this); diff --git a/src/ReactTableEventHandlers.js b/src/ReactTableEventHandlers.js index e8fc04a..df03909 100644 --- a/src/ReactTableEventHandlers.js +++ b/src/ReactTableEventHandlers.js @@ -13,7 +13,6 @@ function ReactTableGetInitialState() { firstColumnLabel: _construct1StColumnLabel(this), extraStyle: {}, rows: [], - rowMultiplier: 0, hasMoreRows: false, itemsPerScroll: this.props.itemsPerScroll ? this.props.itemsPerScroll : 100 };