Created
August 17, 2020 02:37
-
-
Save denihida1216/f9291aed039a1113a475b7378320dbdc to your computer and use it in GitHub Desktop.
DataTables React + Laravel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react"; | |
import Moment from "react-moment"; | |
import ReactTableContainer from "react-table-container"; | |
class DataTable extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
entities: { | |
data: [], | |
meta: { | |
current_page: 1, | |
from: 1, | |
last_page: 1, | |
per_page: 10, | |
to: 1, | |
total: 1 | |
} | |
}, | |
first_page: 1, | |
current_page: 1, | |
sorted_column: this.props.columns[0], | |
offset: 1, | |
order: "DESC", | |
search: "" | |
}; | |
} | |
fetchEntities() { | |
// let fetchUrl = `${this.props.url}/?page=${this.state.current_page}&column=${this.state.sorted_column}&order=${this.state.order}&per_page=${this.state.entities.meta.per_page}&search=${this.state.search}`; | |
let fetchUrl = `${this.props.url}`; | |
let data = { | |
page: this.state.current_page, | |
column: this.state.sorted_column, | |
order: this.state.order, | |
per_page: this.state.entities.meta.per_page, | |
search: this.state.search, | |
filter: this.props.filter | |
}; | |
// console.log(data) | |
axios | |
.post(fetchUrl, data) | |
.then(response => { | |
// console.log(response) | |
this.setState({ entities: response.data }); | |
}) | |
.catch(e => { | |
console.error(e); | |
}); | |
} | |
changeLength(event) { | |
let pp = JSON.parse(JSON.stringify(this.state.entities.meta)); | |
pp.per_page = event.target.value; | |
let entities = JSON.parse(JSON.stringify(this.state.entities)); | |
entities.meta = pp; | |
this.setState({ entities }, () => { | |
this.fetchEntities(); | |
}); | |
} | |
keypressFilter(event) { | |
if (event.key == "Enter") this.fetchEntities(); | |
// console.log({ search: event.key }); | |
} | |
changeFilter(event) { | |
this.setState({ search: event.target.value }, () => { | |
if (event.keyCode == 13 || this.state.search=='') this.fetchEntities(); | |
}); | |
// console.log({ search: event.target.value }); | |
} | |
changePage(pageNumber) { | |
this.setState({ current_page: pageNumber }, () => { | |
this.fetchEntities(); | |
}); | |
} | |
columnHead(value) { | |
return value | |
.split("_") | |
.join(" ") | |
.toUpperCase(); | |
} | |
pagesNumbers() { | |
if (!this.state.entities.meta.to) { | |
return []; | |
} | |
let from = this.state.entities.meta.current_page - this.state.offset; | |
if (from < 1) { | |
from = 1; | |
} | |
let to = from + this.state.offset * 2; | |
if (to >= this.state.entities.meta.last_page) { | |
to = this.state.entities.meta.last_page; | |
} | |
let pagesArray = []; | |
for (let page = from; page <= to; page++) { | |
pagesArray.push(page); | |
} | |
return pagesArray; | |
} | |
componentDidMount() { | |
this.setState( | |
{ current_page: this.state.entities.meta.current_page }, | |
() => { | |
this.fetchEntities(); | |
} | |
); | |
} | |
componentWillUnmount() { | |
this.setState = (state, callback) => { | |
return; | |
}; | |
} | |
componentDidUpdate(props) { | |
let { refresh } = this.props; | |
let { filter } = this.props; | |
if (props.refresh !== refresh) { | |
this.fetchEntities(); | |
} | |
if (props.filter !== filter) { | |
this.changePage(1); | |
} | |
} | |
tableLength() { | |
return ( | |
<div className="col-sm-6 col-xs-12 dt-length"> | |
<label> | |
Show{" "} | |
<select | |
name="table_length" | |
className="form-control input-sm" | |
onChange={this.changeLength.bind(this)} | |
value={this.state.entities.meta.per_page} | |
> | |
<option value="10">10</option> | |
<option value="25">25</option> | |
<option value="50">50</option> | |
<option value="100">100</option> | |
</select>{" "} | |
entries | |
</label> | |
</div> | |
); | |
} | |
tableFilter() { | |
return ( | |
<div className="col-sm-6 col-xs-12 dt-filter"> | |
<label> | |
Search: | |
<input | |
className="input-sm form-control dt-input-search" | |
type="text" | |
name="filter" | |
name="filter" | |
placeholder="" | |
onChange={this.changeFilter.bind(this)} | |
onKeyPress={this.keypressFilter.bind(this)} | |
/> | |
</label> | |
</div> | |
); | |
} | |
tableHeads() { | |
let icon; | |
let datacolumn = []; | |
if (this.state.order === "DESC") { | |
icon = <i className="fa fa-arrow-up"></i>; | |
} else { | |
icon = <i className="fa fa-arrow-down"></i>; | |
} | |
datacolumn.push( | |
<th className="table-head" key={"checkall"}> | |
<input type="checkbox" name="checkall" id="checkall" /> | |
</th> | |
); | |
this.props.columns.map(column => { | |
datacolumn.push( | |
<th | |
className="table-head" | |
key={column} | |
onClick={() => this.sortByColumn(column)} | |
> | |
{this.columnHead(column) + " "} | |
{column === this.state.sorted_column && icon} | |
</th> | |
); | |
}); | |
if (this.props.actions) { | |
datacolumn.push( | |
<th className="table-head text-center" key={"action"}> | |
# | |
</th> | |
); | |
} | |
return datacolumn; | |
} | |
List() { | |
if (this.state.entities.data.length) { | |
return this.state.entities.data.map((user, i) => { | |
return ( | |
<tr key={user.id}> | |
{/* {Object.keys(user).map(key => | |
<td key={key}> | |
{user[key]} | |
{console.log(key)} | |
</td> | |
)} */} | |
<td key={user.id}> | |
<input | |
type="checkbox" | |
name={"check-" + user.id} | |
id={"check-" + user.id} | |
/> | |
</td> | |
{this.props.columns.map(key => | |
key == "status" ? ( | |
user[key] == "read" ? ( | |
<td key={key}> | |
<span className="badge badge-success badge-pill"> | |
{user[key].toUpperCase()} | |
</span> | |
</td> | |
) : ( | |
<td key={key}> | |
<span className="badge badge-danger badge-pill"> | |
{user[key].toUpperCase()} | |
</span> | |
</td> | |
) | |
) : key == "created_at" ? ( | |
<td key={key}> | |
<Moment format="ddd DD-MM-YYYY HH:mm:ss"> | |
{user[key]} | |
</Moment> | |
</td> | |
) : ( | |
<td key={key}>{user[key]}</td> | |
) | |
)} | |
{this.props.actions(user)} | |
</tr> | |
); | |
}); | |
} else { | |
return ( | |
<tr> | |
<td | |
colSpan={ | |
this.props.actions | |
? this.props.columns.length + 1 | |
: this.props.columns.length | |
} | |
className="text-center" | |
> | |
No Records Found. | |
</td> | |
</tr> | |
); | |
} | |
} | |
sortByColumn(column) { | |
if (column === this.state.sorted_column) { | |
this.state.order === "DESC" | |
? this.setState( | |
{ order: "asc", current_page: this.state.first_page }, | |
() => { | |
this.fetchEntities(); | |
} | |
) | |
: this.setState({ order: "DESC" }, () => { | |
this.fetchEntities(); | |
}); | |
} else { | |
this.setState( | |
{ | |
sorted_column: column, | |
order: "DESC", | |
current_page: this.state.first_page | |
}, | |
() => { | |
this.fetchEntities(); | |
} | |
); | |
} | |
} | |
pageList() { | |
let data = []; | |
this.pagesNumbers().map(page => { | |
data.push( | |
<li | |
className={ | |
page === this.state.entities.meta.current_page | |
? "page-item active" | |
: "page-item" | |
} | |
key={page} | |
> | |
<button | |
className="page-link" | |
onClick={() => this.changePage(page)} | |
> | |
{page} | |
</button> | |
</li> | |
); | |
}); | |
return data; | |
} | |
render() { | |
return ( | |
<div className="dt-wrapper"> | |
<div className="row"> | |
{this.tableLength()} | |
{this.tableFilter()} | |
</div> | |
<ReactTableContainer width="100%" height="500px"> | |
<table className="table"> | |
<thead style={{ backgroundColor: "white" }}> | |
<tr>{this.tableHeads()}</tr> | |
</thead> | |
<tbody>{this.List()}</tbody> | |
</table> | |
</ReactTableContainer> | |
{this.state.entities.data && | |
this.state.entities.data.length > 0 && ( | |
<nav> | |
<span style={{ marginTop: "8px" }}> | |
{" "} | |
{" "} | |
<i> | |
Showing {this.state.entities.meta.from} to{" "} | |
{this.state.entities.meta.to} of{" "} | |
{this.state.entities.meta.total} entries. | |
</i> | |
</span> | |
<div className="float-right"> | |
<ul className="pagination"> | |
<li className="page-item"> | |
<button | |
className="page-link" | |
disabled={ | |
1 === | |
this.state.entities.meta | |
.current_page | |
} | |
onClick={() => | |
this.changePage( | |
this.state.entities.meta | |
.current_page - 1 | |
) | |
} | |
> | |
Previous | |
</button> | |
</li> | |
{this.pageList()} | |
<li className="page-item"> | |
<button | |
className="page-link" | |
disabled={ | |
this.state.entities.meta | |
.last_page === | |
this.state.entities.meta | |
.current_page | |
} | |
onClick={() => | |
this.changePage( | |
this.state.entities.meta | |
.current_page + 1 | |
) | |
} | |
> | |
Next | |
</button> | |
</li> | |
</ul> | |
</div> | |
</nav> | |
)} | |
</div> | |
); | |
} | |
} | |
export default DataTable; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment