如何编辑Material-UI-Time-Picker的时间选择器?

时间:2019-04-18 09:03:09

标签: javascript reactjs material-ui timepicker material-ui-pickers

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

答案 0 :(得分:2)

他们的Github repository中提供了一个解决方案组件。请检查一下,这是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;

有关更多详细信息,请参阅其official usage guide

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

您可以在示例中将按钮替换为带有图标的TextField,并且只有单击该图标时,才能打开TimePicker而不是TimeInput,也可以使用{{ TimePicker包中的3}}

Material-ui-pickers演示:material-ui-pickers

答案 3 :(得分:0)

您有2种方法可以执行此操作:

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