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

问题描述 投票:2回答:3

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

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

我该如何解决?

javascript reactjs material-ui timepicker material-ui-pickers
3个回答
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
投票

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


2
投票

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

你可以用带有图标的TextField替换示例中的按钮,只有当你点击图标打开TimePicker而不是TimeInput或者你可以使用TimePicker包的material-ui-pickers

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

© www.soinside.com 2019 - 2024. All rights reserved.