web-dev-qa-db-ja.com

ReactでMaterialize-CSSの日付ピッカー値を正しくキャプチャするにはどうすればよいですか?

私は datepicker を使用してフォームを作成しようとしていますReact with materialize-css を含むコンポーネントです。これは多くのフィールドがありませんフォームはキャプチャしており、構造はかなり単純です。返されるフォームは次のようになります。

<form onSubmit={this.handleSubmit.bind(this)}>
     <div className="container">
          <div className="card grey lighten-3">
               <div className="card-content black-text">
                    <span className="card-title">
                            <input placeholder="Event Name"
                                    name="name" value={this.state.name}
                                    onChange={this.handleStateChange.bind(this)}/>
                    </span>
                    <input name="description" placeholder="Description"
                                      value={this.state.description}
                                      onChange={this.handleStateChange.bind(this)}/>
                    <input name="image" placeholder="Image URL"
                                      value={this.state.image}
                                      onChange={this.handleStateChange.bind(this)}/>
                    <input placeholder="Start Date"
                                className="datepicker" name="startDate" value={this.state.startDate}
                                onSelect={this.handleStateChange.bind(this)}/>
                </div>
                <div class="card-action">
                    <div className="row">
                        <span>
                           <div className="col s3">
                               <input className="btn light-blue accent-1" type="submit" value="Submit"/>
                           </div>
                           <div className="col s3">
                               <a className="btn grey" onClick={this.handleExpand.bind(this)}>Cancel</a>
                           </div>
                       </span>
                   </div>
               </div>
           </div>
       </div>
   </form>

状態の変化は

handleStateChange(item) {
    this.setState({[item.target.name]: item.target.value});
}

私は AutoInit を呼び出して、日付ピッカーを初期化しました

M.AutoInit();

onChangeの代わりにonSelectを使用して日付ピッカーの状態変更を管理しようとしましたが、そのイベントはキャプチャされないようです。 onSelectを使用すると、日付を選択してから日付ピッカーを再度開くと、日付がキャプチャされることがあります。

datepickerの代替初期化メソッド をいくつか使用してみましたが、役に立ちませんでした。

特定のセットアップで入力の変更を正しくキャプチャするにはどうすればよいですか?

10
Matt

こんにちはうまくいけば、これは誰かを助けるでしょう-

<DatePicker />コンポーネントで発生するのは、デフォルトのonChangeメソッドが要素のイベントハンドラーオブジェクトではなく日付(2019-08-01)を返すことです。これに対処するには、イベントハンドラーのtarget.idとtarget.valueを模倣するonChangeメソッド内にオブジェクトを作成する必要があります。

<input />のような他のコンポーネントは、通常どおり機能します。見てみな:

コンポーネントは次のようになります。

            <DatePicker
                label="myDate"
                value={state.myDate}
                id="myDate"
                onChange={(newDate) => {
                    handleChange({
                        target: {
                            id: "myDate",
                            value: newDate
                        }
                    })
                }} />

ここに完全なコードがあります:

import React, { useState, useEffect } from "react";
import "materialize-css/dist/css/materialize.min.css";
import "materialize-css/dist/js/materialize.min.js";
import { DatePicker } from "react-materialize";

const PickDate = (props) => {

    const [state, setState] = useState({myName: "Mags", myDate: "2019-08-01"});

    const handleChange = (e) => {
        const key = e.target.id;
        const val = e.target.value;

        const newState = {...state};
        newState[key] = val;
        setState(newState);
    }

    return (
        <React.Fragment>
            <input type="text" value={state.myName} id="myName" onChange={handleChange} />
            <DatePicker
                label="myDate"
                value={state.myDate}
                id="myDate"
                onChange={(newDate) => {
                    handleChange({
                        target: {
                            id: "myDate",
                            value: newDate
                        }
                    })
                }} />
        </React.Fragment>
    );
}

export default PickDate;

PS。これはReactフックを使用していますが、通常のクラスでも動作します。

2

ルーカスに感謝します。あなたの答えも役に立ちました。

これが私の解決策です-reduxやpropsなしで、独自の状態を持つクラスコンポーネントのみ

import React, { Component } from "react";
import "./calendar.css";
import Materialize from "materialize-css";
import moment from "moment";

class Calendar extends Component {
  componentDidMount() {
    var context = this;

    var elems = document.querySelectorAll(".dateset");
    Materialize.Datepicker.init(elems, {
      defaultDate: new Date(),
      format: this.state.format,
      container: "body",
      onSelect: function(date) {
        context.setState({ value: context.state.value });
        console.log(date); // Selected date is logged
      },
      autoClose: true
    });
  }

  state = {
    value: new Date(),
    format: "ddd d, mmm",
    formatMoment: "ddd D, MMM"
  };

