Materialize: Select on('change') fires twice and one of the times with an empty value

Created on 8 Nov 2016  路  11Comments  路  Source: Dogfalo/materialize

Code example:


$(() => {

    $('select').on('change', e => {

        const $this = $(e.currentTarget)

        console.log('value:', $this.val())

    })

})

When changing the select once, the following outputs in console:

value: test-value
value: 

The second time it fires, the value is simply not empty, which can break your script if you don't add the following checker:

if ($this.val().length === 0) return 
bug

Most helpful comment

I had this problem with my code

$('.myClassName').on('change', function(){
  console.log($(this).val());
});

which fired twice like the OP said. One with the value and other one empty. Reason that happens is because materialize creates a div that you actually interact with and hides the select element. The div has the same class so the onChange applies to the div as well. My solution was

$('select.myClassName').on('change', function(){

or you could use an ID, I haven't tested that.

All 11 comments

Do you have jQuery required twice? This has happened to me before if jQuery is included twice in your code base.

No, only once:

<script src="../node_modules/jquery/dist/jquery.js"></script>
<script src="../node_modules/materialize-css/dist/js/materialize.js"></script>

But thanks for helping with narrowing down the issue.

Are you sure that nothing else has required jQuery on it's own? Other dependencies, which in them selves require the library will bind all events twice.

Yes, the only thing that requires jquery in my project is materialize itself, which is odd, since you have to manually add it on your own.

Can't seem to reproduce this. Can you post your code? Maybe you added multiple listeners to the change event?

@jonasroessum Try making following change and see if it helps

$(() => {

    $('select').off('change').on('change', e => {

        const $this = $(e.currentTarget)

        console.log('value:', $this.val())

    })

})

Some additional questions:

  1. Is this the only select on the page?

Can you share your code?

I had this same exact issue and ended up here.

if ($this.val().length === 0) return

this solves it, but seems abit unnecessary.

I had this problem with my code

$('.myClassName').on('change', function(){
  console.log($(this).val());
});

which fired twice like the OP said. One with the value and other one empty. Reason that happens is because materialize creates a div that you actually interact with and hides the select element. The div has the same class so the onChange applies to the div as well. My solution was

$('select.myClassName').on('change', function(){

or you could use an ID, I haven't tested that.

Try this:
$('.select-wrapper.your_classe_name li').on('click', function(){ console.log($(this).text()) });

As @VeeK727 said, you should only be applying the change event handler to the original select

You got event fired twice because you have two dynamically created material select in your page, each time when you create material select you are calling $('select').on('change', e => {}) which is resulting events to be attached to material select. If you had three material select created then event would have fired thrice.
I prefer to remove all the prior events attached to material select and then attach a new event.
$('select').off('change').on('change', e => {}) seems the clean way. I was using vue.js template repeater with mcss and came across same issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

serkandurusoy picture serkandurusoy  路  3Comments

ericlormul picture ericlormul  路  3Comments

artur99 picture artur99  路  3Comments

cope picture cope  路  3Comments

heshamelmasry77 picture heshamelmasry77  路  3Comments