Reputation: 321
I have an array of appointments and a react view that would display them one at a time. The user can browse the appointments by clicking arrows back and forward.
The data looks something like this:
const arr = [
{ start: 10, end: 12, id: 7532 },
{ start: 11, end: 13, id: 6775 },
{ start: 14, end: 15, id: 554 },
{ start: 17, end: 18, id: 3232 }
];
I'm trying to figure out what is the best way to implement this. The page displays the first element immediately and ideally, the user wouldn't be able to click the back button when the selected element is arr[0]. Same would apply to clicking forward. I'm a bit confused how indexing of arrays works in situations like this, I seem to get index value of -1 even when the selected appointment is part of the array. Also, I'm unsure if it makes sense to save the current index into a react state or just keep it in the function that is triggered on click.
Upvotes: 3
Views: 89
Reputation: 402
Here is my working pagination component
import React from 'react';
// MATERIAL UI CORE
import IconButton from "@material-ui/core/IconButton";
// MATERIAL UI COMPONENTS
import FirstIcon from "@material-ui/icons/FirstPage";
import PrevIcon from "@material-ui/icons/ChevronLeft";
import NextIcon from "@material-ui/icons/ChevronRight";
import LastIcon from "@material-ui/icons/LastPage";
const Pagination = props => {
const {
num, // ARRAYS LENGTH
current, // CURRENT PAGE
onCurrent, // CHAGING THE CURRENT PAGE MINUS OR POSITION
fromPage, // START OF PAGINATION
toPage, // END OF PAGINATION - EXAMPLE 20/40 SO WERE SEEING 20 ARTICLES
pagely // HOW MANY ITEMS PER PAGE
} = props;
const pages = Math.ceil(num / pagely);
const first = current === 0;
const last = current === pages - 1;
return (
<div className = "pagination">
<div className = "icon">
<IconButton
onClick = {onCurrent.bind(this, 0)}
disabled = {first}>
<FirstIcon />
</IconButton>
</div>
<div className = "icon">
<IconButton
onClick = {onCurrent.bind(this, Math.max(current - 1, 0))}
disabled = {first}>
<PrevIcon />
</IconButton>
</div>
<div className = "text">
<span>Items {fromPage + 1} - {toPage} of {num}</span>
<br />
<span>Page {current + 1} of {pages}</span>
</div>
<div className = "icon">
<IconButton
onClick = {onCurrent.bind(this, Math.min(current + 1, pages - 1))}
disabled = {last}>
<NextIcon />
</IconButton>
</div>
<div className = "icon">
<IconButton
onClick = {onCurrent.bind(this, pages - 1)}
disabled = {last}>
<LastIcon />
</IconButton>
</div>
</div>
);
}
export default Pagination;
Hope this helps
Daniel
Upvotes: 1
Reputation: 1
my english isn´t good, but i think u will understand this... The variables names are random, because i am not an organized person, but you can fix it
import React, { Component } from 'react'; import { render } from 'react-dom'; import Hello from './Hello'; import './style.css';
class App extends Component { constructor() {
super();
this.arr = [
{ start: 10, end: 12, id: 7532 },
{ start: 11, end: 13, id: 6775 },
{ start: 14, end: 15, id: 554 },
{ start: 17, end: 18, id: 3232 } ]; this.h1 = document.createElement("h1") } componentDidMount(){
this.h1.innerText = this.arr[0].id
document.body.appendChild(this.h1)
document.getElementById("back").disabled = true
this.numbe = {
number: 0,
change: function(number){
this.number = number
}
}
} render() {
return (
<div> <button onClick={() => this.ir("back")} id="back">Back</button> <button onClick={() => this.ir("foward")} id="foward">Foward</button>
</div>
); } ir(teste){
if(parseInt(this.h1.innerText) === this.arr[this.arr.length - 2].id){
document.getElementById("foward").disabled = true
}
else{
document.getElementById("foward").disabled = false
document.getElementById("back").disabled = false
}
if(parseInt(this.h1.innerText) === this.arr[1].id){
document.getElementById("back").disabled = true
}
else{
document.getElementById("back").disabled = false
document.getElementById("back").disabled = false
}
if(teste === "foward"){
var result = this.numbe.number + 1
this.numbe.change(result)
this.h1.innerText = this.arr[this.numbe.number].id
}
else{
var result = this.numbe.number - 1
this.numbe.change(result)
this.h1.innerText = this.arr[this.numbe.number].id
} } }
render(<App />, document.getElementById('root'));
Upvotes: 0
Reputation: 3777
You're on the right track, there's nothing wrong with storing the index separately from the data. Here's some code to get you started:
class MyComp extends React.Component {
render() {
const { data } = this.props;
return <span>{data.id}</span>;
}
}
class MyList extends React.Component {
state = {
index: 0
};
onPrevClick = () => {
const { index } = this.state;
if (index > 0) this.setState({ index: index - 1 });
};
onNextClick = () => {
const { data } = this.props;
const { index } = this.state;
if (index < data.length - 1) this.setState({ index: index + 1 });
};
render() {
const { data } = this.props;
const { index } = this.state;
return (
<>
<span onClick={this.onPrevClick}>prev</span>
<MyComp data={data[index]} />
<span onClick={this.onNextClick}>next</span>
</>
);
}
}
Here's a working, albeit crude, codesandbox
Upvotes: 0
Reputation: 340
Add a state called pageIndex that initializes to 0 that increments or decrements whenever the next or back buttons are clicked respectively.
If the value of the pageIndex will be -1 on clicking back, then it should disable - this takes care of the arr[0] problem you stated.
If the value of the pageIndex will be greater than the length of arr, then the forward button will disable.
Hope that gives you an idea 😁
Upvotes: 1