Skip to content

Instantly share code, notes, and snippets.

@denihida1216
Created August 17, 2020 02:37
Show Gist options
  • Save denihida1216/f9291aed039a1113a475b7378320dbdc to your computer and use it in GitHub Desktop.
Save denihida1216/f9291aed039a1113a475b7378320dbdc to your computer and use it in GitHub Desktop.
DataTables React + Laravel
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" }}>
{" "}
&nbsp;{" "}
<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