如何在 React 中正确捕获 Materialize-CSS datepicker 值?
Posted
技术标签:
【中文标题】如何在 React 中正确捕获 Materialize-CSS datepicker 值?【英文标题】:How do I correctly capture Materialize-CSS datepicker value in React? 【发布时间】:2019-05-19 10:26:52 【问题描述】:我希望在我的 React 组件中使用 materialize-css 创建一个带有 datepicker 的表单。这个表单捕获的字段不多,结构相当简单。返回的表单如下所示:
<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
,如果我选择一个日期然后重新打开日期选择器,有时会捕获日期。
我也尝试过使用一些alternate initialization methods for the datepicker 无济于事。
如何使用给定的设置正确捕获输入更改?
【问题讨论】:
不相信有onSelect
- 你的意思是onChange
吗?
我已经尝试了几个星期,但一切都是徒劳的,即使我想知道它的答案。
@SakoBu 我在问题中提到了这一点。似乎都没有提供所需的行为
哦,我也有同样的问题...这真的很难...对于时间选择器,我可以使用 onBlur 来完成...但不能使用 datepicker
Check this repository in this 我尝试制作 Materialize CSS 提供的所有 javascript 组件 - github.com/GermaVinsmoke/Reactize
【参考方案1】:
您好,希望这会对某人有所帮助 -
等其他组件正常工作。看看吧:
这是组件的外观:
<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;
附言。这使用 React Hooks - 但它也适用于普通类。
【讨论】:
【参考方案2】:在研究了所有关于 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>);
【讨论】:
伙计,这在 react 和 redux 的情况下也很有效。谢谢【参考方案3】:谢谢卢卡斯,你的回答也帮助了我。
这是我的解决方案 - 没有 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;
【讨论】:
【参考方案4】:已经添加的答案都没有帮助我,所以我决定以我的方式去做。 我没有将 Materialize 和 jQuery 安装到我的模块中,只是将它们添加到 index.html
当您单击输入字段时,日期选择器模式窗口将打开,并且有两个按钮 CANCEL 和 OK。我通过 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 将采用字符串格式(例如“Aug 6, 2019”)
【讨论】:
【参考方案5】:我有同样的问题,这是我的解决方案。
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
【讨论】:
【参考方案6】:我做了一个不太优雅的解决方案,但它也有不少代码行。它似乎正在工作(经过数小时的调试!)。
我创建了一个名为 trouble 的 css 类,并将其应用于处理 DatePicker 和 TimePicker 的所有字段。在初始化中,我创建了事件监听器来检查更改。当检测到更改时,它会调用 _valueTracker,并使其发送 redux 注意到的更新事件。
一件非常奇怪的事情是,如果我传入与 e.target.value 完全相同的值,它什么也不做。它必须是一串随机的东西,例如“UPDATE!”在这种情况下。我将此代码与物化初始化的其余部分一起使用。
const troubles = document.querySelectorAll(".trouble");
troubles.forEach((item) =>
item.addEventListener("change", (e) =>
e.target._valueTracker.setValue("UPDATE!");
);
);
【讨论】:
顺便说一句:这有点像 hack,但它节省了我重写所有不同的日期和时间组件,这很简单。以上是关于如何在 React 中正确捕获 Materialize-CSS datepicker 值?的主要内容,如果未能解决你的问题,请参考以下文章