Как редактировать время выбора материала-пользовательского времени?
У меня есть 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
Когда я запускаю его, я получаю этот ввод, но когда я редактирую его значение, ввод исчезнет.
Как я могу это исправить?
4 ответа
Я думаю 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. Пожалуйста, проверьте это, это уже известная проблема с material-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;
Пожалуйста, обратитесь к их официальному руководству по использованию для получения дополнительной информации.
Посмотрите на этот пример:
https://mui.wertarbyte.com/
Вы можете заменить кнопку в примере на TextField
со значком и только при нажатии на значок открывать TimePicker
вместо TimeInput
или вы можете использовать TimePicker
пакета материалов-пользовательского интерфейса
Демонстрация материалов и пользовательского интерфейса: https://material-ui-pickers.dev/api/timepicker
У вас есть 2 варианта сделать это:
- использовать
<KeyboardTimePicker />
- использовать
<KeyboardDateTimePicker />