1

I'm trying to create a certain functionality in my react-data-grid.

I have a column called subStart, and I have a dropdown that I want to use so that the user can set the value of a cell to the value of a state variable (this.state.timeTotalSec). So if the user clicks on "Use Global Time" option in a 'Start Time' cell, it will replace the value of that cell with the value of this.state.timeTotalSec. How on earth do I do this?

I have the dropdown functionality working. But how do I get it to change the cell value?

const rows = [
  { id: 1, subStart: "00:00.000", subEnd: "00:00.000" , subText: 'Text1'},
  { id: 2, subStart: "00:00.000", subEnd: "00:00.000" , subText: 'Text2'},
  { id: 3, subStart: "00:00.000", subEnd: "00:00.000" , subText: 'Text3'}
];

const columns = [
  {
    key: "id",
    name: "ID"
  },
  {
    key: "subStart",
    name: "Start Time",
    editable: true
  },
  {
    key: "subEnd",
    name: "End Time",
    editable: true
  },
  {
    key: "subText",
    name: "Text",
    editable: true
  }
].map(c => ({ ...c, ...defaultColumnProperties }));

const subStartActions = [
  {
    icon: <span className="glyphicon glyphicon-remove" />,
    callback: () => {
      alert("Deleting");
    }
  },
  {
    icon: "glyphicon glyphicon-link",
    actions: [
      {
        text: "Use Global Time",
        callback: () => {
          // TODO
          // **** TRYING TO MAKE THIS WORK ****
        }
      }
    ]
  }
];

function getCellActions(column, row) {
  const cellActions = {
    subStart: subStartActions
  };
  return row.id % 2 === 0 ? cellActions[column.key] : null;
}

const ROW_COUNT = 50;

class App extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      playing: false,
      duration: 0,
      timeMilli: 0,
      timeSec: 0,
      timeMin: 0,
      timeTotalSec: 0,
      rows
    }
  }

  onDuration = (duration) => {
    this.setState({ duration })
  }
  onProgress = (progress) => {
    if (this.state.duration == 0) {
      return
    }

    const timeTotalSec = progress.played * this.state.duration

    if (timeTotalSec !== this.state.timeTotalSec) {
      const timeMin = Math.floor(timeTotalSec / 60)
      const timeSec = Math.floor(timeTotalSec - (timeMin)*60)
      const timeMilli = (timeTotalSec - timeSec - timeMin*60).toFixed(3)

      this.setState({ timeTotalSec })
      this.setState({ timeMin })
      this.setState({ timeSec })
      this.setState({ timeMilli })
    }
  } 

  onGridRowsUpdated = ({ fromRow, toRow, updated }) => {
    this.setState(state => {
      const rows = state.rows.slice();
      for (let i = fromRow; i <= toRow; i++) {
        rows[i] = { ...rows[i], ...updated };
      }
      return { rows };
    });
  };


  render () {
    const { data } = this;


    return (
        <div className='player-wrapper'>
        <ReactPlayer
          url='https://www.youtube.com/watch?v=lhlZkqEag7E'
          className='react-player'
          playing={this.state.playing}
          onPlay={() => this.setState({ playing: true })}
          onPause={() => this.setState({ playing: false })}
          controls='True'
          onDuration={this.onDuration}
          onProgress={this.onProgress}
        />
        Video is currently: {this.state.playing ? 'playing' : 'paused'}
        <br />
        Duration: {Math.round(this.state.duration).toString() + ' seconds'}
        <br />
        Elapsed: {this.state.timeMin + 'min ' + this.state.timeSec + 'sec ' + 
                  this.state.timeMilli + 'ms'}

        <br />
        <button onClick={() => this.setState({ playing: true })}>Play</button>
        <button onClick={() => this.setState({ playing: false })}>Pause</button>

        <ButtonToolbar>
          <Button variant="primary" onClick={() => this.setState(this.state.playing ? false : true)}>Play/Pause</Button>
        </ButtonToolbar>

      <ReactDataGrid
        columns={columns}
        rowGetter={i => this.state.rows[i]}
        rowsCount={ROW_COUNT}
        // minHeight={500}
        getCellActions={getCellActions}
        onGridRowsUpdated={this.onGridRowsUpdated}
        enableCellSelect={true}
      />

    </div>
    )
  }
}
KyleCraig
  • 25
  • 1
  • 4

1 Answers1

0

ReactDataGrid will just render what data you pass to it, If you want to change the value of a cell, you should update the rows from data source or state you are using.in your case rows

 this.state = {
      playing: false,
      duration: 0,
      timeMilli: 0,
      timeSec: 0,
      timeMin: 0,
      timeTotalSec: 10,
      rows // your datasourse
    };

I've supposed,id is your data Key.Add updateRowDate to actions to handle your state changes.

actions: [
      {
        text: "Use Global Time",
        callback: () => {
          // TODO
          // **** TRYING TO MAKE THIS WORK ****
          updateRowDate(row.id);
        }
      }
    ]

and here is updateRowDate in App component

  updateRowDate = rowId => {
    this.setState(prv => ({
      rows: prv.rows.map(q => {
        if (q.id === rowId) return { ...q, subStart: this.state.timeTotalSec };
        return q;
      })
    }));

finally, you need to pass updateRowDate to getCellActions

<ReactDataGrid
          columns={columns}
          rowGetter={i => this.state.rows[i]}
          rowsCount={ROW_COUNT}
          // minHeight={500}
          getCellActions={(column, row) =>
            getCellActions(column, row, this.updateRowDate)
          }
          onGridRowsUpdated={this.onGridRowsUpdated}
          enableCellSelect={true}
        />

Here is the temporary sandbox containing the fixed version

Alex
  • 3,941
  • 1
  • 17
  • 24