lauraleonilla
lauraleonilla

Reputation: 321

Toggling between array elements React

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

Answers (4)

GaddBox
GaddBox

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

Ronkzinho
Ronkzinho

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

Danny Buonocore
Danny Buonocore

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

johnmikelridzz
johnmikelridzz

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

Related Questions