如何编辑material-ui-时间选择器的时间选择器?

How to edit the time picker of material-ui-time-picker?

我有一个 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

当我运行它的时候,我得到了这个输入,但是当我编辑他的值时,这个输入就会消失。

我该如何解决?

他们的 Github repository 中提供了一个解决方案组件。请检查一下,这是 material-ui 的一个已知问题,并且已经被接受为 solution.This 是提供的解决方案,以防 link 变得过时:

'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错误,请检查您是否在使用任何组件之前将主题定义为提供者,否则将无法运行。检查此注释:

Beginning with v0.15.0, Material-UI components require a theme to be provided. The quickest way to get up and running is by using the MuiThemeProvider to inject the theme into your application context.

这是展示如何完成该操作的示例片段:

在你的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了解更多详情。

我认为 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

看这个例子:
https://mui.wertarbyte.com/#timepicker

您可以将示例中的按钮替换为带图标的 TextField,并且仅当您单击该图标时才会打开 TimePicker instead of TimeInput or you can use the TimePicker of the material-ui-pickers

Material-ui-选择器演示:https://material-ui-pickers.dev/api/timepicker#keyboard-input

您有 2 个选择:

  1. 使用<KeyboardTimePicker />
  2. 使用<KeyboardDateTimePicker />