Open Gi972 opened 7 years ago
@Gi972, I will support this feature, I want separate the content as two kind of usage, one is for the data loading and the other is for the real content after data loading.
BTW, I'm not sure when this feature will be supported, because I'm busy on my job and ready to release for v3.0.0
, so maybe pending to v3.0.0
or on v2.11.3
.
I also agree that this will be a good feature. It lets you be lazy with expanding rows. In the use case you are doing an async call for each row, it could reduce server calls.
THanks for the great library by the way!
hi all, I've some troubles on implement this feature and after I investigate further, I've some feedback want to give you guys.
For the async content, maybe you can achieve with following
AsyncExpandContent extends React.Component {
constructor(props) {
super(props);
this.state = {
expandingContentId: []
};
}
isExpandableRow(row) {
if (row.id < 3) return true;
else return false;
}
expandComponent(row) {
if (this.state.expandingContentId.indexOf(row.id) === -1) {
setTimeout(() => { // here is just a simulative AJAX call
// after AJAX complete::: save your content and force update the expandingContentId state
const expandingContentId = this.state.expandingContentId;
expandingContentId.push(row.id);
this.setState({ expandingContentId });
}, 10000);
} else {
return (
// your content
);
}
}
render() {
const options = {
expandRowBgColor: 'rgb(242, 255, 163)'
};
return (
<BootstrapTable ref='table'
data={ products }
options={ options }
striped
expandableRow={ this.isExpandableRow }
expandComponent={ this.expandComponent }
search>
<TableHeaderColumn dataField='id' isKey={ true }>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name'>Product Name</TableHeaderColumn>
<TableHeaderColumn dataField='price'>Product Price</TableHeaderColumn>
</BootstrapTable>
);
}
}
Anyway, I'll keep to find some solution, bot I want to hear you guys feedback, thanks
Hi @AllenFang ,
I don't know if is the most elegant, but It's not a bad idea. I will test it.
How you would like to implement it if you had no problem? with a new props like expandableAsyncRow ?
How you would like to implement it if you had no problem? with a new props like expandableAsyncRow ?
Good question, that's actually my problem, I wanna expose an API for you so that your AJAX call complete then call this exposed API, but there's something stuck.. If use a props is also a good solution, you need to save your result data in somewhere and the other problem is I dont know when you complete the AJAX~
Hi @AllenFang,
Arff! I tested and I had forgotten on the expanComponent you loop on all rows . So the ajax's call doesn't make on the click for a specific row but make a call on all rows and this is what we want to avoid. Maybe you should create a spécific props when you click on one row... lol in fact like onSelectRow...
I try with onSelectRow callback it works, it 's a bit messy but it works...
So Norw I don't know if you want create a new props or use the onSelectRow Call Back.
This is the code:
import React from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import $ from 'jquery';
const products = [];
function addProducts(quantity) {
const startId = products.length;
for (let i = 0; i < quantity; i++) {
const id = startId + i;
if (i < 3) {
products.push({
id: id,
name: 'Item name ' + id,
price: 2100 + i,
expand: null
});
} else {
products.push({
id: id,
name: 'Item name ' + id,
price: 2100 + i
});
}
}
}
addProducts(5);
export default class AsyncExpandContent extends React.Component {
constructor(props) {
super(props);
this.state = { expandingContentId: [] };
}
addAsyncProduct(row) {
const root = 'http://jsonplaceholder.typicode.com';
console.log('async');
$.ajax({
url: root + '/users',
method: 'GET'
}).then((data)=> {
console.log('data', data);
products[row.id].expand = {
email: data[row.id].email,
name: data[row.id].name,
phone: data[row.id].phone
};
const expandingContentId = this.state.expandingContentId;
expandingContentId.push(row.id);
this.setState({ expandingContentId });
});
}
isExpandableRow(row) {
if (row.id > 1) return true;
else return false;
}
expandComponent(row) {
console.log('row', row);
if (this.state.expandingContentId.filter((el) => {
return el === row.id;
}).length > 0) {
return (<div>
<ul>
<li>{ row.id }</li>
<li>{ row.price }</li>
<li>{ row.expand.email }</li>
<li>{ row.expand.name }</li>
<li>{ row.expand.phone }</li>
</ul>
</div>);
}
}
render() {
const options = {
expandRowBgColor: 'rgb(242, 255, 163)'
};
const selectRow = {
mode: 'checkbox', // multi select
bgColor: 'pink',
onSelect: this.addAsyncProduct.bind(this),
hideSelectColumn: true,
clickToExpand: true,
clickToSelect: true
};
return (
<BootstrapTable ref='table'
data={ products }
options={ options }
striped
selectRow={ selectRow }
expandableRow={ this.isExpandableRow }
expandComponent={ this.expandComponent.bind(this) }
search>
<TableHeaderColumn dataField='id' isKey={ true }>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name'>Product Name</TableHeaderColumn>
<TableHeaderColumn dataField='price'>Product Price</TableHeaderColumn>
</BootstrapTable>
);
}
}
It's not perfect , I think we can better... Give me your opinion.
The advantage of this, is you can use any libraries for ajax call... You not need implement a ajax call in bootstrapt Table, but you manage from A to Z.
sure, thanks your feedback, I'll keep to find out a best solution 👍 Thanks!
Since v3.3.5 there is the options.onExpand
callback which gives a pretty easy way to do async loading of data in the content of the expanded row.
I don't think we should have a special feature for that in this lib, since it's pretty easy to do it with the callback.
Any updates on this issue? Still struggling to execute this.
@ajits731 what exactly is the problem?
So a bit late, but is it still not possible to do a ajax call and based in the response, render the expanded view?
I am also facing the same issue. I want to trigger an async call and then want to show data in expanded table. But as of now this is being executed for each row on table initialisation, but I want this should happen only for specific row which I clicked on. Any updates ?
Hello @AllenFang
I want when I expand a row, make a ajax's call and return a content, maybe a other table or other div. Or in your example your expand props the data is already loaded. I think it's better to make a call ajax to fill the expand row.
It's possible? or have you a idea for implement this? or have you got a example? thanks