Surreal Surreal - 4 years ago 183
React JSX Question

react-bootstrap-table: Programmatically filter by clicking from another component

I’m using the react-bootstrap-table component and would like to programmatically filter a column by clicking on a button from another component.

I followed the Programmatically Select Filter example from the react-bootstrap-table examples list but didn’t manage to adapt it so the button from the other component can control the filter.

When I call

this.refs.nameCol.applyFilter(1);
on click, I get the following error message:


Uncaught TypeError: Cannot read property 'applyFilter' of undefined


The main question is: what's the best approach to tackle this?

Test example here:



var data = [
{id : "1", name : "Item name 1", quality : "bad"},
{id : "2", name : "Item name 2", quality : "good"},
{id : "3", name : "Item name 3", quality : "unknown"},
{id : "4", name : "Item name 4", quality : "good"},
{id : "5", name : "Item name 5", quality : "good"},
{id : "6", name : "Item name 6", quality : "bad"}
];

const qualityType = {
'good': 'good',
'bad': 'bad',
'unknown': 'unknown'
};

function enumFormatter(cell, row, enumObject) {
return enumObject[cell];
}

var FilterBtn = React.createClass({
handleBtnClick: function(e) {
this.refs.nameCol.applyFilter(1); // Cannot read property 'applyFilter' of undefined
},
render: function() {
return (
<button onClick={ this.handleBtnClick } className='btn btn-default'>Click to apply select filter</button>
);
}
});

var BigTable = React.createClass({
render: function() {
return (
<div>
<BootstrapTable data={ data }>
<TableHeaderColumn dataField='id' isKey>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name'>Product Name</TableHeaderColumn>
<TableHeaderColumn ref='nameCol' dataField='quality' filterFormatted dataFormat={ enumFormatter }
formatExtraData={ qualityType } filter={ { type: 'SelectFilter', options: qualityType } }>Product Quality</TableHeaderColumn>
</BootstrapTable>
</div>
);
}
});

ReactDOM.render(
<div>
<FilterBtn/>
<BigTable/>
</div>,
document.querySelector("#container")
);

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>

<body>
<div id="container"></div>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://npmcdn.com/react-bootstrap-table/dist/react-bootstrap-table.min.js"></script>

</body>
</html>





Many thanks for your help!

Answer Source

I wrote your program in ES6.Find the code below.

The problem is you mentioned the select options dictionary as something and while applying filter you are passing different argument.So if you want to select good upon button click then need to pass 'good' in applyFilter function.

        var data = [
      {id : "1", name : "Item name 1", quality : "bad"},
      {id : "2", name : "Item name 2", quality : "good"},
      {id : "3", name : "Item name 3", quality : "unknown"},
      {id : "4", name : "Item name 4", quality : "good"},
      {id : "5", name : "Item name 5", quality : "good"},
      {id : "6", name : "Item name 6", quality : "bad"}
    ];

    const qualityType = {
      'good': 'good',
      'bad': 'bad',
      'unknown': 'unknown'
    };

    function enumFormatter(cell, row, enumObject) {
      return enumObject[cell];
    }
class FilterBtn extends React.Component{
    constructor(){
    super();
    this.handleBtnClick = this.handleBtnClick.bind(this);
  }
    handleBtnClick(){
    this.props.callAF();
  }
  render(){
    return (
            <button 
                onClick={ this.handleBtnClick } 
        className='btn btn-default'>
        Click to apply select filter
            </button>
        );
  }
}
class BigTable extends React.Component{
    constructor(){
    super();
    this.state={
        data: data
    }
  }
  componentWillReceiveProps(nextProps){
    if(this.props.applyFilter !== nextProps.applyFilter){
        this.refs.nameCol.applyFilter('good');  
    }
  }
  render(){
    return(
            <div>
                <BootstrapTable data={data}>
                    <TableHeaderColumn 
            dataField='id' 
            isKey>
            Product ID
                    </TableHeaderColumn>
                    <TableHeaderColumn 
            dataField='name'>
            Product Name
                    </TableHeaderColumn>
                    <TableHeaderColumn 
            ref='nameCol' 
            dataField='quality' 
            filterFormatted 
            dataFormat={ enumFormatter }
                        formatExtraData={ qualityType } 
            filter={{ 
                type: 'SelectFilter', 
              options: qualityType 
                        }}>
            Product Quality
                    </TableHeaderColumn>
                </BootstrapTable>
            </div>
        );
  }
}
class MainClass extends React.Component{
    constructor(){
    super();
    this.state = {
        applyFilter : false
    }
    this.callAFF = this.callAFF.bind(this);
  }
  callAFF(){
    this.setState({
        applyFilter: true
    });
  }
  render(){
    return (
        <div>
        <FilterBtn 
            callAF={
                this.callAFF
            }/>
         <BigTable
            applyFilter={this.state.applyFilter}/>
      </div>
    );
  }
}
ReactDOM.render(
    <MainClass/>,
    document.querySelector("#container")
);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download