How to dropdown menu in Angular with Materialize CSS?

Asked

Viewed 522 times

0

I was doing a small project with Angular (V8.2.5) and Materialize (materialize-css v1.0.0), and decided at a certain point to insert a dropdown menu into a header component. Following the documentation template, my HTML looked like this:

<div class="right hide-on-med-and-down">
  <ul>
    <li><a>item1</a></li>
    <li><a>item2</a></li>
    <li><a>item3</a></li>
    <li><a id="dropdown-trigger" target="dropdown1">
      <fa-icon [icon]="['fas', 'user']" size="lg"></fa-icon>
    </a></li>
  </ul>
</div>
<ul id="dropdown1" class="dropdown-content">
  <li><a href="#!">one</a></li>
  <li><a href="#!">two</a></li>
  <li class="divider"></li>
  <li><a href="#!">three</a></li>
</ul>

However, when doing Typescript, I don’t know which place is right to call jQuery from the example, and I did this:

import { Component, OnInit } from '@angular/core';
import * as $ from 'jquery';

/* trecho omitido */
export class HeaderComponent implements OnInit {

  /* trecho omitido */

  ngOnInit() {
    $(document).ready(() => {
      $("#dropdown-trigger").dropdown();
    });
  }
}

However, typescript does not recognize the dropdown function (https://materializecss.com/dropdown.html), and the system does not perform the corresponding action. What should I do?

  • 1

    And what error is returned? Remembering that it is not very advised to use jQuery together with Angular, each manipulates the Dom in its own way and this can generate many bugs, plus more N reasons, but, people insist to use them together, for example, for Angular there is the ngx-materialize to use Materialize: https://www.npmjs.com/package/ngx-materialize

  • ERROR in src/app/core/header/header.component.ts:15:30 - error TS2339: Property 'dropdown' does not exist on type 'JQuery<HTMLElement>'. $("#dropdown-trigger").dropdown(); wdm : Failed to Compile.

  • What makes me more confused is that, according to the documentation of Materialize, this alone would be enough to make the menu work

  • 1

    Only that’s enough, maybe with Angular no. You know that Materialize works with pure Javascript tbm right?!

  • I saw the javascript on the site, and I had a question in this excerpt: var instances = M.Dropdown.init(elems, options);. What is that class M, Where is Dropdown.init (an extract from https://materializecss.com/dropdown.html) called? Even Typescript error when searching for class.

  • 1

    M is Materialize, it’s like a command: Materialize will start the Dropdown component. You have to see which scope is declaring the instance variable, as I said, messing with something that wasn’t made for that is really bad.

  • It worked, I removed the jQuery and imported the Materialize and the function started to respond. It also had a conflict with @types/materialize-css that caused an error calling it without jQuery, but it was just reinstalling. Thank you.

  • 1

    Cool Arthur, success there.

  • 1

    Hello hello hello, share your own solution in a new response with the most complete code snippet possible, so you can help someone in the future as is the goal of this platform.

Show 4 more comments

1 answer

1


I was able to make the menu work, but for that, I had to give up Jquery. Just as @Leandrade mentioned in the comments, I couldn’t use Jquery, because it was conflicting with Angular, and I had to do it using pure Javascript.

So, the class I created looked something like this:

document.addEventListener('DOMContentLoaded', function() {
    var elems = document.querySelectorAll('.dropdown-trigger');
    var instances = M.Dropdown.init(elems, options);
});
export class MyClass extends OnInit{
    constructor( /* dependências */ ){}

    ngOnInit(){ }
}

The function of Event Listener was outside the class because it seemed to make more semantic sense (I don’t know if I did it correctly, but ok, it works). Finally, it was necessary to add the import line at the beginning of the file:

import * as M from 'materialize-css';

Remembering that I already own the file angular.json configured to import Materialize, as shown below:

"styles": [
    "src/styles.css",
    "./node_modules/materialize-css/dist/css/materialize.min.css"
],
"scripts": [
    "./node_modules/materialize-css/dist/js/materialize.min.js"
]

I hope I’ve helped.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.