i have a data grid which gets it's data from an api response then rendering it to server-side rendering and i basically do this SQL query from the database:
select * from orders
this simply selects every row in the orders table which is 350 rows
and in the api response i can see all the 350 rows that got retrieved from the database.
but when i render them in a Material-UI data grid i just get first 101 rows exactly 101.
i searched everywhere and couldn't see if there is a row limit so why is it exactly rendering only 101 rows?
i don't know if it will help but here is my code (i believe i didn't set a row limit if there is one....):
DataTable.js:
import { DataGrid, GridColDef, GridRowsProp } from "#material-ui/data-grid";
import React, { Fragment } from "react";
import { renderSelectEditCell } from "./select-field";
export default function DataTable({ rows0 }) {
const columns: GridColDef[] = [
{
editable: false,
sortable: false,
field: "username",
headerName: "username",
width: 150,
},
{
editable: true,
sortable: false,
field: "order_title",
headerName: "order_title",
width: 150,
},
{
editable: true,
sortable: false,
field: "order_price",
headerName: "order_price",
width: 150,
},
{
editable: true,
sortable: false,
field: "date",
headerName: "date",
width: 150,
},
{
editable: true,
sortable: false,
field: "order_status",
headerName: "order_status",
width: 150,
renderCell: renderSelectEditCell,
renderEditCell: renderSelectEditCell,
},
];
return (
<Fragment>
<div style={{ width: imgwidth }}>
<DataGrid
hideFooter
disableSelectionOnClick
disableDensitySelector
disableColumnSelector
disableColumnMenu
autoHeight
rows={rows0}
columns={columns}
/>
</div>
</Fragment>
);
}
Data0.js where i use DataTable:
import { getSession } from "next-auth/client";
import DataTable from "../../components/DataTable";
export default function Data0({ rows0 }) {
return (
<Fragment>
<DataTable rows0={rows0} />
</Fragment>
);
}
export async function getServerSideProps(context) {
const session = await getSession(context);
if (session) {
const res = await fetch(
`${process.env.WEBSITE_URL}/api/orders?user=${session.user.user_id}&test=ff`
);
const rows = await res.json();
return {
props: {
rows0: rows,
},
};
} else {
return {
props: {},
};
}
}
I think you'll find that if you remove the hideFooter prop, you'll see that there is pagination occurring -- you are just hiding the part that allows you to navigate through the pages.
From https://material-ui.com/components/data-grid/pagination/#paginate-gt-100-rows:
The DataGrid component can display up to 100 rows per page. The XGrid component removes this limitation.
DataGrid has a default page size of 100 and that is also the max page size allowed (unless you pay for the enterprise XGrid component).
Related
I have a data grid using MUI. I want to hide a few rows and not display them based on a given condition and if a particular value exists in a column. How do I hide it? There seems to be props such as
hide
for columns but there is nothing for rows.
EDIT
The code is as follows
I want to hide the row from being displayed if a value exists in the 4th column (field: 'recvDistLocId')
and I want to hide the rows only when I press a button in the toolbar. So basically, its like a filter. Initially, all the data should be displayed and if I click the button, all rows with a value in the 4th column should disappear.
const columns = []
columns.push({
field: 'code',
headerName: nowrapHeader(appLanguages.serialCode[lang]),
flex: 1,
getApplyQuickFilterFn: getApplyFilterFnSameYear
});
columns.push({
field: 'brandId',
headerName: nowrapHeader(appLanguages.brand[lang]),
renderCell: (params) =>
getSelectCustomBodyRender(this.getBrandOptionMap(), params.row.brandId),
flex: 1,
});
columns.push({
field: 'slip',
headerName: nowrapHeader(appLanguages.slipNum[lang]),
renderCell: (params) => this.getSlipText(params.row.slip),
flex: 1,
});
columns.push({
field: 'recvDistLocId',
headerName: 'RecvDistLocId',
flex: 1,
hide: true,
});
/////This is the main data grid element code in the render()
<div style={{ height: 640, width: '100%' }}>
<DataGrid
sx={{
'& .MuiDataGrid-columnHeaderCheckbox .MuiDataGrid-columnHeaderTitleContainer': {
display: 'none',
},
}}
rows={serialsList || []}
columns={columns}
rowsPerPageOptions={[25, 50, 100]}
checkboxSelection={this.state.cancelShipFlag ? true : false}
disableSelectionOnClick={false}
components={{
Toolbar: NewToolbar,
}}
onSelectionModelChange={(ids) => {
const selectedIDs = new Set(ids);
const selectedRows = rowData.filter((row) => selectedIDs.has(row.id));
this.setState({ rowinfo: selectedRows });
this.setState({ selectedrows: ids });
//console.log('Selected rows: ' + this.state.selectedrows);
}}
selectionModel={this.state.selectedrows}
/>
</div>
filter the data based on the condition
// use setFilterValue to set the value of the clicked column e.g. recvDistLocId
const [filterValue, setFilterValue] = React.useState()
// assuming serialsList is array of strings
// use same case for comparing values
// use row.toLowerCase() !== filterValue.toLowerCase()
const rows = (serialsList || []).filter(row => row !== filterValue)
Then pass rows to the data grid
<DataGrid
rows={rows}
....
I have a table on my react website using Tabulator. For some reason, the column headings would not show even though I have all the titles setup. My guess is that maybe cause I am setting the data again on componentDidUpdate() which is loading the data from redux.
Please help me on how to fix this.
The attached screenshot below shows how it is currently looking. I would want the column headings like "Name, ID" be shown on top.
import React, {Component} from 'react';
import {connect} from 'react-redux'
import {withRouter} from "react-router";
import 'react-tabulator/lib/styles.css'; // required styles
import 'react-tabulator/lib/css/tabulator_modern.css'; // theme
import Tabulator from "tabulator-tables";
class AllCoursesTabulator extends Component {
constructor(props) {
super(props);
this.el = React.createRef();
this.tabulator = null;
this.ref = null;
this.dataEditedFunc = this.dataEditedFunc.bind(this);
}
componentDidMount() {
let columns = [
{title: "ID", width: 150, field: "course_id"},
{title: "Name", field: "course_name"},
{title: "Section", field: "course_section"},
{title: "Instructor ID", field: "employee_id"},
{title: "Instructor Email", field: "employee_email", width: 250},
{
title: "Ilearn Video Service Requested",
field: "ilearn_video_service_requested",
hozAlign: "center",
formatter: "tickCross"
},
{title: "Ilearn Page ID", field: "ilearn_id"}
];
this.tabulator = new Tabulator(this.el, {
columns: columns,
layout: "fitColumns",
data: this.props.data,
reactiveData: true,
height: "500px",
cellEdited: this.dataEditedFunc
})
}
componentDidUpdate(prevProps, prevState, snapshot) {
this.tabulator.replaceData(this.props.data)
}
dataEditedFunc(cellData) {
//this function is to edit the cell on click
};
render() {
return (
<div className="emailTabulatorContainer">
<div ref={el => (this.el = el)}/>
</div>
)
}
}
function mapStateToProps({
globalsReducer,
coursesReducer
}, {props}) {
let data = []
let columns = []
let formatData = (course) => {
let ilearn_data = course.ilearn_page_id
if (ilearn_data != null) {
return {
course_id: course.course_gen_id,
course_name: course.course_name,
course_section: course.course_section,
employee_id: course.employee_id,
employee_email: course.course_instructor.employee_email,
ilearn_video_service_requested: course.ilearn_video_service_requested,
ilearn_id: course.ilearn_page_id.ilearn_page_id
}
}
}
if (coursesReducer !== undefined) {
Object.keys(coursesReducer).forEach(function (key) {
data.push(formatData(coursesReducer[key]))
});
}
return {
data,
columns,
semester: globalsReducer['currentSemester'],
coursesReducer
}
}
export default withRouter(connect(mapStateToProps)(AllCoursesTabulator))
Please tell me how to fix this. Thank you for your help.
Try to modify css? Just Like this
.tabulator-header .tabulator-headers.tabulator-col {
height: 40px !important; }
But, that's not a good solution.
After implementing the drag and drop feature on AG Grid table, I'm looking for a way to get the current state with the updated order/index of rows. My goal is to persist the table data after changing the order, but can't find the respective state of the current order.
I'd appreciate any help or any idea.
Sandbox demo and example code below
import React from "react";
import { AgGridReact } from "ag-grid-react";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-alpine.css";
function App() {
const [gridApi, setGridApi] = React.useState(null);
const [gridColumnApi, setGridColumnApi] = React.useState(null);
const onGridReady = (params) => {
setGridApi(params.api);
setGridColumnApi(params.columnApi);
};
const defaultColDef = {
flex: 1,
editable: true
};
const columnDefs = [
{
headerName: "Name",
field: "name",
rowDrag: true
},
{ headerName: "stop", field: "stop" },
{
headerName: "duration",
field: "duration"
}
];
const rowData = React.useMemo(
() => [
{
name: "John",
stop: 10,
duration: 5
},
{
name: "David",
stop: 15,
duration: 8
},
{
name: "Dan",
stop: 20,
duration: 6
}
],
[]
);
return (
<div>
<h1 align="center">React-App</h1>
<div>
<div className="ag-theme-alpine" style={{ height: "700px" }}>
<AgGridReact
columnDefs={columnDefs}
rowData={rowData}
defaultColDef={defaultColDef}
onGridReady={onGridReady}
rowDragManaged={true}
></AgGridReact>
</div>
</div>
</div>
);
}
export default App;
You can get the order of the rows inside the grid by iterating over them using the Grid API method forEachNode:
API for Row Nodes
const rows = [];
gridApi.forEachNodeAfterFilterAndSort((node) => rows.push(node.data));
console.log(rows);
See this implemented in the following sample.
You're currently using managed dragging by passing rowManagedDragging={true}, which means the AgGridReact component is managing the row order state.
If you want to maintain row order state outside the component, you need to use Unmanaged Dragging.
Add a handler for onRowDragMove, and use the node and overIndex or overNode properties of the event to update your local event order state, and pass it to the AgGridReact component to re-render.
Take a look at this example from the docs
I have source code below: (version antd: "^4.2.4")
column:
const columns = [
{
title: 'ID',
dataIndex: 'id',
sorter: true,
width: 100,
},
...
Table:
<Table rowSelection={rowSelection}
onChange={onChangeTable}
className='table'
size='small'
loading={schedules.loading}
pagination={{
...PAGINATION,
current: schedules.param.current,
pageSize: schedules.param.pageSize,
total: schedules.param.total,
}}
rowKey='id'
columns={columns}
dataSource={schedules.listData}
/>
call onChange:
const onChangeTable = (pagination, sorter) => {
console.log(sorter)
}
console.log(sorter) is empty when I click sort at column id.
Can you help me? Thanks you very much!
The documentation for onChange on the Table component shows the following signature:
function(
pagination,
filters,
sorter,
extra: { currentDataSource: [], action: paginate | sort | filter }
)
So you need to change the callback to:
const onChangeTable = (pagination, filters, sorter) => {
console.log(sorter)
}
I created a search app where users can search movies and it will be shown in the table. However, I want a delete button in the last column in each movie row to delete a movie from the table. I'm being unable to do that. Can someone help me as to how to add that delete button in the last column? I've already created the deleteMovie action and reducers. I'm just not sure how to add it to the table. I tried to do as they told in the docs but it isn't working for me
import React from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { deleteMovie } from "../action/movieActions";
import "react-bootstrap-table-next/dist/react-bootstrap-table2.min.css";
import BootstrapTable from "react-bootstrap-table-next";
const MovieTable = ({ data, deleteMovie }) => {
console.log(data);
const columns = [
{
dataField: "movieId",
text: "ID",
sort: true
},
{
dataField: "name",
text: "Name",
sort: true
},
{
dataField: "year",
text: "Year",
sort: true
},
{
dataField: "Delete",
title: "delete",
text: "Delete",
events: {
onClick: () => deleteMovie(data.movieId)//tried this but didn't work
}
}
]
return (
<div className="col m4">
<BootstrapTable keyField="id" data={data} columns={columns} />
</div>
);
};
MovieTable.propTypes = {
deleteMovie: PropTypes.func.isRequired
};
export default connect(
null,
{ deleteMovie }
)(MovieTable);
That way you are adding click event on column.
First you have to create a hook or a component that returns a button (The delete button) and then pass as parameter to that hook or component the id of the product.
The hook/component you will create has to be called on the data array!
The selector data.movieId is not valid, the data variable is an object containing an array. Select the movieId like this:
{
dataField: "movieId",
formatter: (rowContent, row) => {
return (
<button onClick={() => deleteMovie(data[0].movieId)}>delete</button>
);
}
}