我有一个material-ui-time-picker
,我想控制这个输入,它运作良好,但我想编辑键盘输入的时间,而不是我点击时钟输入。
我的代码是:
import React, { Component } from "react";
import { TimePicker } from "material-ui-time-picker";
import { Input as Time, Dialog as Clock } from "@material-ui/core";
openDialog = () => this.setState({ isOpen: true });
closeDialog = () => this.setState({ isOpen: false });
handleDialogTimeChange = newValue => {
const hours = newValue
.getHours()
.toString()
.padStart(2, "0");
const minutes = newValue
.getMinutes()
.toString()
.padStart(2, "0");
const textValue = hours + ":" + minutes;
this.setState({ time: textValue });
};
handleKeyboardTimeChange = time => this.setState({ time });
createDateFromTextValue = value => {
const splitParts = value.split(":");
return new Date(1970, 1, 1, splitParts[0], splitParts[1]);
};
render() {
return (
<div>
<Time
value={this.state.time}
onChange={this.handleKeyboardTimeChange}
endAdornment={
<InputAdornment position="end">
<IconButton onClick={this.openDialog}>
<AccessTime />
</IconButton>
</InputAdornment>
}
//}
/>
<Clock maxWidth="xs" open={this.state.isOpen}>
<TimePicker
mode="24h"
value={this.createDateFromTextValue(this.state.time)}
onChange={this.handleDialogTimeChange}
autoOk={true}
cancelLabel=""
okLabel=""
placeholder=""
disableUnderline={true}
/>
</Clock>
</div>
);
}
我的沙箱:https://codesandbox.io/s/vm9wm19p27
当我运行它时,我得到了这个输入,但是当我编辑它的值时,输入将消失。
我该如何解决?
我认为TimeInput
组件不允许这样做,但您可以编写自己的组件来创建所需的确切行为。而不是从包中导入TimeInput
导入{ TimePicker }
并创建自定义组件。
这绝不是万无一失的,但它将为您提供继续的基础知识。工作示例:https://codesandbox.io/embed/5l167pzrx
import React, { useState } from "react";
import { Button, Input, InputAdornment, IconButton, Dialog, DialogActions } from '@material-ui/core';
import { TimePicker } from 'material-ui-time-picker';
import AccessTime from '@material-ui/icons/AccessTime';
function CustomDatePicker() {
const [isOpen, setIsOpen] = useState(false);
const [value, setValue] = useState('10:10');
const openDialog = () => setIsOpen(true);
const closeDialog = () => setIsOpen(false);
const handleDialogTimeChange = (newValue) => {
const hours = newValue.getHours().toString().padStart(2, "0");
const minutes = newValue.getMinutes().toString().padStart(2, "0")
const textValue = hours + ':' + minutes;
setValue(textValue);
}
const handleKeyboardTimeChange = (event) => setValue(event.target.value);
const createDateFromTextValue = value => {
const splitParts = value.split(':');
return new Date(1970, 1, 1, splitParts[0], splitParts[1]);
}
return (
<div>
<Input
value={value}
onChange={handleKeyboardTimeChange}
endAdornment={
<InputAdornment position="end">
<IconButton onClick={openDialog}>
<AccessTime />
</IconButton>
</InputAdornment>
}
/>
<Dialog maxWidth='xs' open={isOpen}>
<TimePicker mode='24h' value={createDateFromTextValue(value)} onChange={handleDialogTimeChange} />
<DialogActions>
<Button onClick={closeDialog} color='primary'>
Cancel
</Button>
<Button onClick={closeDialog} color='primary'>
Ok
</Button>
</DialogActions>
</Dialog>
</div>
)
}
export default CustomDatePicker
他们的Github repository提供了一个解决方案组件。请检查一下,这是材料-ui已经知道的问题,并且已经被接受为解决方案。这是解决方案,如果链接变得过时:
'use strict';
import React, {Component} from 'react';
import {DatePicker, IconButton, TextField} from "material-ui";
import ActionDateRange from 'material-ui/svg-icons/action/date-range';
import format from 'date-fns/format'
import parse from 'date-fns/parse'
export default class DatePickerField extends Component{
constructor(props){
super(props);
this.state = {
selectedDate: new Date(),
dateText: format(new Date(), 'MM/DD/YYYY')
};
}
handleChangeDatePicker = (event, date) => {
this.setState({selectedDate: date, dateText:format(date, 'MM/DD/YYYY')});
};
handleDateInputChange = (event, value) => {
this.setState({dateText:value});
};
handleDateInputBlur = (value) => {
let parsedDate = parse(value, 'MM/DD/YYYY');
if(this.isADate(parsedDate)){
this.setState({selectedDate:parsedDate});
}
else{
this.setState({dateText:format(this.state.selectedDate, 'MM/DD/YYYY')});
}
};
isADate = (maybeDate) => {
if ( Object.prototype.toString.call(maybeDate) === "[object Date]" ) {
if ( isNaN( maybeDate.getTime() ) ) {
return false;
}
else {
return true;
}
}
else {
return false;
}
};
render(){
let dateInputWidth = "150px";
let datePickerMargin = "-185px";
return (
<div style={{display: "flex"}}>
<TextField
style={{width:dateInputWidth}}
value={this.state.dateText}
onChange={this.handleDateInputChange}
onBlur={(event) => this.handleDateInputBlur(event.currentTarget.value)}
/>
<IconButton style={{opacity:"0.65"}}
onClick={() => this.datePicker.focus()}>
<ActionDateRange />
</IconButton>
<div style={{width:"0px", height:"0px", marginLeft:datePickerMargin}}>
<DatePicker
id="dataPicker"
floatingLabelText={''}
value={this.state.selectedDate}
errorText={''}
disabled={false}
formatDate={date => { return format(date, 'MM/DD/YYYY') } }
autoOk
container="inline"
fullWidth
onChange={this.handleChangeDatePicker}
ref={c => {
this.datePicker = c
}}
/>
</div>
</div>
)
}
}
如果您遇到问题Cannot find prepareStyles of undefined
错误,请检查您是否在任何组件使用之前将主题定义为提供者,否则它将无效。查看此注释:
从v0.15.0开始,Material-UI组件需要提供主题。启动和运行的最快方法是使用MuiThemeProvider将主题注入到应用程序上下文中。
这是展示如何实现这一目标的示例代码段:
在你的App.js中
import React from 'react';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import MyAwesomeReactComponent from './MyAwesomeReactComponent';
const App = () => (
<MuiThemeProvider>
<MyAwesomeReactComponent />
</MuiThemeProvider>
);
ReactDOM.render(
<App />,
document.getElementById('app')
);
在你的./MyAwesomeReactComponent.js
(这是你想要使用的组件):
import React from 'react';
import RaisedButton from 'material-ui/RaisedButton';
const MyAwesomeReactComponent = () => (
<RaisedButton label="Default" />
);
export default MyAwesomeReactComponent;
请参阅他们的official usage guide了解更多详情。
看看这个例子: https://mui.wertarbyte.com/#timepicker
你可以用带有图标的TextField
替换示例中的按钮,只有当你点击图标打开TimePicker
而不是TimeInput
或者你可以使用TimePicker
包的material-ui-pickers
Material-ui-pickers演示:https://material-ui-pickers.dev/api/timepicker#keyboard-input