Skip to content

Commit

Permalink
Fixed #809 - Add row edit support to DataTable
Browse files Browse the repository at this point in the history
  • Loading branch information
mertsincan committed Sep 9, 2019
1 parent dcbbc3d commit 6527c72
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 34 deletions.
6 changes: 4 additions & 2 deletions src/components/column/Column.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ export class Column extends Component {
onEditorCancel: null,
excludeGlobalFilter: false,
rowReorder: false,
rowReorderIcon: 'pi pi-bars'
rowReorderIcon: 'pi pi-bars',
rowEditor: false
}

static propTypes = {
Expand Down Expand Up @@ -80,6 +81,7 @@ export class Column extends Component {
editorValidatorEvent: PropTypes.string,
excludeGlobalFilter: PropTypes.bool,
rowReorder: PropTypes.bool,
rowReorderIcon: PropTypes.string
rowReorderIcon: PropTypes.string,
rowEditor: PropTypes.bool
}
}
82 changes: 61 additions & 21 deletions src/components/datatable/BodyCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ export class BodyCell extends Component {

constructor(props) {
super(props);
this.state = {};
this.state = {
editing: this.props.editing
};

this.onExpanderClick = this.onExpanderClick.bind(this);
this.onClick = this.onClick.bind(this);
this.onBlur = this.onBlur.bind(this);
Expand All @@ -29,31 +32,35 @@ export class BodyCell extends Component {
}

onKeyDown(event) {
if (event.which === 13 || event.which === 9) { // tab || enter
this.switchCellToViewMode(true);
}
if (event.which === 27) // escape
{
this.switchCellToViewMode(false);
if (this.props.editMode !== 'row') {
if (event.which === 13 || event.which === 9) { // tab || enter
this.switchCellToViewMode(true);
}
if (event.which === 27) // escape
{
this.switchCellToViewMode(false);
}
}
}

onClick() {
this.editingCellClick = true;
if (this.props.editMode !== 'row') {
this.editingCellClick = true;

if (this.props.editor && !this.state.editing) {
this.setState({
editing: true
});
if (this.props.editor && !this.state.editing) {
this.setState({
editing: true
});

if (this.props.editorValidatorEvent === 'click') {
this.bindDocumentEditListener();
}
if (this.props.editorValidatorEvent === 'click') {
this.bindDocumentEditListener();
}
}
}
}

onBlur() {
if (this.state.editing && this.props.editorValidatorEvent === 'blur') {
if (this.props.editMode !== 'row' && this.state.editing && this.props.editorValidatorEvent === 'blur') {
this.switchCellToViewMode(true);
}
}
Expand Down Expand Up @@ -113,9 +120,19 @@ export class BodyCell extends Component {
this.documentEditListener = null;
}
}

static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.editing !== prevState.editing) {
return {
editing: nextProps.editing
}
}

return null;
}

componentDidUpdate() {
if (this.container && this.props.editor) {
if (this.props.editMode !== 'row' && this.container && this.props.editor) {
clearTimeout(this.tabindexTimeout);
if (this.state.editing) {
let focusable = DomHandler.findSingle(this.container, 'input');
Expand All @@ -141,7 +158,7 @@ export class BodyCell extends Component {
}

render() {
let content, header;
let content, header, editorKeyHelper;
let cellClassName = classNames(this.props.bodyClassName||this.props.className, {
'p-selection-column': this.props.selectionMode,
'p-editable-column': this.props.editor,
Expand Down Expand Up @@ -169,6 +186,27 @@ export class BodyCell extends Component {
<i className={reorderIcon}></i>
);
}
else if (this.props.rowEditor) {
if (this.state.editing) {
content = (
<React.Fragment>
<button onClick={this.props.onRowEditSave} className="p-row-editor-save p-link">
<span className="p-row-editor-save-icon pi pi-fw pi-check p-clickable"></span>
</button>
<button onClick={this.props.onRowEditCancel} className="p-row-editor-cancel p-link">
<span className="p-row-editor-cancel-icon pi pi-fw pi-times p-clickable"></span>
</button>
</React.Fragment>
);
}
else {
content = (
<button onClick={this.props.onRowEditInit} className="p-row-editor-init p-link">
<span className="p-row-editor-init-icon pi pi-fw pi-pencil p-clickable"></span>
</button>
);
}
}
else {
if (this.state.editing) {
if (this.props.editor)
Expand All @@ -188,9 +226,11 @@ export class BodyCell extends Component {
header = <span className="p-column-title">{this.props.header}</span>;
}

/* eslint-disable */
let editorKeyHelper = this.props.editor && <a tabIndex="0" ref={(el) => {this.keyHelper = el;}} className="p-cell-editor-key-helper p-hidden-accessible" onFocus={this.onEditorFocus}><span></span></a>;
/* eslint-enable */
if (this.props.editMode !== 'row') {
/* eslint-disable */
editorKeyHelper = this.props.editor && <a tabIndex="0" ref={(el) => {this.keyHelper = el;}} className="p-cell-editor-key-helper p-hidden-accessible" onFocus={this.onEditorFocus}><span></span></a>;
/* eslint-enable */
}

return (
<td ref={(el) => {this.container = el;}} className={cellClassName} style={this.props.bodyStyle||this.props.style} onClick={this.onClick} onKeyDown={this.onKeyDown}
Expand Down
64 changes: 62 additions & 2 deletions src/components/datatable/BodyRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ export class BodyRow extends Component {

constructor(props) {
super(props);
this.state = {
editing: false
};

this.onClick = this.onClick.bind(this);
this.onDoubleClick = this.onDoubleClick.bind(this);
this.onTouchEnd = this.onTouchEnd.bind(this);
Expand All @@ -17,6 +21,9 @@ export class BodyRow extends Component {
this.onDragLeave = this.onDragLeave.bind(this);
this.onDrop = this.onDrop.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
this.onRowEditInit = this.onRowEditInit.bind(this);
this.onRowEditSave = this.onRowEditSave.bind(this);
this.onRowEditCancel = this.onRowEditCancel.bind(this);
}

onClick(event) {
Expand Down Expand Up @@ -161,6 +168,58 @@ export class BodyRow extends Component {
}
}

onRowEditInit(event) {
if (this.props.onRowEditInit) {
this.props.onRowEditInit({
originalEvent: event,
data: this.props.rowData
});
}

this.setState({
editing: true
});

event.preventDefault();
}

onRowEditSave(event) {
let valid = true;

if (this.props.rowEditorValidator) {
valid = this.props.rowEditorValidator(this.props.rowData);
}

if (this.props.onRowEditSave) {
this.props.onRowEditSave({
originalEvent: event,
data: this.props.rowData
});
}

this.setState({
editing: !valid
});

event.preventDefault();
}

onRowEditCancel(event) {
if (this.props.onRowEditCancel) {
this.props.onRowEditCancel({
originalEvent: event,
data: this.props.rowData,
index: this.props.rowIndex
});
}

this.setState({
editing: false
});

event.preventDefault();
}

render() {
let columns = React.Children.toArray(this.props.children);
let conditionalStyles = {
Expand All @@ -176,7 +235,7 @@ export class BodyRow extends Component {
let hasRowSpanGrouping = this.props.rowGroupMode === 'rowspan';
let cells = [];

for(let i = 0; i < columns.length; i++) {
for (let i = 0; i < columns.length; i++) {
let column = columns[i];
let rowSpan;
if(hasRowSpanGrouping) {
Expand All @@ -192,7 +251,8 @@ export class BodyRow extends Component {
}

let cell = <BodyCell key={i} {...column.props} value={this.props.value} rowSpan={rowSpan} rowData={this.props.rowData} rowIndex={this.props.rowIndex} onRowToggle={this.props.onRowToggle} expanded={this.props.expanded}
onRadioClick={this.props.onRadioClick} onCheckboxClick={this.props.onCheckboxClick} responsive={this.props.responsive} selected={this.props.selected} />;
onRadioClick={this.props.onRadioClick} onCheckboxClick={this.props.onCheckboxClick} responsive={this.props.responsive} selected={this.props.selected}
editMode={this.props.editMode} editing={this.state.editing} onRowEditInit={this.onRowEditInit} onRowEditSave={this.onRowEditSave} onRowEditCancel={this.onRowEditCancel} />;

cells.push(cell);
}
Expand Down
21 changes: 17 additions & 4 deletions src/components/datatable/DataTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export class DataTable extends Component {
tabIndex: '0',
stateKey: null,
stateStorage: 'session',
editMode: 'cell',
onColumnResizeEnd: null,
onSort: null,
onPage: null,
Expand All @@ -94,7 +95,11 @@ export class DataTable extends Component {
onContextMenu: null,
onColReorder: null,
onRowReorder: null,
onValueChange: null
onValueChange: null,
rowEditorValidator: null,
onRowEditInit: null,
onRowEditSave: null,
onRowEditCancel: null
}

static propTypes = {
Expand Down Expand Up @@ -163,6 +168,7 @@ export class DataTable extends Component {
tabIndex: PropTypes.string,
stateKey: PropTypes.string,
stateStorage: PropTypes.string,
editMode: PropTypes.string,
onColumnResizeEnd: PropTypes.func,
onSort: PropTypes.func,
onPage: PropTypes.func,
Expand All @@ -177,7 +183,11 @@ export class DataTable extends Component {
onContextMenu: PropTypes.func,
onColReorder: PropTypes.func,
onRowReorder: PropTypes.func,
onValueChange: PropTypes.func
onValueChange: PropTypes.func,
rowEditorValidator: PropTypes.func,
onRowEditInit: PropTypes.func,
onRowEditSave: PropTypes.func,
onRowEditCancel: PropTypes.func
};

constructor(props) {
Expand Down Expand Up @@ -987,7 +997,9 @@ export class DataTable extends Component {
}

closeEditingCell() {
document.body.click();
if (this.props.editMode !== "row") {
document.body.click();
}
}

onHeaderCheckboxClick(event) {
Expand Down Expand Up @@ -1153,7 +1165,8 @@ export class DataTable extends Component {
onRowExpand={this.props.onRowExpand} onRowCollapse={this.props.onRowCollapse} responsive={this.props.responsive} emptyMessage={this.props.emptyMessage}
virtualScroll={this.props.virtualScroll} virtualRowHeight={this.props.virtualRowHeight} loading={this.props.loading}
groupField={this.props.groupField} rowGroupMode={this.props.rowGroupMode} rowGroupHeaderTemplate={this.props.rowGroupHeaderTemplate} rowGroupFooterTemplate={this.props.rowGroupFooterTemplate}
sortField={this.getSortField()} rowClassName={this.props.rowClassName} onRowReorder={this.props.onRowReorder}>
sortField={this.getSortField()} rowClassName={this.props.rowClassName} onRowReorder={this.props.onRowReorder}
editMode={this.props.editMode} rowEditorValidator={this.props.rowEditorValidator} onRowEditInit={this.props.onRowEditInit} onRowEditSave={this.props.onRowEditSave} onRowEditCancel={this.props.onRowEditCancel}>
{columns}
</TableBody>;
}
Expand Down
13 changes: 8 additions & 5 deletions src/components/datatable/TableBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,11 +518,14 @@ export class TableBody extends Component {

//row content
let bodyRow = <BodyRow key={i} value={this.props.value} rowData={rowData} rowIndex={i} onClick={this.onRowClick} onDoubleClick={this.props.onRowDoubleClick} onRightClick={this.onRowRightClick} onTouchEnd={this.onRowTouchEnd}
onRowToggle={this.onRowToggle} expanded={expanded} responsive={this.props.responsive} selectionMode={this.props.selectionMode}
onRadioClick={this.onRadioClick} onCheckboxClick={this.onCheckboxClick} selected={selected} contextMenuSelected={contextMenuSelected} rowClassName={this.props.rowClassName}
sortField={this.props.sortField} rowGroupMode={this.props.rowGroupMode} groupRowSpan={groupRowSpan}
onDragStart={(e) => this.onRowDragStart(e, i)} onDragEnd={this.onRowDragEnd} onDragOver={(e) => this.onRowDragOver(e, i)} onDragLeave={this.onRowDragLeave}
onDrop={this.onRowDrop} virtualRowHeight={this.props.virtualRowHeight}>{this.props.children}</BodyRow>
onRowToggle={this.onRowToggle} expanded={expanded} responsive={this.props.responsive} selectionMode={this.props.selectionMode}
onRadioClick={this.onRadioClick} onCheckboxClick={this.onCheckboxClick} selected={selected} contextMenuSelected={contextMenuSelected} rowClassName={this.props.rowClassName}
sortField={this.props.sortField} rowGroupMode={this.props.rowGroupMode} groupRowSpan={groupRowSpan}
onDragStart={(e) => this.onRowDragStart(e, i)} onDragEnd={this.onRowDragEnd} onDragOver={(e) => this.onRowDragOver(e, i)} onDragLeave={this.onRowDragLeave}
onDrop={this.onRowDrop} virtualRowHeight={this.props.virtualRowHeight}
editMode={this.props.editMode} rowEditorValidator={this.props.rowEditorValidator} onRowEditInit={this.props.onRowEditInit} onRowEditSave={this.props.onRowEditSave} onRowEditCancel={this.props.onRowEditCancel}>
{this.props.children}
</BodyRow>

rows.push(bodyRow);

Expand Down

0 comments on commit 6527c72

Please sign in to comment.