7

I am trying to test my vuejs component via jest that contains materialize select. When performing a component test, I get the following error in materialize.js:

TypeError: Cannot set property 'tabIndex' of null at Dropdown._makeDropdownFocusable

How fix this error?

Vitaliy Demchuk
  • 180
  • 1
  • 1
  • 9

7 Answers7

8

This problem can happen when the input field is not wrapped inside a div with the class input-field:

  <div class="input-field">
    <input type="text" class="autocomplete"></input>
  </div>

Adding a div with the class "input-field might solve this problem.

Paul Massendari
  • 417
  • 3
  • 6
6

use id selector instead class selector. for example call dropdown like this :

html :

<a class='dropdown-trigger' id="dropdowner" href='#' data-target='dropdown1'>Drop Me!</a>

                         <!-- Dropdown Structure -->
                         <ul id='dropdown1' class='dropdown-content'>
                           <li><a href="#!">one</a></li>
                           <li><a href="#!">two</a></li>
                           <li class="divider" tabindex="-1"></li>
                           <li><a href="#!">three</a></li>
                           <li><a href="#!"><i class="material-icons">view_module</i>four</a></li>
                           <li><a href="#!"><i class="material-icons">cloud</i>five</a></li>
                         </ul>

js:

$('#dropdowner').dropdown();
sajjad
  • 646
  • 1
  • 9
  • 20
  • 1
    Strangely, this answer is correct, using id selector does fix the error. I don't know why people down-voted. Still if you want to keep using class selector, just wrap it with try/catch and you are good to go. – M.Imran Mamda Nov 24 '19 at 17:58
1
  • Can only be used once.
  • data-target="name_target" must not be repeated

Exam1.❌

<nav>
  <div class="nav-wrapper">
    <ul class="right hide-on-med-and-down">
      <li><a class="dropdown-trigger" href="#!" data-target="name_target1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
 <li><a class="dropdown-trigger" href="#!" data-target="name_target1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
    </ul>
  </div>
</nav>
  <!-- Dropdown Structure -->
<ul id="name_target1" class="dropdown-content">
  <li><a href="#!">one</a></li>
  <li><a href="#!">two</a></li>
</ul>

Exam2.✔️

<nav>   <div class="nav-wrapper">
    <a href="#!" class="brand-logo">Logo</a>
    <ul class="right hide-on-med-and-down">
      <li><a class="dropdown-trigger" href="#!" data-target="name_target2">Dropdown<i enter code here class="material-icons right">arrow_drop_down</i></a></li>
    </ul>   </div> </nav>   <ul id="name_target2" class="dropdown-content">   <li><a href="#!">one</a></li>   <li><a href="#!">two</a></li> </ul>
0

When I ran into this issue I was trying to create the whole dropdown list dynamically in JS. The fix for me was creating the list and any default list elements in HTML:

<div id="select1" class=\"input-field col s12\">
    <select>
        <option value="" selected>Default</option>
    </select>
    <label>Test</label>
</div>

Then appending any dynamic values in JS:

contents.forEach(function(content) {
    var buffer = "<option></option>";
    var template = $(buffer);
    $(template).text(content);
    $("select1").find("select").append(template);
});

$("select").formSelect();
0

pre 1.0.0 you would use data-activates, if data-target is not specified you will get this error

Pulse-Eight
  • 101
  • 3
0

My problem was, that jQuery object was not attached to the DOM yet, so inner materialise code could not init element due to inability to find element by ID:

// materializecss initing dropdown (in my case for input autocomplete), where `t` is the input element
i.id = M.getIdFromTrigger(t),
i.dropdownEl = document.getElementById(i.id),
i.$dropdownEl = h(i.dropdownEl),

M.getIdFromTrigger(t) returned some random ID (not the one I provided) and dropdownEl was inited with null, and later method _makeDropdownFocusable failed on using it `this.dropdownEl.tabIndex = 0

So my problem code looked like this:

let root = $('#root'); // root in the DOM already
let wrapper = $('<div>'); // wrapper is just created and NOT attached to the DOM yet 
let input = $('<input>').appendTo(wrapper); // creating input and attaching to the wrapper, but still not in DOM
initAutocomplete(input) // M.Autocomplete.init logic here FAILS 
root.append(wrapper) // too late, error above

So the quick fix is to append elements first and only than do M.Autocomplete.init

Vitaliy Moskalyuk
  • 2,463
  • 13
  • 15
-1

I just stumbled this issue too while using Materializecss for my Vue project. As mentioned by sajjad, using id selector instead of class works. However, this is problem for initializing multiple dropdown, since each dropdown must have unique ID.

The way I solve this is just by selecting all the elements with the '.dropdown-trigger' class, and initialize every each of those. It works for me.

$.each($('.dropdown-trigger'), function(index, value) {
        $(value).dropdown();
});
Afif Zafri
  • 640
  • 1
  • 5
  • 11