Expanding does not work with clickToSelect
See original GitHub issueHi, @AllenFang I was still struggling with the managing expanding with row-select. I found the same issue here: issue 1038
But unlike the solution provided(disable clicktoselect), I would like both clickToSelect = true and clickToExpand = true, because I need clickToSelect to hight the row selected, and clickToExpand to expand the row at the same time.
I wanted to:
- select and expand the row on row click // working
- unselect and collapse the expandComponent on button click inside the expandComponent // not working
Currently the options{expanding: …} is not working though I followed the example here: manage-expanding
I am managing the selection and expanding from the two redux function :
- this.props.selectOrganization(row._id)
- this.props.unSelectOrganization(row._id);
Here is the code for the redux function: ` export default function reducer(state = defaultState, action) { switch (action.type) {
case "SELECT_ORGANIZATION": {
console.log([...state.batchEdit.selectedOrganizations, action.org]);
return {
...state,
batchEdit: {
...state.batchEdit,
selectedOrganizations: [...state.batchEdit.selectedOrganizations, action.org]
}
}
}
case "UNSELECT_ORGANIZATION": {
// console.log(state.batchEdit.selectedOrganizations.filter(it => it !== action.org));
return {
...state,
batchEdit: {
...state.batchEdit,
selectedOrganizations: state.batchEdit.selectedOrganizations.filter(it => it !== action.org)
}
}
}
… `
Here is my code for the table: ` class OrganizationsTable extends Component {
constructor(props) {
super(props);
}
handleRowSelect(row, isSelected, e){
if (isSelected) {
this.props.selectOrganization(row._id);
} else {
// delete from selectedRow array if unselected
this.props.unSelectOrganization(row._id);
}
return false;
}
render() {
const options = {
expandRowBgColor: '#D9D9D9', // grey background
sizePerPageList: [10, 15, 20, 50, 100], // Dropdown Options for rows per page
sizePerPage: 10,
expanding: this.props.selectedOrganizations, // not working as expected
};
const selectRow = {
mode: 'checkbox', // multi-select
className: 'clicked-row',
clickToSelect: true, // click to select, default is false
clickToExpand: true, // click to expand row, default is false
selected: this.props.selectedOrganizations, // manage selection
onSelect: this.handleRowSelect.bind(this),
};
var validateContext = Organizations.schema.namedContext("createNewOrganization");
return (
<div>
<MyImporter importFunction='organizations.import'
message='You have successfully added all organizations' context={validateContext}
collections='Organizations'/>
<BootstrapTable
data={ this.props.organizations }
options={ options } selectRow={ selectRow }
expandableRow={ () => {
return true // always return true as all rows are expandable
} }
expandComponent={(row) => {
return (<OrganizationDetail organization={ row }/>)
}}
exportCSV pagination>
<TableHeaderColumn dataField='_id' isKey hidden>ID</TableHeaderColumn>
<TableHeaderColumn dataField='organization_name'
dataSort={ true }>Organization</TableHeaderColumn>
<TableHeaderColumn dataField='address' dataSort={ true }>Address</TableHeaderColumn>
<TableHeaderColumn dataField='post_code' dataSort={ true }>Postal Code</TableHeaderColumn>
<TableHeaderColumn dataField='city' dataSort={ true }>City</TableHeaderColumn>
<TableHeaderColumn dataField='contact_name' dataSort={ true }>Contact Name</TableHeaderColumn>
<TableHeaderColumn dataField='phone' dataSort={ true }>Phone Number</TableHeaderColumn>
</BootstrapTable>
</div>
)
}
} `
And here is the code for the ExpandComponent: ` class OrganizationDetail extends Component {
// Called only once when the component is first loaded
constructor(props) {
super(props);
// inherit properties from parent and initialise state of this component
// we need to use state because state is changeable, while props is passing from parent and not changeable
this.state = props.organization;
this.state.errors = {
organization_name: '', contact_id: '', address: '', city: '', post_code: '', phone: ''
}
}
updateOrganization(event) {
event.preventDefault();
const organization = this.props.organization._id;
const {organization_name, address, post_code, city, phone, contact_id} = this.state;
// Validation
var validateContext = Organizations.schema.namedContext("updateOrganization");
validateContext.validate({organization_name, address, post_code, city, phone, contact_id});
var invalidKeys = validateContext.invalidKeys();
invalidKeys = _.map(invalidKeys, function (o) { // get error messages
return _.extend({message: validateContext.keyErrorMessage(o.name)}, o);
});
if (validateContext.isValid()) {
// call the server side to update this organization data, we need to pass the data for updating
Meteor.call('organizations.update', organization, this.state, (error)=> {
if (error) {
// console.log(error)
} else {
// should close the expansion (not working) and change row color to normal (working)
this.props.unSelectOrganization(organization);
}
});
} else { // else -> return error msg
this.showErrorMessages(invalidKeys)
}
}
showErrorMessages(invalidKeys) {
var errors = {};
_.map(invalidKeys, (error) => { // mapping errors for each field
errors[error.name] = error.message
});
// console.log(errors);
this.setState({...this.state, errors})
}
handleContactChange(contact_id) {
var errors = {...this.state.errors, contact_id:''};
let contact = Meteor.users.findOne({_id: contact_id});
this.setState({
contact_id,
contact_name: contact ? contact.username : null,
errors
});
}
// handle the change of content of respective <input> caller
// name: is used to refer back which <input> value need to be updated
// event: is used to track the change in value
handleChange(name, event) {
var change = {};
var errors = {...this.state.errors, [name]:''};
change[name] = event.target.value;
change['errors'] = errors;
// console.log(change);
this.setState(change);
}
render() {
const {organization_name, address, post_code, city, phone, contact_id, errors} = this.state;
// console.log(this.state);
return (
<form className="form-inline">
<div className="col-md-10">
<Textfield
widthClass="col-md-3"
label="Organization Name"
labelPlace="top"
value={organization_name}
error={errors.organization_name}
onChange={this.handleChange.bind(this, 'organization_name')}
/>
<Textfield
widthClass="col-md-3"
label="Address"
labelPlace="top"
value={address}
error={errors.address}
onChange={this.handleChange.bind(this, 'address')}
/>
<Textfield
widthClass="col-md-3"
label="Postal Code"
labelPlace="top"
value={post_code}
error={errors.post_code}
onChange={this.handleChange.bind(this, 'post_code')}
/>
<Textfield
widthClass="col-md-3"
label="City"
labelPlace="top"
value={city}
error={errors.city}
onChange={this.handleChange.bind(this, 'city')}
/>
<Textfield
widthClass="col-md-3"
label="Phone"
labelPlace="top"
placeholder="phone"
value={phone}
error={errors.phone}
onChange={this.handleChange.bind(this, 'phone')}
/>
<SearchContacts
widthClass="col-md-3"
label="Contact Name"
labelPlace="top"
value={contact_id}
error={errors.contact_id}
handleSelectChange={this.handleContactChange.bind(this)}
/>
</div>
<div className="col-md-2 align-center">
<div className="btn-trash">
<i className="glyphicon glyphicon-trash"
onClick={this.props.deleteOrganizations.bind(this)}/>
</div>
<button
onClick={this.updateOrganization.bind(this)}
className="btn btn-raised btn-primary">
Save
</button>
</div>
</form>
)
}
}
`
Do you have any suggestion on this? Thank you so much for your time and patience.
Issue Analytics
- State:
- Created 7 years ago
- Reactions:1
- Comments:11 (5 by maintainers)
Top GitHub Comments
@AllenFang Thank you so much for the great work! it’s working fine now! you saved my life!! Gonna close this issue now !
I’ll review this issue again after my business trip, sorry for long fixing…