admin管理员组

文章数量:1279050

I have a Materialize input like so:

<input type="date" className="datepicker" onChange={this.props.handleChange} />

It is being correctly initialised by Materialize, but not firing onChange when the value of the datepicker changes. What am I doing wrong here? This problem seems to extend to all Materialize inputs.

I have a Materialize input like so:

<input type="date" className="datepicker" onChange={this.props.handleChange} />

It is being correctly initialised by Materialize, but not firing onChange when the value of the datepicker changes. What am I doing wrong here? This problem seems to extend to all Materialize inputs.

Share Improve this question asked Jan 27, 2016 at 10:20 j_dj_d 3,08210 gold badges55 silver badges96 bronze badges 8
  • 1 did u try binding this to the function if you are using ES6, ex: onChange={this.props.handleChange.bind(this)}; – Vikramaditya Commented Jan 27, 2016 at 12:51
  • @Vikramaditya Unfortunately I'm not using ES6, will try to find a monjs way though. Thanks. – j_d Commented Jan 27, 2016 at 12:54
  • @Vikramaditya I get this error React ponent methods may only be bound to the ponent instance... – j_d Commented Jan 27, 2016 at 13:29
  • I am having the same issue. onChange is simply not triggering using Materialize for this datepicker. It works fine for the normal fields though, what am I missing? – born2gamble Commented Nov 19, 2018 at 8:43
  • Dear @j_d, please test the onChange with the following function, onChange={function(e) { console.log(e.target.value)}}, if it show the chosen date on the console so you should put the handleChange function inside your question. maybe the issue is from handleChange – AmerllicA Commented Feb 26, 2020 at 22:50
 |  Show 3 more ments

7 Answers 7

Reset to default 1

On ponentDidUpdate() using a prop id

var elem = document.getElementById('date');
        M.Datepicker.init(elem,{
            onClose:()=>{
                this.state.date = elem.value;                    
                this.setState(this.state)
            }
        });

I'm pretty sure this solves the caveat if you put it in your ponentDidMount ponent. If the select is to be re-rendered on state change, this should as well be put in ponentDidUpdate

// find the select element by its ref
const el = ReactDOM.findDOMNode(this.refs.ref_to_my_select);
// initialize the select
$('select').material_select();
// register a method to fireup whenever the select changes
$(el).on('change', this.handleInputChange)

To get the value of the datepicker in materialize they provide an onSelect option when initialising the ponent:

var instances = M.Datepicker.init(
      elems,
      {
        onSelect:function(){
          date = instances[0].date;
          console.log(date);
        }
      }
    );

https://codepen.io/doughballs/pen/dyopgpa

Every time you pick a date, onSelect fires, in this case console.logging the chosen date.

When you close the datepicker (which is actually a modal), that's when the onChange fires, in this case logging 'onChange triggered' to the console.

that's my solution. I use useRef hook, to identify datepicker input and when onClose is fired, we can capture the object and data value, through ref var.

import React, { useEffect, useState, useRef } from "react";
import M from "materialize-css";

export default function App() {

  const fromref = useRef(null); //create reference

  const [date, setDate] = useState({ fromdate: "" });

  const { fromdate } = date;

  useEffect(() => {
    let elem = document.querySelectorAll(".datepicker");
    M.Datepicker.init(elem, {
      firstDay: true,
      format: "yyyy-mm-dd",
      onClose: function() { // when onclose datepicker, we can get the value and data through the ref
        console.log(fromref.current.name, fromref.current.value);
        setDate({ [fromref.current.name]: fromref.current.value });
      }
    });
  }, []);

  return (
    <form class="col s12">
      <div class="row">
        <div class="input-field col s12">
          <input
            name="fromdate"
            type="text"
            class="datepicker"
            placeholder="from date"
            ref={fromref} //set reference to the input
          />
        </div>
      </div>
    </form>
  );
}

If you want to get the value or other attributes you can access them from instaces variable when initialized and then check before submitting your form.

var elems = document.querySelectorAll('.timepicker');
var instances = M.Timepicker.init(elems);

Then in order to get your value before submitting your form can do as follow:

var date = instances[0].el.value;

There are two things which might be stopping the execution of expected behaviour.


  1. If the code which you have displayed question section is from rendered html tree, then onchnage assigment needs to be called while assignment itself.
<input type="date" className="datepicker" onChange=this.props.handleChange(event)/>
  • Note: Previously browser events use to expects event callback handlers in string format as a value.

  • In MaterializeCss documentation there is no mentioning of onChange event, this means there cannot be direct way to get it.
  • https://materializecss./pickers.html

It looks like you're using materialize directly in your post but if it is possible, you could try using react-materialize as it wraps all the materialize ponents such that it's easier to use with React. Using react-materialize would probably be the cleanest way to handle state and event changes as they provide a convenience wrapper around each materialize ponent.

When using the date picker from react-materialize, you'll need to pass the handleChange method into the options prop like so:

<DatePicker
  options={{
    ...,
    onSelect: this.props.handleChange
  }}
 />

In the case of using the materialize date picker independently, if you could provide more details on how you're initializing the date picker input, I could provide a more relevant answer. But I'll give it a shot in the dark.

From the materialize docs it looks like you'll also have to pass back some options when you initialize it to handle a callback function when a date is selected.

I've added a JSFiddle that has a working example as well as a code snippet below, notice that when you select a date, 'hello world' is logged in the console, and the date is the first argument passed into the callback.

class Datepicker extends React.Component {
  constructor(props) {
    super(props)
  }

  handleChange(date) {
    console.log('hello world', date);
  }

  ponentDidMount() {
      var elems = document.querySelectorAll('.datepicker');
      var instances = M.Datepicker.init(elems, {
        onSelect: this.handleChange
      });
  }

  render() {
    return (
        <div>
          <input type="text" className="datepicker" />
        </div>
    )
  }
}

Live Example Fiddle

So to answer your question of how to handle events and setting the state, you just need to pass your handleChange method into the provided options configs depending on how you're using materialize date picker. In regards to integrating with a form, you could use the other callback hooks like onClose to do form validation.

本文标签: javascriptMaterialize inputs not triggering onChange in ReactStack Overflow