Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handsontable & React

I'm starting with react and trying to set up handsontable in my react app following: react-handsontable

// import React...
import React from 'react';
import ReactDOM from 'react-dom';

// ... Handsontable with its main dependencies...
import moment from 'moment';
import numbro from 'numbro';
import pikaday from 'pikaday';
import Zeroclipboard from 'zeroclipboard';
import Handsontable from 'handsontable';

// ... and HotTable
import HotTable from 'react-handsontable';

class ExampleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handsontableData = [
      ["", "Ford", "Volvo", "Toyota", "Honda"],
      ["2016", 10, 11, 12, 13],
      ["2017", 20, 11, 14, 13],
      ["2018", 30, 15, 12, 13]
    ];
  }

  render() {
    return (
      <div id="example-component">
        <HotTable root="hot" data={this.handsontableData} colHeaders={true} rowHeaders={true} width="600" height="300" stretchH="all" />
      </div>
    );
  }
}

Works so far but how do I get the instance of the table like in pure javascript

var ht = new Handsontable(document.getElementById('example1'), options);


ht.setDataAtCell(0, 0, 'new value');

Thanks, Tim

like image 874
Tim Avatar asked May 07 '17 11:05

Tim


3 Answers

If you're trying to access the core methods, like 'setDataAtCell()', you can use refs to access them.

For example add the "ref='xyz'" attribute to the HTML element and you can then call it with "this.refs.xyz". I've modified your example below to illustrate. It adds a button that onClick runs a function to 'setDataAtCell'.

// import React...
import React from 'react';
import ReactDOM from 'react-dom';

// ... Handsontable with its main dependencies...
import moment from 'moment';
import numbro from 'numbro';
import pikaday from 'pikaday';
import Zeroclipboard from 'zeroclipboard';
import Handsontable from 'handsontable';

// ... and HotTable
import HotTable from 'react-handsontable';

class ExampleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handsontableData = [
      ["", "Ford", "Volvo", "Toyota", "Honda"],
      ["2016", 10, 11, 12, 13],
      ["2017", 20, 11, 14, 13],
      ["2018", 30, 15, 12, 13]
    ];
  }

  handleClick(e) {
    this.refs.hot.hotInstance.setDataAtCell(0, 0, 'new value')
  }

  render() {
    return (
      <div id="example-component">
        <HotTable root="hot"
                  data={this.handsontableData}
                  colHeaders={true}
                  rowHeaders={true}
                  width="600"
                  height="300"
                  stretchH="all"
                  ref="hot"
        />
        <br/>
        <button onClick={(e)=>this.handleClick(e)}>Click Me</button>
      </div>
    );
  }
}

export default ExampleComponent

This method can be used to access other methods like "getData()" which can be used to get a snapshot of the data in the table which can be saved to state or similar. So it's more lengthy than "ht" you can use "this.refs.hot.hotInstance" for similar affect.

You can read more about the ref attribute in "Refs and the DOM" in the React documentation.

like image 112
Tantivy Avatar answered Oct 11 '22 19:10

Tantivy


To access the instance of HotTable component, use ref. However, don't use old way of using ref. As of version 16.3, React provides 2 ways :

  • using createRef API which is the recommended way
  • using callback ref which is already available in earlier version, but better than the old "string ref" way.

I only show how to use createRef here :

  1. In your constructor, add the following :

    this.refToHotIns=React.createRef();
    

    The name of the field property is arbitrary, you can name it as you like.

  2. In your render() method, change the JSX element to :

       <HotTable ref={this.refToHotIns} data={this.handsontableData} colHeaders={true} rowHeaders=true} width="600" height="300" stretchH="all" />
    
  3. Now, this.refToHotIns.current references to mounted HotTable instance. The Handsontable instance is stored under the hotInstance property of the wrapper component. So you can then access properties/methods of HotTable instance, like so :

    this.refToHotIns.current.hotInstance.setDataAtCell(0, 0, 'new value');
    
like image 45
Lex Soft Avatar answered Oct 11 '22 18:10

Lex Soft


It's pretty simple to write your own react wrapper for handsontable, and then you can create a reference to your HOT instance. Here is some sample React component code:

componentWillReceiveProps({ gridSpec }) {

     if (gridSpec) {
        const {columns, colHeaders, data} = gridSpec;
        const container = document.getElementById(GRID_ID);

        this.hotInstance = new handsontable(container, {
            columns,
            colHeaders,
            data,
            height: 600
        });
    }
}

shouldComponentUpdate () {

    return false;
 }

render () {
    return (
        <div style={{overflowX: 'hidden', height: '600px'}}>
            <div id={GRID_ID} />
        </div>
    )
}
like image 3
Alex Sokoloff Avatar answered Oct 11 '22 19:10

Alex Sokoloff