Как редактировать время выбора материала-пользовательского времени? - PullRequest
2 голосов
/ 18 апреля 2019

У меня есть 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

Когда я запускаю его, я получаю этот ввод, но когда я редактирую его значение, ввод исчезает.

Как я могу это исправить?

Ответы [ 3 ]

2 голосов
/ 18 апреля 2019

Я думаю, что компонент 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 голосов
/ 18 апреля 2019

Посмотрите на этот пример:
https://mui.wertarbyte.com/#timepicker

Вы можете заменить кнопку в примере на TextField со значком, и только когда вы щелкнете по значку, откройте TimePicker вместо TimeInput или вы можете использовать TimePicker из комплектующих материалов упаковка

Демонстрация материалов-пользовательского интерфейса: https://material -ui-pickers.dev / api / timepicker # ввод с клавиатуры

2 голосов
/ 18 апреля 2019

Один компонент решения был предоставлен в их 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;

Более подробную информацию см. в их официальном руководстве по использованию .

...