7
votes

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?

7
Can you share the codes where *.tabIndex is used?Sajib Khan
I use custom component material-select, who containts this template: <select><slot></slot></select>Vitaliy Demchuk

7 Answers

6
votes

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.

5
votes

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();
1
votes
  • 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
votes

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
votes

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

0
votes

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

-1
votes

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();
});