kyserslick kyserslick - 1 month ago 13
Javascript Question

Passing filtered value to react render()

I use react-datagrid to represent my documents table, but I cannot figure out how to instantiate render() scope with full data. It always instantiate with no data.

this is my datagrid

'use strict';

var React = require('react')
var DataGrid = require('react-datagrid')


var columns = [
{ name: 'id', title: '#', width: 50 },
{ name: 'business_id', flex: 1 },
{ name: 'lastName' },
{ name: 'city', flex: 1 },
{ name: 'country', flex: 1 },
{ name: 'email', width: 200 }
]

var App = React.createClass({

initData: function(documents){
if(documents){
return documents;
} else {
console.log('documents: '+ this.props.documents);
return this.props.documents;
}
},
getInitialState: function(){
return {
dataSource: [],
}
},
componentDidMount() {
this.setState({
dataSource: this.initData()
})
},
render: function(){
console.log('this.props.documents: '+ this.props.documents)
return <DataGrid
idProperty='id'
dataSource={this.initData()}
columns={columns}
style={{height: 400}}

onFilter={this.handleFilter}
liveFilter={true} //to apply the filter while typing
/>
},

handleFilter: function(column, value, allFilterValues){
//reset data to original data-array
var data = this.initData()

//go over all filters and apply them
Object.keys(allFilterValues).forEach(function(name){
var columnFilter = (allFilterValues[name] + '').toUpperCase()

if (columnFilter == ''){
return
}

data = data.filter(function(item){
if ((item[name] + '').toUpperCase().indexOf(columnFilter) === 0){
return true
}
})

})
this.initData(data)
this.setState({})
}
})


the first console log returns nothind


documents:


the console log in the render() returns data


this.props.documents:[object Object],[object Object],[object Object],[object Object],[object Object]


and this how I call my datagrid component from my home component

<DocumentReactNewGrid documents={this.state.documents}/>

Answer

Make the dataSource as a state. On filter, set the new data to the state. This will re-render the component with the new data.

'use strict';

 var React    = require('react')
 var DataGrid = require('react-datagrid')


var columns = [
   { name: 'id', title: '#', width: 50 },
   { name: 'business_id', flex: 1 },
   { name: 'lastName'  },
   { name: 'city', flex: 1 },
   { name: 'country', flex: 1 },
   { name: 'email', width: 200 }
]

var App = React.createClass({
  initData: function(documents){
    if(documents){
        return documents;
    } else {
        return this.props.documents;
    }
   },
  getInitialState: function(){
    return { 
      dataSource: this.initData(),
    }
  },
  componentWillReceiveProps(nextProps) {
    this.setState({
     dataSource: nextProps.documents,
    })
  },
  render: function(){
    return <DataGrid
        idProperty='id'
        dataSource={this.state.dataSource}
        columns={columns}
        style={{height: 400}}

        onFilter={this.handleFilter}
        liveFilter={true} //to apply the filter while typing
    />
   },


   handleFilter: function(column, value, allFilterValues){
    //reset data to original data-array
    var data = this.initData()

    //go over all filters and apply them
    Object.keys(allFilterValues).forEach(function(name){
        var columnFilter = (allFilterValues[name] + '').toUpperCase()

        if (columnFilter == ''){
            return
        }

        data = data.filter(function(item){
            if ((item[name] + '').toUpperCase().indexOf(columnFilter) === 0){
                return true
            }
        })

      })
      this.setState({
        dataSource: data
      })
    }
   })

Hope this helps!