我使用了 prime-react 的可编辑数据表,它可以通过鼠标单击。但问题是制表键不起作用。我想使用制表键启用一个单元格到另一个单元格的可编辑模式。我使用 Prime 反应版本 1.4.0
完整代码如下:-
我的可编辑表格代码包含的index.js
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { FormattedMessage } from 'react-intl';
import { createStructuredSelector } from 'reselect';
import { compose } from 'redux';
import injectSaga from 'utils/injectSaga';
import injectReducer from 'utils/injectReducer';
import reducer from './reducer';
import saga from './saga';
import messages from './messages';
import { Messages } from 'primereact/components/messages/Messages';
import { Growl } from 'primereact/components/growl/Growl';
import { Panel } from 'primereact/components/panel/Panel';
import { Button } from 'primereact/components/button/Button';
import { DataTable } from 'primereact/components/datatable/DataTable';
import { Column } from 'primereact/components/column/Column';
import { InputText } from 'primereact/components/inputtext/InputText';
import { Dropdown } from 'primereact/components/dropdown/Dropdown';
import CustomDataTable from 'components/CustomDataTable';
import { makeSelectSelectedStudent, makeSelectSectionName, makeSelectStudentUpdateBasicInformation, makeSelectSectionList, makeSelectStdBasicInfo, makeSelectEditorStudent, makeSelectSetMessage, makeSelectSetErrMessage, makeSelectLoaderOff, makeSelectLoaderOn } from './selectors';
import { selectStudent, setEditorData, submitUpdate, getMessage, getErrMessage, submitForm, changeSectionName, getLoaderOn, getLoaderOff } from './actions';
import AppPrivateLayout from '../AppPrivateLayout';
export class StudentUpdateBasicInformation extends React.Component {
componentDidUpdate() {
this.props.changeMessage('');
}
rollBody(rowData) {
return <InputText type="text" value={rowData.studentRoll} />;
}
nameBody(rowData) {
return <InputText type="text" value={rowData.studentName} />;
}
fatherNameBody(rowData) {
return <InputText type="text" value={rowData.fatherName} />;
}
motherNameBody(rowData) {
return <InputText type="text" value={rowData.motherName} />;
}
contactBody(rowData) {
return <InputText type="text" value={rowData.guardianMobile} />;
}
genderBody(rowData) {
let gender = [
{ label: 'Male', value: 'Male' },
{ label: 'Female', value: 'Female' },
{ label: 'Others', value: 'Others' }
];
return <Dropdown value={rowData.studentGender} options={gender} style={{ width: '100%' }} placeholder="Select" />
}
religionBody(rowData) {
let religion = [
{ label: 'Islam', value: 'Islam' },
{ label: 'Hindu', value: 'Hindu' },
{ label: 'Buddhist', value: 'Buddhist' },
{ label: 'Christian', value: 'Christian' },
{ label: 'Others', value: 'Others' }
];
return <Dropdown value={rowData.studentReligion} options={religion} style={{ width: '100%' }} placeholder="Select" />
}
bloodBody(rowData) {
let blood = [
{ label: 'A+', value: 'A+' },
{ label: 'A-', value: 'A-' },
{ label: 'B+', value: 'B+' },
{ label: 'B-', value: 'B-' },
{ label: 'O+', value: 'O+' },
{ label: 'O-', value: 'O-' }
];
return <Dropdown value={rowData.bloodGroup} options={blood} style={{ width: '100%' }} placeholder="Select" />
}
render() {
let rollEditor = (row) => {
return <InputText onChange={(evt) => { this.props.onEditorValueChange(row, evt.target.value); }} placeholder="Roll" value={row.rowData.studentRoll} />
}
let nameEditor = (row) => {
return <InputText onChange={(evt) => { this.props.onEditorValueChange(row, evt.target.value); }} placeholder="Student name" value={row.rowData.studentName} />
}
let fatherNameEditor = (row) => {
return <InputText onChange={(evt) => { this.props.onEditorValueChange(row, evt.target.value); }} placeholder="Father name" value={row.rowData.fatherName} />
}
let motherNameEditor = (row) => {
return <InputText onChange={(evt) => { this.props.onEditorValueChange(row, evt.target.value); }} placeholder="Mother name" value={row.rowData.motherName} />
}
let contactEditor = (row) => {
return <InputText onChange={(evt) => { this.props.onEditorValueChange(row, evt.target.value); }} placeholder="Contact Number" value={row.rowData.guardianMobile} />
}
let genderEditor = (row) => {
let gender = [
{ label: 'Male', value: 'Male' },
{ label: 'Female', value: 'Female' },
{ label: 'Others', value: 'Others' }
];
return <Dropdown value={row.rowData.gender} options={gender} onChange={(evt) => this.props.onEditorValueChange(row, evt.value)} style={{ width: '100%' }} placeholder="Select" />
}
let religionEditor = (row) => {
let religion = [
{ label: 'Islam', value: 'Islam' },
{ label: 'Hindu', value: 'Hindu' },
{ label: 'Buddhist', value: 'Buddhist' },
{ label: 'Christian', value: 'Christian' },
{ label: 'Others', value: 'Others' }
];
return <Dropdown value={row.rowData.religion} options={religion} onChange={(evt) => { this.props.onEditorValueChange(row, evt.value); }} style={{ width: '100%' }} placeholder="Select" />
}
let bloodEditor = (row) => {
let blood = [
{ label: 'A+', value: 'A+' },
{ label: 'A-', value: 'A-' },
{ label: 'B+', value: 'B+' },
{ label: 'B-', value: 'B-' },
{ label: 'O+', value: 'O+' },
{ label: 'O-', value: 'O-' }
];
return <Dropdown value={row.rowData.blood} options={blood} onChange={(evt) => { this.props.onEditorValueChange(row, evt.value); }} style={{ width: '100%' }} placeholder="Select" />
}
let msg = "";
if (this.props.setMessage) {
msg = { severity: 'success', detail: this.props.setMessage.message };
this.growl.show(msg);
}
else if (this.props.setErrMessage) {
msg = { severity: 'error', summary: 'Failed', detail: this.props.setErrMessage };
this.growl.show(msg);
}
if(this.props.loaderOn){
if(this.props.loaderOn === 'On') {
$('.loaderDiv').show();
} else if(this.props.loaderOn === 'Off'){
$('.loaderDiv').hide();
}
}
let content = '';
if (this.props.stdBasicInfo && this.props.stdBasicInfo.length) {
$('#UpdateBtnID').show();
let selectedStudentArr = [];
if (this.props.selectedStudent.length) {
Array.prototype.push.apply(selectedStudentArr, this.props.selectedStudent);
}
let columnData = [
<Column selectionMode="multiple" header="Mark" style={{ width: '3em' }} />,
<Column field="studentRoll" header="Roll No." editor={rollEditor} body={this.rollBody} style={{ width: '55px' }} />,
<Column field="studentName" header="Name" editor={nameEditor} body={this.nameBody} style={{ width: '170px' }} />,
<Column field="fatherName" header="Father Name" editor={fatherNameEditor} body={this.fatherNameBody} style={{ width: '145px' }} />,
<Column field="motherName" header="Mother Name" editor={motherNameEditor} body={this.motherNameBody} style={{ width: '145px' }} />,
<Column field="guardianMobile" header="Contact No." editor={contactEditor} style={{ width: '100px' }} body={this.contactBody} />,
<Column field="studentGender" header="Gender" editor={genderEditor} body={this.genderBody} style={{ width: '85px' }} />,
<Column field="studentReligion" header="Religion" editor={religionEditor} body={this.religionBody} style={{ width: '85px' }} />,
<Column field="bloodGroup" header="Blood Group" editor={bloodEditor} style={{ width: '80px' }} body={this.bloodBody} />
];
content = <CustomDataTable
info={this.props.stdBasicInfo}
onSelectionChange={this.props.onSelectionChange}
selectedData={selectedStudentArr}
columnData={columnData}
isSelectionOn={true}
editable={true}
header={'Student List'}
rows={10}
/>
}
//FOR SECTION LIST
let sectionListOptions = [];
if (this.props.sectionList && this.props.sectionList.length) {
sectionListOptions = this.props.sectionList.map((item) => ({
value: item.classConfigId,
label: item.classShiftSection,
}))
}
return (
<div>
<AppPrivateLayout>
<Panel header="Student Information Update">
<form method="post" onSubmit={this.props.onSubmitForm} >
<div className='ui-g form-group'>
<div className='ui-g-2 ui-lg-2 ui-md-2'></div>
<div className='ui-g-2 ui-lg-2 ui-md-2 ui-sm-12 netiLabel'>
<label> Section <span className="required"> * </span></label>
</div>
<div className='ui-g-3 ui-lg-3 ui-md-4 ui-sm-12 ui-fluid'>
<Dropdown value={this.props.sectionname} onChange={this.props.onChangeSectionList} options={sectionListOptions} placeholder="Select Section" autoWidth={false} />
</div>
<div className='ui-g-2 ui-lg-2 ui-md-3 ui-sm-12 ui-fluid'>
<Button icon="ui-icon-search" title="Search" label='Search'></Button>
</div>
<div className='ui-g-2 ui-lg-2 ui-fluid'></div>
</div>
</form>
{content}
<div className='ui-g'>
<Growl ref={(el) => this.growl = el} />
<div className='ui-g-4 ui-lg-4 ui-md-4 ui-sm-12 ui-fluid'>
</div>
<div className='ui-g-6 ui-lg-6 ui-md-5 ui-sm-12 ui-fluid'></div>
<div className='ui-g-2 ui-lg-2 ui-md-3 ui-sm-12 ui-fluid'>
<Button id="UpdateBtnID" style={{ display: 'none' }} onClick={this.props.onUpdate} icon='ui-icon-autorenew' label='Update'></Button>
</div>
</div>
</Panel>
<div class="loaderDiv" style={{display: 'none'}}>
<img className="sticky" src="https://loading.io/spinners/harmony/lg.harmony-taiji-spinner.gif" />
</div>
</AppPrivateLayout>
</div>
);
}
}
StudentUpdateBasicInformation.propTypes = {
stdBasicInfo: PropTypes.any,
onSubmitForm: PropTypes.func,
onEditorValueChange: PropTypes.func,
value: PropTypes.any,
onUpdate: PropTypes.func,
setMessage: PropTypes.any,
setErrMessage: PropTypes.any,
changeMessage: PropTypes.func,
sectionList: PropTypes.any,
onChangeSectionList: PropTypes.func,
sectionname: PropTypes.any,
loaderOn: PropTypes.any,
};
const mapStateToProps = createStructuredSelector({
stdBasicInfo: makeSelectStdBasicInfo(),
selectedStudent: makeSelectSelectedStudent(),
value: makeSelectEditorStudent(),
setMessage: makeSelectSetMessage(),
setErrMessage: makeSelectSetErrMessage(),
sectionList: makeSelectSectionList(),
sectionname: makeSelectSectionName(),
loaderOn: makeSelectLoaderOn(),
});
function mapDispatchToProps(dispatch) {
return {
changeMessage: (evt) => {
dispatch(getMessage());
dispatch(getErrMessage());
dispatch(getLoaderOn(evt));
},
onSubmitForm: (evt) => {
if (evt !== undefined && evt.preventDefault)
evt.preventDefault();
dispatch(submitForm());
},
onSelectionChange: (evt) => dispatch(selectStudent(evt.data)),
onEditorValueChange: (row, value) => {
dispatch(setEditorData(row, value));
},
onUpdate: (evt) => dispatch(submitUpdate()),
onChangeSectionList: (evt) => dispatch(changeSectionName(evt.value)),
};
}
const withConnect = connect(mapStateToProps, mapDispatchToProps);
const withReducer = injectReducer({ key: 'studentUpdateBasicInformation', reducer });
const withSaga = injectSaga({ key: 'studentUpdateBasicInformation', saga });
export default compose(
withReducer,
withSaga,
withConnect,
)(StudentUpdateBasicInformation);
常量.js
export const DEFAULT_ACTION = 'app/StudentUpdateBasicInformation/DEFAULT_ACTION';
export const SUBMIT_FORM = 'app/StudentUpdateBasicInformation/SUBMIT_FORM';
export const SET_STD_BASIC_INFO = 'app/StudentUpdateBasicInformation/SET_STD_BASIC_INFO';
export const SELECT_STUDENT = 'app/StudentUpdateBasicInformation/SELECT_STUDENT';
export const SET_EDITOR_DATA = 'app/StudentUpdateBasicInformation/SET_EDITOR_DATA';
export const GET_MESSAGE = 'app/StudentUpdateStudentId/GET_MESSAGE';
export const GET_ERR_MESSAGE = 'app/StudentUpdateStudentId/GET_ERR_MESSAGE';
export const SUBMIT_UPDATE = 'app/StudentUpdateBasicInformation/SUBMIT_UPDATE';
export const SET_SECTION_LIST = 'app/StudentUpdateBasicInformation/SET_SECTION_LIST';
export const CHANGE_SECTIONNAME = 'app/StudentUpdateBasicInformation/CHANGE_SECTIONNAME';
export const GET_LOADER_ON = 'app/StudentUpdateBasicInformation/GET_LOADER_ON';
动作.js
import {
DEFAULT_ACTION, SUBMIT_FORM, SET_STD_BASIC_INFO, SELECT_STUDENT, SET_EDITOR_DATA, SUBMIT_UPDATE, GET_MESSAGE, GET_ERR_MESSAGE, CHANGE_SECTIONNAME, SET_SECTION_LIST, GET_LOADER_OFF, GET_LOADER_ON
} from './constants';
export function defaultAction() {
return {
type: DEFAULT_ACTION,
};
}
export function setStdBasicInfo(item) {
return {
type: SET_STD_BASIC_INFO,
item,
}
}
export function selectStudent(data) {
return {
type: SELECT_STUDENT,
data,
};
}
export function setEditorData(row, value) {
return {
type: SET_EDITOR_DATA,
row,
value,
};
}
export function submitForm() {
return {
type: SUBMIT_FORM,
};
}
export function submitUpdate() {
return {
type: SUBMIT_UPDATE,
};
}
export function getMessage(message) {
return {
type: GET_MESSAGE,
message,
}
}
export function getErrMessage(errmessage) {
return {
type: GET_ERR_MESSAGE,
errmessage,
}
}
export function setSectionList(sectionList) {
return {
type: SET_SECTION_LIST,
sectionList,
};
}
export function changeSectionName(sectionname) {
return {
type: CHANGE_SECTIONNAME,
sectionname,
};
}
export function getLoaderOn(loaderOn){
return{
type: GET_LOADER_ON,
loaderOn,
}
}
减速器.js
import { fromJS } from 'immutable';
import {
DEFAULT_ACTION, SET_STD_BASIC_INFO, SELECT_STUDENT, SET_EDITOR_DATA, GET_MESSAGE, GET_ERR_MESSAGE, SET_SECTION_LIST, CHANGE_SECTIONNAME, GET_LOADER_ON, GET_LOADER_OFF
} from './constants';
const initialState = fromJS({
selectedStudent: [],
value: [],
sectionList: {},
sectionname: '',
});
function studentUpdateBasicInformationReducer(state = initialState, action) {
switch (action.type) {
case DEFAULT_ACTION:
return state;
case SET_STD_BASIC_INFO:
return state.set('stdBasicInfo', action.item);
case SELECT_STUDENT:
return state.set('selectedStudent', action.data);
case SET_EDITOR_DATA:
let updatedInfost = [...action.row.value];
updatedInfost = [...action.row.value];
updatedInfost[action.row.rowIndex][action.row.field] = action.value;
return state.set('stdBasicInfo', updatedInfost);
case GET_MESSAGE:
return state.set('setMessage', action.message);
case GET_ERR_MESSAGE:
return state.set('setErrMessage', action.errmessage);
case SET_SECTION_LIST:
return state.set('sectionList', action.sectionList);
case CHANGE_SECTIONNAME:
return state.set('sectionname', action.sectionname);
case GET_LOADER_ON:
return state.set('loaderOn', action.loaderOn);
// case GET_LOADER_OFF:
// return state.set('loaderOff', action.loaderOff);
default:
return state;
}
}
export default studentUpdateBasicInformationReducer;
选择器.js
import { createSelector } from 'reselect';
const selectStudentUpdateBasicInformationDomain = (state) => state.get('studentUpdateBasicInformation');
const makeSelectStudentUpdateBasicInformation = () => createSelector(
selectStudentUpdateBasicInformationDomain,
(substate) => substate.toJS()
);
const makeSelectStdBasicInfo = () => createSelector(selectStudentUpdateBasicInformationDomain, (abc) => abc.get('stdBasicInfo'));
const makeSelectSelectedStudent = () => createSelector(selectStudentUpdateBasicInformationDomain, (substate) => substate.get('selectedStudent'));
const makeSelectEditorStudent = () => createSelector(selectStudentUpdateBasicInformationDomain, (substate) => substate.get('value'));
const makeSelectSetMessage = () => createSelector(selectStudentUpdateBasicInformationDomain, (abc) => abc.get('setMessage'));
const makeSelectSetErrMessage = () => createSelector(selectStudentUpdateBasicInformationDomain, (abc) => abc.get('setErrMessage'));
const makeSelectSectionName = () => createSelector(selectStudentUpdateBasicInformationDomain, (abc) => abc.get('sectionname'));
const makeSelectSectionList = () => createSelector(selectStudentUpdateBasicInformationDomain,(substate) => substate.get('sectionList'));
const makeSelectLoaderOn = () => createSelector(selectStudentUpdateBasicInformationDomain, (substate) => substate.get('loaderOn'));
export {
selectStudentUpdateBasicInformationDomain,
makeSelectStdBasicInfo,
makeSelectSelectedStudent,
makeSelectEditorStudent,
makeSelectSetMessage,
makeSelectSetErrMessage, makeSelectSectionName, makeSelectSectionList, makeSelectLoaderOn,
//makeSelectLoaderOff
};
传奇.js
import { take, call, put, select, takeLatest } from 'redux-saga/effects';
import { BASE_URL, FETCH_BASIC_INFO_LIST, UPDATE_ID, GET_CLASS_CONFIGURATION_URL, STUDENT_CONFIG_LIST } from '../../utils/serviceUrl';
import { setStdBasicInfo, getMessage, getErrMessage, selectStudent, setSectionList, changeSectionName, getLoaderOn } from './actions';
import request from '../../utils/request';
import { SUBMIT_FORM, SUBMIT_UPDATE } from './constants';
import { makeSelectEditorStudent, makeSelectSelectedStudent, makeSelectSectionList, makeSelectSectionName } from './selectors';
import { getTokenData } from '../../utils/authHelper';
//FOR SECTION LIST
export function* fetchSectionList() {
const tokenData = JSON.parse(getTokenData());
const requestUrl = BASE_URL.concat(GET_CLASS_CONFIGURATION_URL);
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': tokenData.token_type+" "+tokenData.access_token,
},
};
try {
const response = yield call(request, requestUrl, options);
if (response.item) {
yield put(setSectionList(response.item));
}
} catch (err) {
console.dir(err);
}
}
//FOR STUDENT BASIC INFO LIST
export function* fetchStudentBasicInfoList() {
const tokenData = JSON.parse(getTokenData());
const classConfigId = yield select(makeSelectSectionName());
let msgg;
if (classConfigId == '') {
let msg = "An error has occured. Please fill up all required fields";
yield put(getErrMessage(msg));
}
else {
msgg = 'On';
yield put(getLoaderOn(msgg));
const requestURL = BASE_URL.concat(STUDENT_CONFIG_LIST).concat('?classConfigId=').concat(classConfigId);
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': tokenData.token_type+" "+tokenData.access_token,
},
};
const info = yield call(request, requestURL,options);
yield put(setStdBasicInfo(info.item));
msgg = 'Off';
yield put(getLoaderOn(msgg));
}
}
//FOR UPDATE STUDENT INFORMATION
export function* updateStdBasicInfo() {
const tokenData = JSON.parse(getTokenData());
const selectedCheckData = yield select(makeSelectSelectedStudent());
let selectedData = [];
if (selectedCheckData.length === undefined || selectedCheckData.length === 0) {
const errresult = "An error has occured. Please fill up all required fields";
yield put(getErrMessage(errresult));
} else {
for (const i in selectedCheckData) {
const DataList = selectedCheckData[i];
selectedData.push(DataList);
}
const requestURL = BASE_URL.concat(UPDATE_ID);
const options = {
method: 'PUT',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': tokenData.token_type+" "+tokenData.access_token,
},
body: JSON.stringify(selectedData),
}
try {
const result = yield call(request, requestURL, options);
yield put(selectStudent([]));
yield fetchStudentBasicInfoList();
yield put(getMessage(result));
} catch (err) {
const errresult = "Something went wrong. Please try again.";
yield put(setStdBasicInfo(info.item));
yield put(getErrMessage(errresult));
}
}
}
export default function* defaultSaga() {
yield fetchSectionList();
yield takeLatest(SUBMIT_FORM, fetchStudentBasicInfoList);
yield takeLatest(SUBMIT_UPDATE, updateStdBasicInfo);
}