New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Onchange event for <select> is not propagated in materialize css when not used with class "browser-default" #3667

Closed
richardsabow opened this Issue Apr 14, 2015 · 20 comments

Comments

Projects
None yet
@richardsabow

richardsabow commented Apr 14, 2015

I use materialize css framework with react and had an issue on <select>s onChange event propagation.
This way the event is not fired, this.handleSelectChange is not called.

<select value="B" onChange={this.handleSelectChange}>
    <option value="A">Apple</option>
    <option value="B">Banana</option>
    <option value="C">Cranberry</option>
</select>

When i add the class browser-default to select it works pretty well.

<select className="browser-default" value="B" onChange={this.handleSelectChange}>
    <option value="A">Apple</option>
    <option value="B">Banana</option>
    <option value="C">Cranberry</option>
</select>

Not sure if it's a react issue, but maybe.
I also created an issue on materialize repo: Dogfalo/materialize#1160

@syranide

This comment has been minimized.

Show comment
Hide comment
@syranide

syranide Apr 14, 2015

Contributor

If you have a repro it would be great.

Is "materialize" perhaps modifying the DOM? It kind of sounds like it, that's a big no-no, you may update styles and props of React managed nodes without errors, but if they're cloned/replaced/moved then it's an invariant error waiting to happen.

Contributor

syranide commented Apr 14, 2015

If you have a repro it would be great.

Is "materialize" perhaps modifying the DOM? It kind of sounds like it, that's a big no-no, you may update styles and props of React managed nodes without errors, but if they're cloned/replaced/moved then it's an invariant error waiting to happen.

@bloodyowl

This comment has been minimized.

Show comment
Hide comment
@bloodyowl

bloodyowl Apr 14, 2015

Contributor

I think the guilty's here https://github.com/Dogfalo/materialize/blob/master/sass/components/_form.scss#L654

materialize creates a fake select with a <ul> as you can see in their demo

Contributor

bloodyowl commented Apr 14, 2015

I think the guilty's here https://github.com/Dogfalo/materialize/blob/master/sass/components/_form.scss#L654

materialize creates a fake select with a <ul> as you can see in their demo

@Charca

This comment has been minimized.

Show comment
Hide comment
@Charca

Charca Apr 14, 2015

Contributor

There's a lot of DOM mutation happening when you use a materialize custom component, and I guess you'll face similar problems with most of those components. Maybe Material-UI is more suitable for your requirements: http://callemall.github.io/material-ui/

Contributor

Charca commented Apr 14, 2015

There's a lot of DOM mutation happening when you use a materialize custom component, and I guess you'll face similar problems with most of those components. Maybe Material-UI is more suitable for your requirements: http://callemall.github.io/material-ui/

@richardsabow

This comment has been minimized.

Show comment
Hide comment
@richardsabow

richardsabow Apr 14, 2015

Thank you guys! :)
@bloodyowl You're right, i"ve forgotten that this could be the issue.
@Charca Yes i know about material-ui, i tried it, but materialize felt to be more mature and it has more features. And i hadn't any real issue with it until now. :)

richardsabow commented Apr 14, 2015

Thank you guys! :)
@bloodyowl You're right, i"ve forgotten that this could be the issue.
@Charca Yes i know about material-ui, i tried it, but materialize felt to be more mature and it has more features. And i hadn't any real issue with it until now. :)

@zpao

This comment has been minimized.

Show comment
Hide comment
@zpao

zpao Apr 21, 2015

Member

Not an actual React bug so closing out. The fact that materialize is modifying the DOM means you're probably going to have a tricky time of things and you'll probably want to build some wrapper components to make things work better. Good luck!

Member

zpao commented Apr 21, 2015

Not an actual React bug so closing out. The fact that materialize is modifying the DOM means you're probably going to have a tricky time of things and you'll probably want to build some wrapper components to make things work better. Good luck!

@zpao zpao closed this Apr 21, 2015

@richardsabow

This comment has been minimized.

Show comment
Hide comment
@richardsabow

richardsabow Apr 21, 2015

Yes, but actually your answers helped me, so thanks! :)

richardsabow commented Apr 21, 2015

Yes, but actually your answers helped me, so thanks! :)

@davidleverage

This comment has been minimized.

Show comment
Hide comment
@davidleverage

davidleverage Jun 16, 2015

