/** * File: table.js * Author: Markus Grigull * Date: 02.03.2017 * * This file is part of VILLASweb. * * VILLASweb is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VILLASweb is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VILLASweb. If not, see . ******************************************************************************/ import React, { Component } from 'react'; import _ from 'lodash'; import { Table, Button, Glyphicon, FormControl, Label, Checkbox } from 'react-bootstrap'; import { Link } from 'react-router-dom'; //import TableColumn from './table-column'; class CustomTable extends Component { constructor(props) { super(props); this.activeInput = null; this.state = { rows: [], editCell: [ -1, -1 ] }; } static defaultProps = { width: null }; onClick(event, row, column) { this.setState({ editCell: [ column, row ]}); // x, y } addCell(data, index, child) { // add data to cell let content = null; if ('dataKeys' in child.props) { for (let key of child.props.dataKeys) { if (_.get(data, key) != null) { content = _.get(data, key); break; } } } else if ('dataKey' in child.props) { content = _.get(data, child.props.dataKey); } const modifier = child.props.modifier; if (modifier && content != null) { content = modifier(content); } let cell = []; if (content != null) { content = content.toString(); // check if cell should be a link const linkKey = child.props.linkKey; if (linkKey && data[linkKey] != null) { cell.push({content}); } else if (child.props.clickable) { cell.push( child.props.onClick(index)}>{content}); } else { cell.push(content); } } // add label to content const labelKey = child.props.labelKey; if (labelKey && data[labelKey] != null) { var labelContent = data[labelKey]; if (child.props.labelModifier) { labelContent = child.props.labelModifier(labelContent); } cell.push( ); } if (child.props.dataIndex) { cell.push(index); } // add buttons if (child.props.editButton) { cell.push(); } if (child.props.deleteButton) { cell.push(); } if (child.props.checkbox) { const checkboxKey = this.props.checkboxKey; cell.push( child.props.onChecked(index, e)} />); } if (child.props.exportButton) { cell.push(); } return cell; } componentWillReceiveProps(nextProps) { // check if data exists if (nextProps.data == null) { this.setState({ rows: [] }); return; } // create row data var rows = nextProps.data.map((data, index) => { // check if multiple columns if (Array.isArray(nextProps.children)) { var row = []; nextProps.children.forEach(child => { row.push(this.addCell(data, index, child)); }); return row; } else { // table only has a single column return [ this.addCell(data, index, nextProps.children) ]; } }); this.setState({ rows: rows }); } componentDidUpdate() { // A cell will not be selected at initial render, hence no need to call this in 'componentDidMount' if (this.activeInput) { this.activeInput.focus(); } } onCellFocus(index) { // When a cell focus is detected, update the current state in order to uncover the input element this.setState({ editCell: [ index.cell, index.row ]}); } cellLostFocus() { // Reset cell selection state this.setState({ editCell: [ -1, -1 ] }); } render() { // get children let children = this.props.children; if (Array.isArray(this.props.children) === false) { children = [ children ]; } return ( {this.props.children} { this.state.rows.map((row, rowIndex) => ( { row.map((cell, cellIndex) => { let isCellInlineEditable = children[cellIndex].props.inlineEditable === true; let tabIndex = isCellInlineEditable? 0 : -1; let evtHdls = isCellInlineEditable ? { onCellClick: (event) => this.onClick(event, rowIndex, cellIndex), onCellFocus: () => this.onCellFocus({cell: cellIndex, row: rowIndex}), onCellBlur: () => this.cellLostFocus() } : { onCellClick: () => {}, onCellFocus: () => {}, onCellBlur: () => {} }; return () }) } )) }
{(this.state.editCell[0] === cellIndex && this.state.editCell[1] === rowIndex ) ? ( children[cellIndex].props.onInlineChange(event, rowIndex, cellIndex)} inputRef={ref => { this.activeInput = ref; }} /> ) : ( {cell.map((element, elementIndex) => ( {element} ))} )}
); } } export default CustomTable;