  render() {
    return (
      <div className="input-field col s6">
        <i className="material-icons prefix">date_range</i>
        <input
          id="date"
          type="text"
          className="datepicker dateset"
          defaultValue={moment(this.state.value).format(
            this.state.formatMoment
          )}
        />
      </div>
    );
  }
}

export default Calendar;
1
mrs_suis

すでに追加された回答のどれも私を助けなかったので、私は自分のやり方でそれを行うことにしました。 MaterializeとjQueryをモジュールにインストールせず、index.htmlに追加しただけです。

入力フィールドをクリックすると、datepickerモーダルウィンドウが開き、CANCELとOKの2つのボタンがあります。 jQueryによる[OK]ボタンを見つけ、クリック関数を追加します。これは、入力フィールドから値を受け取り、状態を更新します。

componentDidMount(){
window.$(".datepicker-done").click(() => {
      var datepickerValue = window.$("#date-input").val();  // date-input it's 'id' on datepicker input

      this.setState({ approxLastDay: datepickerValue });
    });
}

注: datepickerValueは文字列形式になります(例:「2019年8月6日」)

0
airush

私は同じ問題を抱えています、これが私の解決策です。

import React, { Component } from 'react'
import M from 'materialize-css';

class CreateReport extends Component {
    constructor(props) {
        super(props);
        this.state = {
            startDate: '',
            endDate: ''
        };
        // refs for startDate, endDate
        this.startDate = React.createRef();
        this.endDate = React.createRef();
    }
    componentDidMount() {
        var context = this;
        document.addEventListener('DOMContentLoaded', function () {
            var start = document.querySelectorAll('.datepicker');
            M.Datepicker.init(start, {
                format: "mm/dd/yyyy",
                autoClose: true,
                onClose: context.handleDate
            });
        });
    }
    handleDate = () => {
        this.setState({
            startDate: this.startDate.current.value,
            endDate: this.endDate.current.value,
        })
        // console.log(this.state.startDate)
        // console.log(this.state.endDate)
    }
    handleChange = (e) => {
        this.setState({
            [e.target.id]: e.target.value
        })
    }
    handleSumbit = (e) => {
        e.preventDefault();
        console.log(this.state)
    }
    render() {
        return (
            <div>
                <div className="container">
                    <form onSubmit={this.handleSumbit} className="white col s12 m6">

                        <div className="row">
                            <div className="input-field col s3 offset-s2">
                                <label htmlFor="date">Start Date</label>
                                <input
                                    type="text"
                                    className="datepicker"
                                    id="startDate"
                                    onChange={this.handleChange}
                                    value={this.state.startDate}
                                    ref={this.startDate}
                                />
                            </div>
                            <div className="input-field col s3 offset-s2">
                                <label htmlFor="date">End Date</label>
                                <input
                                    type="text"
                                    className="datepicker"
                                    id="endDate"
                                    onChange={this.handleChange}
                                    value={this.state.endDate}
                                    ref={this.endDate} />
                            </div>
                        </div>
                        <div className="col s8 offset-s2 center-align">
                            <button className="btn pink lighten-1 z-depth-0 ">Sign Up</button>
                        </div>

                    </form>
                </div>
            </div >
        )
    }
}
export default CreateReport
0
Khanh Luu

Reactのライフサイクルに関する土曜日をすべて調査した後。私はこのためのこの解決策を得ました:

コンポーネントの使用:

    <DatePicker label="Fecha" value={this.state.formSchedule.start} 
onChange={(date) => {
    this.state.formSchedule.start = date;
    this.setState({ formSchedule: this.state.formSchedule });
}}/>

クラスDatePicker.tsx:

    import * as React from 'react';
import Materialize from 'materialize-css';
import moment from 'moment'
import 'moment/locale/es'
import { any } from 'prop-types';


interface IState {
  value: any;
}

interface IProps {
  label: any;
  format: any;
  onChange: any;
  formatMoment: any;
}

export default class DatePicker extends React.Component<IProps, IState> {

  static defaultProps = {
    label: "Fecha",
    value: new Date(),
    format: 'ddd d, mmm',
    formatMoment: 'ddd D, MMM'
  }

  constructor(props: any) {
    super(props);
    this.componentWillReceiveProps(props);
  }

  componentWillReceiveProps(props) {
    this.state = {
      value: props.value
    };
  }

  render() {
    return <div className="input-field col s6">
      <i className="material-icons prefix">date_range</i>
      <input id="date" type="text" className="datepicker queso"
        value={moment(this.state.value).locale('es').format(this.props.formatMoment)}
      />
      <label className="active" htmlFor="date">{this.props.label}</label>
    </div>;
  }


  componentDidMount() {
    var context = this;

    var elems = document.querySelectorAll('.queso');
    Materialize.Datepicker.init(elems, {
      defaultDate: new Date(),
      format: this.props.format,
      container: 'body',
      onSelect: function (date) {
        context.setState({ value: context.state.value });
        context.props.onChange(date);
      },
      autoClose: true
    } as Partial<any>);

  }
}