this isnt a react answer but materializecss ensures that when the form is submitted, the correct value is sent in the select element so if for instance you have a form (or any container) with id subject_update and the select name is type you can capture the change event with jquery as follows:
$('#subject_update select[name=type]').on('change',function(){console.log('select has changed to:',$(this).val());});

davidleverage commented Jun 16, 2015

this isnt a react answer but materializecss ensures that when the form is submitted, the correct value is sent in the select element so if for instance you have a form (or any container) with id subject_update and the select name is type you can capture the change event with jquery as follows:
$('#subject_update select[name=type]').on('change',function(){console.log('select has changed to:',$(this).val());});

@burabure

This comment has been minimized.

Show comment
Hide comment
@burabure

burabure Jul 21, 2015

here's a clean way to do it:

  componentDidMount() {
    // Use Materialize custom select input
    $(this.refs.yourSelectTag).material_select(this._handleSelectChange.bind(this));
  }

if you're using react < 0.14.0 you'll have to use getDOMNode() on this.refs.yourSelectTag

burabure commented Jul 21, 2015

here's a clean way to do it:

  componentDidMount() {
    // Use Materialize custom select input
    $(this.refs.yourSelectTag).material_select(this._handleSelectChange.bind(this));
  }

if you're using react < 0.14.0 you'll have to use getDOMNode() on this.refs.yourSelectTag

@waganse

This comment has been minimized.

Show comment
Hide comment
@waganse

waganse Sep 29, 2015

@davidleverage You made my day! Form with id="subject_update" put me on the right track.

waganse commented Sep 29, 2015

@davidleverage You made my day! Form with id="subject_update" put me on the right track.

@quannt

This comment has been minimized.

Show comment
Hide comment
@quannt

quannt Mar 22, 2016

Using delegated event fixes the problem for me.

HTML

`

Choose your option
`

JS

$('#pickerContainer').on('change', 'select', function(){ console.log("got you"); });

quannt commented Mar 22, 2016

Using delegated event fixes the problem for me.

HTML

`

Choose your option
`

JS

$('#pickerContainer').on('change', 'select', function(){ console.log("got you"); });

@erudinsky

This comment has been minimized.

Show comment
Hide comment
@erudinsky

erudinsky May 11, 2016

Guys, quick question. When I have dynamic children and need to bind onChangeHandler to each generated "select" component. How can I do this? Seems my ref is not unique and it just binds it to the last in my loop..

erudinsky commented May 11, 2016

Guys, quick question. When I have dynamic children and need to bind onChangeHandler to each generated "select" component. How can I do this? Seems my ref is not unique and it just binds it to the last in my loop..

@saiponethaaung

This comment has been minimized.

Show comment
Hide comment
@saiponethaaung

saiponethaaung Jul 3, 2016

Hi @erudinsky I think we can simply use
$("select.dynamicclass").on("change")
handler( by using select element as a prefix ). I just fix my problem in this way.

saiponethaaung commented Jul 3, 2016

Hi @erudinsky I think we can simply use
$("select.dynamicclass").on("change")
handler( by using select element as a prefix ). I just fix my problem in this way.

@yanickrochon

This comment has been minimized.

Show comment
Hide comment
@yanickrochon

yanickrochon Aug 13, 2016

The element value is always empty for me. The options are generated dynamically, and they do appear in the list, however the node is empty when I inspect it and whatever method I use, the value is not set (i.e. this.refs.selectElement.value, $(this.refs.selectElement).val(), this.refs.selectElement.selectedIndex, etc.)

yanickrochon commented Aug 13, 2016

The element value is always empty for me. The options are generated dynamically, and they do appear in the list, however the node is empty when I inspect it and whatever method I use, the value is not set (i.e. this.refs.selectElement.value, $(this.refs.selectElement).val(), this.refs.selectElement.selectedIndex, etc.)

@yanickrochon

This comment has been minimized.

Show comment
Hide comment
@yanickrochon

yanickrochon Aug 13, 2016

@zpao many projects use React with Materialize. This is not an isolated case. And I'm not even sure, yet, how Materialize lists all the OPTIONS as they aren't there when I inspect my DOM.... Closing this issue on the basis that "make your own wrapper" in these circumstances is almost insulting.

yanickrochon commented Aug 13, 2016

@zpao many projects use React with Materialize. This is not an isolated case. And I'm not even sure, yet, how Materialize lists all the OPTIONS as they aren't there when I inspect my DOM.... Closing this issue on the basis that "make your own wrapper" in these circumstances is almost insulting.

