Я пытаюсь реализовать группу кнопок в reactjs es6. теперь я взял этот пример https://react-bootstrap.github.io/components/button-group/ с флажком, и я пытаюсь реализовать, но, похоже, он не запускает событие onchange.
class ToggleButtonGroupControlled extends React.Component {
constructor(props, context) {
super(props, context);
//this.handleChangeEvent = this.handleChangeEvent.bind(this);
this.state = {
value: 1
};
}
handleChangeEvent(e) {
console.info(e);
this.setState({ value: e });
}
render() {
return (
<ToggleButtonGroup
type = "radio"
name = "exemption_status_button"
value = {this.state.value}
onChange = {this.handleChangeEvent.bind(this)}
defaultChecked = {this.state.value}
>
<ToggleButton onChange = {this.handleChangeEvent}value = {1} className = "badge2" data-count = {this.props.statusButton.requested}>Requested</ToggleButton>
<ToggleButton onChange = {this.handleChangeEvent}value = {3} className = "badge2" data-count = {this.props.statusButton.accepted}>Accepted</ToggleButton>
<ToggleButton onChange = {this.handleChangeEvent}value = {6} className = "badge2" data-count = {this.props.statusButton.implemented}>Implemented</ToggleButton>
<T
oggleButton onChange = {this.handleChangeEvent}value = {5} className = "badge2" data-count = {this.props.statusButton.cancelled}>Cancelled</ToggleButton>
<ToggleButton onChange = {this.handleChangeEvent}value = {4} className = "badge2" data-count = {this.props.statusButton.rejected}>Rejected</ToggleButton>
</ToggleButtonGroup>
);
}
}
у меня это работает следующим образом. Мне пришлось использовать jquery для извлечения значения и использования функций возврата.
import _ from 'lodash';
import axios from 'axios';
import React, { Component } from 'react';
import { Checkbox } from 'react-bootstrap';
import { connect } from 'react-redux';
import {
fetchSecurityExemptions,
fetchSecurityExemptionsCount,
fetchMarkets,
fetchServiceDomains,
fetchServicesList,
fetchSecurityEngineerList,
fetchBusinessPriorityList,
updateSecurityExemption
} from '../../actions/security';
import { bindActionCreators } from 'redux';
import { Button, ButtonToolbar, Modal, Tooltip, OverlayTrigger, ToggleButton, ToggleButtonGroup } from 'react-bootstrap';
import FontAwesome from 'react-fontawesome';
import { BootstrapTable, TableHeaderColumn, InsertModalHeader, InsertModalFooter, SearchField } from 'react-bootstrap-table';
import 'react-bootstrap-table/dist/react-bootstrap-table-all.min.css';
import $ from 'jquery';
import ModalError from '../modalerror';
import ModalConfirm from '../modalconfirm';
import { Link } from 'react-router-dom';
import { isGenericName } from '../../scripts/validation';
class ToggleButtonGroupControlled extends Component {
constructor(props, context) {
super(props, context);
this.handleChangeEvent = this.handleChangeEvent.bind(this);
this.value = 1
}
handleChangeEvent(e) {
this.value = $(e.target).children('input').val();
this.passStatusButtonBack();
}
passStatusButtonBack(){
this.props.passStatusButtonBack(this.value);
}
render() {
return (
<ButtonToolbar>
<ToggleButtonGroup
type = "radio"
name = "exemption_status_button"
value = {this.value}
onChange = {this.handleChangeEvent}
defaultChecked = {this.value}
>
<ToggleButton onClick = {this.handleChangeEvent}value = {1} className = "badge2" data-count = {this.props.statusButton.requested}>Requested</ToggleButton>
<ToggleButton onClick = {this.handleChangeEvent}value = {3} className = "badge2" data-count = {this.props.statusButton.accepted}>Accepted</ToggleButton>
<ToggleButton onClick = {this.handleChangeEvent}value = {6} className = "badge2" data-count = {this.props.statusButton.implemented}>Implemented</ToggleButton>
<ToggleButton onClick = {this.handleChangeEvent}value = {5} className = "badge2" data-count = {this.props.statusButton.cancelled}>Cancelled</ToggleButton>
<ToggleButton onClick = {this.handleChangeEvent}value = {4} className = "badge2" data-count = {this.props.statusButton.rejected}>Rejected</ToggleButton>
</ToggleButtonGroup>
</ButtonToolbar>
);
}
}
class SecurityExemptions extends Component {
constructor(props) {
super(props);
this.securityExemptions = [];
this.state = {
viewport: {
width: window.innerWidth,
height: window.innerHeight
},
data: [],
show: false,
showError: false,
errorMsg: '',
errorTitle: '',
confirm: {
body: '',
show: false,
id: '',
next: null
},
totalDataSize: 0,
currentPage: 1,
statusButton: {value: 1, requested: 0, accepted: 0, implemented: 0, cancelled:0, rejected: 0}
};
this.where = [];
this.sort = 'id desc';
this.meta = { title: '', description: 'Lists and manages security exemptions' };
this.options = {
noDataText: 'Loading...',
defaultSortName: 'id',
defaultSortOrder: 'desc',
page: 1,
paginationShowsTotal: true,
sizePerPage: 50,
sizePerPageList: [10, 25, 50, 100, 250],
onPageChange: this.onPageChange.bind(this),
onSizePerPageList: this.onSizePerPageList.bind(this),
onFilterChange: this.onFilterChange.bind(this),
onSortChange: this.onSortChange.bind(this),
selectRowProp: {
mode: 'checkbox',
clickToSelect: true,
onSelect: this.handleRowSelect,
customComponent: this.customMultiSelect.bind(this)
},
cellEditProp: {
mode: 'click',
blurToSave: true,
afterDeleteRow: this.onAfterDeleteRow.bind(this),
afterSaveCell: this.onAfterSaveCell.bind(this),
nonEditableRows: function() {
return this.state.data.filter(row => row.exemption_status_id != 1 ).map(row => row.id);
}.bind(this)
},
handleConfirmDeleteRow: this.customConfirm.bind(this),
btnGroup: this.createCustomButtonGroup.bind(this),
deleteBtn: this.createCustomDeleteButton.bind(this),
onSearchChange: this.onSearchChange.bind(this),
searchField: this.createCustomSearchField
};
this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
this.handleShowError = this.handleShowError.bind(this);
this.fetchSecurityExemptions = this.fetchSecurityExemptions.bind(this);
this.handlestatusButtonChange = this.handlestatusButtonChange.bind(this);
this.runOnce = false;
this.passStatusButtonBack = this.passStatusButtonBack.bind(this)
this.markets = [];
this.serviceDomain = [];
this.servicesList = [];
this.servicesListDisplay = [];
this.securityEngineerList = [];
this.businessPriority = []
}
passStatusButtonBack(status){
let statusButton = this.state.statusButton;
statusButton.value = status;
this.setState({ statusButton });
this.where.exemption_status_id = status;
this.fetchSecurityExemptions(this.options.page, this.options.sizePerPage, this.where, this.sort);
}
passMetaBack = () => {
this.props.passMetaBack(this.meta);
};
createCustomButtonGroup = props => {
return (
<ButtonGroup className = "my-custom-class" sizeClass = "btn-group-md">
{props.insertBtn}
{props.deleteBtn}
<ExemptionStatusButtons self = {this} />
<ToggleButtonGroupControlled statusButton = {this.state.statusButton} passStatusButtonBack = {this.passStatusButtonBack}/>
</ButtonGroup>
);
};
componentDidMount() {
this.passMetaBack();
this.updateWindowDimensions();
window.addEventListener('resize', this.updateWindowDimensions);
}
componentWillUnmount() {
window.removeEventListener('resize', this.updateWindowDimensions);
}
renderTable(tableData) {
let insertRow = false;
let deleteRow = false;
return (
<div className = "container-fluid">
<div className = "row-fluid">
<BootstrapTable
data = {tableData}
remote
search
fetchInfo = {{ dataTotalSize: this.state.totalDataSize }}
options = {this.options}
pagination
striped
hover
tableHeaderClass = "table-vf thead"
tableContainerClass = "securityExemptions"
insertRow = {insertRow}
cellEdit = {this.options.cellEditProp}
deleteRow = {deleteRow}
selectRow = {this.options.selectRowProp}
maxHeight = {this.state.viewport.height * 0.66}
ref = "table"
>
<TableHeaderColumn dataField = "id" isKey = {true} editable = {false} hiddenOnInsert width = {`60px`} dataFormat = {this.exemptionsLink}>
ID
</TableHeaderColumn>
<TableHeaderColumn dataField = "hits" editable = {false} hiddenOnInsert width = {`50px`}>
Hits
</TableHeaderColumn>
<TableHeaderColumn dataField = "market" width = {`150px`} formatExtraData = {this.markets} editable = {{ type: 'select', options: { values: this.markets } }}>
Market
</TableHeaderColumn>
<TableHeaderColumn dataField = "service_domain" width = {`150px`} formatExtraData = {this.serviceDomain} editable = {{ type: 'select', options: { values: this.serviceDomain } }}>
Service Domain
</TableHeaderColumn>
<TableHeaderColumn dataField = "service_id" width = {`200px`} editable = {false} dataFormat = {this.serviceFormatter}>
Service / Project / Programme
</TableHeaderColumn>
<TableHeaderColumn dataField = "demand_ref" width = {`70px`} editable = {{ type: 'text', validator: this.isGenericName }}>
Demand ID
</TableHeaderColumn>
<TableHeaderColumn dataField = "summary" width = {`200px`} editable = {false}>
Summary
</TableHeaderColumn>
<TableHeaderColumn dataField = "filename" width = {`200px`} dataFormat = {this.commsMatrixLink} editable = {false}>
Commsmatrix
</TableHeaderColumn>
<TableHeaderColumn dataField = "business_priority" width = {`100px`} formatExtraData = {this.businessPriority} editable = {{ type: 'select', options: { values: this.businessPriority } }}>
Priority
</TableHeaderColumn>
<TableHeaderColumn dataField = "expiry_date" width = {`150px`} editable = {true}>
Expiry
</TableHeaderColumn>
<TableHeaderColumn dataField = "security_engineer" width = {`200px`} dataFormat = {this.htmlFormatter} formatExtraData = {this.securityEngineerList} editable = {{ type: 'select', options: { values: this.securityEngineerList } }}>
Security Engineer
</TableHeaderColumn>
<TableHeaderColumn dataField = "ts_created" width = {`130px`} editable = {false} hiddenOnInsert>
Requested
</TableHeaderColumn>
<TableHeaderColumn dataField = "created_by" width = {`110px`} editable = {false} hiddenOnInsert>
Requested By
</TableHeaderColumn>
</BootstrapTable>
</div>
</div>
);
}
render() {
const { securityExemptions } = this.props;
if (!this.runOnce && this.props.isReady && this.securityExemptions.length == 0) {
this.runOnce = true;
this.where = {exemption_status_id : this.state.statusButton.value};
this.initData();
}
let table = (
<div>
Loading...<i className = "fa fa-spinner fa-spin" />
</div>
);
if (this.state.show) {
table = this.renderTable(this.state.data);
this.moveElement();
}
return (
<div className = "container-fluid">
<div className = "row-fluid top-buffer">{table}</div>
<ModalConfirm body = {this.state.confirm.body} show = {this.state.confirm.show} id = {this.state.confirm.id} handleConfirmYes = {this.handleConfirmYes} handleConfirmNo = {this.handleConfirmNo} />
<ModalError title = {this.state.errorTitle} body = {this.state.errorMsg} show = {this.state.showError} handleCloseError = {this.handleCloseError} />
</div>
);
}
}
function mapStateToProps(state) {
return {
securityExemptions: state.securityExemptions,
listsReducer: state.listsReducer
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
fetchSecurityExemptions,
fetchSecurityExemptionsCount,
fetchMarkets,
fetchServiceDomains,
fetchServicesList,
fetchSecurityEngineerList,
fetchBusinessPriorityList,
updateSecurityExemption
},
dispatch
);
}
экспортировать соединение по умолчанию (mapStateToProps, mapDispatchToProps) (SecurityExemptions);
}





Согласно документации onChange следует указывать на компоненте ToggleButtonGroup, а не на компоненте ToggleButton,
<ToggleButtonGroup
type = "checkbox"
value = {this.state.value}
onChange = {this.handleChangeEvent}
>
<ToggleButton value = {1}>Checkbox 1 (pre-checked)</ToggleButton>
<ToggleButton value = {2}>Checkbox 2</ToggleButton>
<ToggleButton value = {3}>Checkbox 3 (pre-checked)</ToggleButton>
<ToggleButton value = {4} disabled>
Checkbox 4 (disabled)
</ToggleButton>
</ToggleButtonGroup>
Обновлено: если это не сработает, вы всегда можете использовать,
handleClick = (e)=>{
console.info(e.target.value)
}
<ToggleButton onClick = {this.handleClick}value = {1} className = "badge2" data-count = {this.props.statusButton.requested}>Requested</ToggleButton>
Вы пробовали после удаления onchange из ToggleButton ??
Я добавил еще один метод
@ Shortif2000 А вторым способом пробовали? с помощью onclick?
У меня есть
onChangeнаToggleButtonGroup, но он не работает, еслиtypeявляется радио.