Skip to content
This repository was archived by the owner on Feb 20, 2020. It is now read-only.

Commit 0a26dd1

Browse files
garytang8wcjordan
authored andcommitted
Added support to fix columns to the right side of the table. (schrodinger#250)
* Added support to fix columns to right side of table. * Added new `fixedRight` prop type to `FixedDataTableColumn`
1 parent eab8246 commit 0a26dd1

File tree

7 files changed

+166
-2
lines changed

7 files changed

+166
-2
lines changed

examples/FixedRightColumnsExample.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Copyright Schrodinger, LLC
3+
*/
4+
5+
"use strict";
6+
7+
const FakeObjectDataListStore = require('./helpers/FakeObjectDataListStore');
8+
const { DateCell, ImageCell, LinkCell, TextCell } = require('./helpers/cells');
9+
const { Table, Column, Cell } = require('fixed-data-table-2');
10+
const React = require('react');
11+
12+
class FixedRightColumnsExample extends React.Component {
13+
constructor(props) {
14+
super(props);
15+
16+
this.state = {
17+
dataList: new FakeObjectDataListStore(1000000),
18+
};
19+
}
20+
21+
render() {
22+
var {dataList} = this.state;
23+
return (
24+
<Table
25+
rowHeight={50}
26+
headerHeight={50}
27+
rowsCount={dataList.getSize()}
28+
width={1000}
29+
height={500}
30+
{...this.props}>
31+
<Column
32+
columnKey="avatar"
33+
cell={<ImageCell data={dataList} />}
34+
fixed={true}
35+
width={50}
36+
/>
37+
<Column
38+
columnKey="firstName"
39+
header={<Cell>First Name</Cell>}
40+
cell={<LinkCell data={dataList} />}
41+
fixedRight={true}
42+
width={100}
43+
/>
44+
<Column
45+
columnKey="lastName"
46+
header={<Cell>Last Name</Cell>}
47+
cell={<TextCell data={dataList} />}
48+
fixedRight={true}
49+
width={100}
50+
/>
51+
<Column
52+
columnKey="city"
53+
header={<Cell>City</Cell>}
54+
cell={<TextCell data={dataList} />}
55+
width={100}
56+
/>
57+
<Column
58+
columnKey="street"
59+
header={<Cell>Street</Cell>}
60+
cell={<TextCell data={dataList} />}
61+
width={200}
62+
/>
63+
<Column
64+
columnKey="zipCode"
65+
header={<Cell>Zip Code</Cell>}
66+
cell={<TextCell data={dataList} />}
67+
width={200}
68+
/>
69+
<Column
70+
columnKey="email"
71+
header={<Cell>Email</Cell>}
72+
cell={<LinkCell data={dataList} />}
73+
width={200}
74+
/>
75+
<Column
76+
columnKey="date"
77+
header={<Cell>DOB</Cell>}
78+
cell={<DateCell data={dataList} />}
79+
width={200}
80+
/>
81+
</Table>
82+
);
83+
}
84+
}
85+
86+
module.exports = FixedRightColumnsExample;

site/Constants.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ exports.ExamplePages = {
3636
title: 'With JSON Data',
3737
description: 'A basic table example with two fixed columns, fed in some JSON data.',
3838
},
39+
FIXED_RIGHT_COLUMNS_EXAMPLE: {
40+
location: 'fixed-right-columns.html',
41+
fileName: 'FixedRightColumnsExample.js',
42+
title: 'Fixed Right Columns',
43+
description: 'A table example that has a columns fixed to the right side of the table.',
44+
},
3945
FLEXGROW_EXAMPLE: {
4046
location: 'example-flexgrow.html',
4147
fileName: 'FlexGrowExample.js',

site/examples/ExamplesPage.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ var EXAMPLE_COMPONENTS = {
4545
[ExamplePages.TOOLTIP_EXAMPLE.location]: require('../../examples/TooltipExample'),
4646
[ExamplePages.LONG_CLICK_EXAMPLE.location]: require('../../examples/LongClickExample'),
4747
[ExamplePages.CONTEXT_EXAMPLE.location]: require('../../examples/ContextExample'),
48+
[ExamplePages.FIXED_RIGHT_COLUMNS_EXAMPLE.location]: require('../../examples/FixedRightColumnsExample'),
4849
};
4950

5051
class ExamplesPage extends React.Component {

src/FixedDataTable.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ var FixedDataTable = createReactClass({
571571
offsetTop={0}
572572
scrollLeft={state.scrollX}
573573
fixedColumns={state.groupHeaderFixedColumns}
574+
fixedRightColumns={state.groupHeaderFixedRightColumns}
574575
scrollableColumns={state.groupHeaderScrollableColumns}
575576
onColumnResize={this._onColumnResize}
576577
onColumnReorder={onColumnReorder}
@@ -662,6 +663,7 @@ var FixedDataTable = createReactClass({
662663
zIndex={1}
663664
offsetTop={footOffsetTop}
664665
fixedColumns={state.footFixedColumns}
666+
fixedRightColumns={state.footFixedRightColumns}
665667
scrollableColumns={state.footScrollableColumns}
666668
scrollLeft={state.scrollX}
667669
/>;
@@ -685,6 +687,7 @@ var FixedDataTable = createReactClass({
685687
offsetTop={headerOffsetTop}
686688
scrollLeft={state.scrollX}
687689
fixedColumns={state.headFixedColumns}
690+
fixedRightColumns={state.headFixedRightColumns}
688691
scrollableColumns={state.headScrollableColumns}
689692
touchEnabled={state.touchScrollEnabled}
690693
onColumnResize={this._onColumnResize}
@@ -764,6 +767,7 @@ var FixedDataTable = createReactClass({
764767
firstRowIndex={state.firstRowIndex}
765768
firstRowOffset={state.firstRowOffset}
766769
fixedColumns={state.bodyFixedColumns}
770+
fixedRightColumns={state.bodyFixedRightColumns}
767771
height={state.bodyHeight}
768772
offsetTop={offsetTop}
769773
onRowClick={state.onRowClick}
@@ -957,31 +961,38 @@ var FixedDataTable = createReactClass({
957961
var columnInfo = {};
958962
if (canReuseColumnSettings) {
959963
columnInfo.bodyFixedColumns = oldState.bodyFixedColumns;
964+
columnInfo.bodyFixedRightColumns = oldState.bodyFixedRightColumns;
960965
columnInfo.bodyScrollableColumns = oldState.bodyScrollableColumns;
961966
columnInfo.headFixedColumns = oldState.headFixedColumns;
967+
columnInfo.headFixedRightColumns = oldState.headFixedRightColumns;
962968
columnInfo.headScrollableColumns = oldState.headScrollableColumns;
963969
columnInfo.footFixedColumns = oldState.footFixedColumns;
970+
columnInfo.footFixedRightColumns = oldState.footFixedRightColumns;
964971
columnInfo.footScrollableColumns = oldState.footScrollableColumns;
965972
} else {
966973
var bodyColumnTypes = this._splitColumnTypes(columns);
967974
columnInfo.bodyFixedColumns = bodyColumnTypes.fixed;
975+
columnInfo.bodyFixedRightColumns = bodyColumnTypes.fixedRight;
968976
columnInfo.bodyScrollableColumns = bodyColumnTypes.scrollable;
969977

970978
var headColumnTypes = this._splitColumnTypes(
971979
this._selectColumnElement(HEADER, columns)
972980
);
973981
columnInfo.headFixedColumns = headColumnTypes.fixed;
982+
columnInfo.headFixedRightColumns = headColumnTypes.fixedRight;
974983
columnInfo.headScrollableColumns = headColumnTypes.scrollable;
975984

976985
var footColumnTypes = this._splitColumnTypes(
977986
this._selectColumnElement(FOOTER, columns)
978987
);
979988
columnInfo.footFixedColumns = footColumnTypes.fixed;
989+
columnInfo.footFixedRightColumns = footColumnTypes.fixedRight;
980990
columnInfo.footScrollableColumns = footColumnTypes.scrollable;
981991
}
982992

983993
if (canReuseColumnGroupSettings) {
984994
columnInfo.groupHeaderFixedColumns = oldState.groupHeaderFixedColumns;
995+
columnInfo.groupHeaderFixedRightColumns = oldState.groupHeaderFixedRightColumns;
985996
columnInfo.groupHeaderScrollableColumns =
986997
oldState.groupHeaderScrollableColumns;
987998
} else {
@@ -990,6 +1001,7 @@ var FixedDataTable = createReactClass({
9901001
this._selectColumnElement(HEADER, columnGroups)
9911002
);
9921003
columnInfo.groupHeaderFixedColumns = groupHeaderColumnTypes.fixed;
1004+
columnInfo.groupHeaderFixedRightColumns = groupHeaderColumnTypes.fixedRight;
9931005
columnInfo.groupHeaderScrollableColumns =
9941006
groupHeaderColumnTypes.scrollable;
9951007
}
@@ -1285,16 +1297,20 @@ var FixedDataTable = createReactClass({
12851297

12861298
_splitColumnTypes(/*array*/ columns) /*object*/ {
12871299
var fixedColumns = [];
1300+
var fixedRightColumns = [];
12881301
var scrollableColumns = [];
12891302
for (var i = 0; i < columns.length; ++i) {
12901303
if (columns[i].props.fixed) {
12911304
fixedColumns.push(columns[i]);
1305+
} else if (columns[i].props.fixedRight) {
1306+
fixedRightColumns.push(columns[i]);
12921307
} else {
12931308
scrollableColumns.push(columns[i]);
12941309
}
12951310
}
12961311
return {
12971312
fixed: fixedColumns,
1313+
fixedRight: fixedRightColumns,
12981314
scrollable: scrollableColumns,
12991315
};
13001316
},

src/FixedDataTableBufferedRows.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ var FixedDataTableBufferedRows = createReactClass({
3030
firstRowIndex: PropTypes.number.isRequired,
3131
firstRowOffset: PropTypes.number.isRequired,
3232
fixedColumns: PropTypes.array.isRequired,
33+
fixedRightColumns: PropTypes.array.isRequired,
3334
height: PropTypes.number.isRequired,
3435
offsetTop: PropTypes.number.isRequired,
3536
onRowClick: PropTypes.func,
@@ -170,6 +171,7 @@ var FixedDataTableBufferedRows = createReactClass({
170171
scrollLeft={Math.round(props.scrollLeft)}
171172
offsetTop={Math.round(rowOffsetTop)}
172173
fixedColumns={props.fixedColumns}
174+
fixedRightColumns={props.fixedRightColumns}
173175
scrollableColumns={props.scrollableColumns}
174176
onClick={props.onRowClick}
175177
onDoubleClick={props.onRowDoubleClick}

src/FixedDataTableColumn.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ class FixedDataTableColumn extends React.Component {
3131
*/
3232
fixed: PropTypes.bool,
3333

34+
/**
35+
* Controls if the column is fixed to the right side of the table when scrolling in the X axis.
36+
*/
37+
fixedRight: PropTypes.bool,
38+
3439
/**
3540
* The header cell for this column.
3641
* This can either be a string a React element, or a function that generates
@@ -181,6 +186,7 @@ class FixedDataTableColumn extends React.Component {
181186
static defaultProps = {
182187
allowCellsRecycling: false,
183188
fixed: false,
189+
fixedRight: false,
184190
};
185191

186192
render() {

src/FixedDataTableRow.js

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ class FixedDataTableRowImpl extends React.Component {
4444
*/
4545
fixedColumns: PropTypes.array.isRequired,
4646

47+
/**
48+
* Array of <FixedDataTableColumn /> for the fixed columns positioned at end of the table.
49+
*/
50+
fixedRightColumns: PropTypes.array.isRequired,
51+
4752
/**
4853
* Height of the row.
4954
*/
@@ -172,15 +177,39 @@ class FixedDataTableRowImpl extends React.Component {
172177
rowIndex={this.props.index}
173178
/>;
174179
var columnsLeftShadow = this._renderColumnsLeftShadow(fixedColumnsWidth);
180+
var fixedRightColumnsWidth = this._getColumnsWidth(this.props.fixedRightColumns);
181+
var fixedRightColumns =
182+
<FixedDataTableCellGroup
183+
key="fixed_right_cells"
184+
isScrolling={this.props.isScrolling}
185+
height={this.props.height}
186+
cellGroupWrapperHeight={this.props.cellGroupWrapperHeight}
187+
left={-this.props.width + fixedRightColumnsWidth}
188+
width={fixedRightColumnsWidth}
189+
zIndex={2}
190+
columns={this.props.fixedRightColumns}
191+
touchEnabled={this.props.touchEnabled}
192+
onColumnResize={this.props.onColumnResize}
193+
onColumnReorder={this.props.onColumnReorder}
194+
onColumnReorderMove={this.props.onColumnReorderMove}
195+
onColumnReorderEnd={this.props.onColumnReorderEnd}
196+
isColumnReordering={this.props.isColumnReordering}
197+
columnReorderingData={this.props.columnReorderingData}
198+
rowHeight={this.props.height}
199+
rowIndex={this.props.index}
200+
/>;
201+
var fixedRightColumnsShdadow = fixedRightColumnsWidth ?
202+
this._renderFixedRightColumnsShadow(this.props.width - fixedRightColumnsWidth - 5) : null;
175203
var scrollableColumns =
176204
<FixedDataTableCellGroup
177205
key="scrollable_cells"
178206
isScrolling={this.props.isScrolling}
179207
height={this.props.height}
180208
cellGroupWrapperHeight={this.props.cellGroupWrapperHeight}
209+
align="right"
181210
left={this.props.scrollLeft}
182211
offsetLeft={fixedColumnsWidth}
183-
width={this.props.width - fixedColumnsWidth}
212+
width={this.props.width - fixedColumnsWidth - fixedRightColumnsWidth}
184213
zIndex={0}
185214
columns={this.props.scrollableColumns}
186215
touchEnabled={this.props.touchEnabled}
@@ -219,6 +248,8 @@ class FixedDataTableRowImpl extends React.Component {
219248
{fixedColumns}
220249
{scrollableColumns}
221250
{columnsLeftShadow}
251+
{fixedRightColumns}
252+
{fixedRightColumnsShdadow}
222253
</div>
223254
{rowExpanded && <div
224255
className={cx('fixedDataTableRowLayout/rowExpanded')}
@@ -271,7 +302,23 @@ class FixedDataTableRowImpl extends React.Component {
271302
height: dividerHeight
272303
};
273304
return <div className={className} style={style} />;
274-
};
305+
};
306+
307+
_renderFixedRightColumnsShadow = (/*number*/ left) => /*?object*/ {
308+
var className = cx(
309+
'fixedDataTableRowLayout/columnsShadow',
310+
'fixedDataTableRowLayout/columnsRightShadow',
311+
'fixedDataTableRowLayout/fixedColumnsDivider',
312+
'public/fixedDataTableRow/columnsShadow',
313+
'public/fixedDataTableRow/columnsRightShadow',
314+
'public/fixedDataTableRow/fixedColumnsDivider'
315+
);
316+
var style = {
317+
height: this.props.height,
318+
left: left
319+
};
320+
return <div className={className} style={style} />;
321+
};
275322

276323
_renderColumnsRightShadow = (/*number*/ totalWidth) => /*?object*/ {
277324
if (Math.ceil(this.props.scrollLeft + this.props.width) < Math.floor(totalWidth)) {

0 commit comments

Comments
 (0)