@syranide

This comment has been minimized.

Show comment
Hide comment
@syranide

syranide Aug 13, 2016

Contributor

Closing this issue on the basis that "make your own wrapper" in these circumstances is almost insulting.

@yanickrochon Materialize replaces what React renders outside of React, that is simply not possible to support and thus there's nothing React can fix here. So Materialize is simply incompatible with React, there may be workarounds but I doubt they truly work due to the nature of Materialize, but may just hide the immediate issues and cause errors later.

EDIT: PS. you can always render markup using dangerouslySetInnerHTML and apply Materialize on that, that is fully supported.

Contributor

syranide commented Aug 13, 2016

Closing this issue on the basis that "make your own wrapper" in these circumstances is almost insulting.

@yanickrochon Materialize replaces what React renders outside of React, that is simply not possible to support and thus there's nothing React can fix here. So Materialize is simply incompatible with React, there may be workarounds but I doubt they truly work due to the nature of Materialize, but may just hide the immediate issues and cause errors later.

EDIT: PS. you can always render markup using dangerouslySetInnerHTML and apply Materialize on that, that is fully supported.

@yanickrochon

This comment has been minimized.

Show comment
Hide comment
@yanickrochon

yanickrochon Aug 13, 2016

@syranide Well, then, luckily some people do not agree with you, and created react-materialize which seems to solve many issues that "React [can't] fix".

yanickrochon commented Aug 13, 2016

@syranide Well, then, luckily some people do not agree with you, and created react-materialize which seems to solve many issues that "React [can't] fix".

@bloodyowl

This comment has been minimized.

Show comment
Hide comment
@bloodyowl

bloodyowl Aug 13, 2016

Contributor

@yanickrochon That's literally what the "make your own wrapper" advice means when it's applied 😉

Contributor

bloodyowl commented Aug 13, 2016

@yanickrochon That's literally what the "make your own wrapper" advice means when it's applied 😉

@mcmxc

This comment has been minimized.

Show comment
Hide comment
@mcmxc

mcmxc Sep 14, 2016

@quannt Man, thanks God I met you here. Thank you for leaving your solution, works great for me. Thanks!

mcmxc commented Sep 14, 2016

@quannt Man, thanks God I met you here. Thank you for leaving your solution, works great for me. Thanks!

@nanda248

This comment has been minimized.

Show comment
Hide comment
@nanda248

nanda248 Jun 8, 2017

_I've been playing around with Materialize(^0.98.2) select feature with Meteor React. Below is the way how i fixed the issue. Meteor 1.4.4.3 _

import ReactDOM from 'react-dom'; 
...
componentDidMount(){
	  $(document).ready(function() {
	    $('select').material_select();
	  });		  
	  $(ReactDOM.findDOMNode(this.refs.testSelect)).on('change',this.handleSelectChange.bind(this));
}
``
handleSelectChange(event) {
	event.preventDefault();
	var test = event.target.value;
     	       this.setState({value: test});
}

render(){
...
<div className="input-field col s12">
<select ref="testSelect">
   <option value="" disabled selected>Choose your option</option>
   <option value="123">Option 1</option>
   <option value="223">Option 2</option>
   <option value="332">Option 3</option>
</select>
    <label>Materialize Select</label>
 </div>	
}

nanda248 commented Jun 8, 2017

_I've been playing around with Materialize(^0.98.2) select feature with Meteor React. Below is the way how i fixed the issue. Meteor 1.4.4.3 _

import ReactDOM from 'react-dom'; 
...
componentDidMount(){
	  $(document).ready(function() {
	    $('select').material_select();
	  });		  
	  $(ReactDOM.findDOMNode(this.refs.testSelect)).on('change',this.handleSelectChange.bind(this));
}
``
handleSelectChange(event) {
	event.preventDefault();
	var test = event.target.value;
     	       this.setState({value: test});
}

render(){
...
<div className="input-field col s12">
<select ref="testSelect">
   <option value="" disabled selected>Choose your option</option>
   <option value="123">Option 1</option>
   <option value="223">Option 2</option>
   <option value="332">Option 3</option>
</select>
    <label>Materialize Select</label>
 </div>	
}
@hienng

This comment has been minimized.

Show comment
Hide comment
@hienng

hienng Jul 5, 2017

How can i do @nanda248 's with ref callbacks?

hienng commented Jul 5, 2017

How can i do @nanda248 's with ref callbacks?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment