Changing the background color of a mat-menu in Angular material through programming techniques

I am currently working on a mega menu and have the following code snippet:

<button mat-button [matMenuTriggerFor]="objectmenu">Objects</button>
        <mat-menu #objectmenu="matMenu" >
              <div class="menu-content" [style.backgroundColor]="getUnSelectedRandomColor()" style="height: 550px;">
                <div  fxFlex="100" fxFlex.gt-sm="30" fxFlex.sm="45" class="dropdown-menu-items"> 
                  <div class="dropdown-menu-btns" *ngFor="let parent of (objectList$ | async)"
                   (mouseover)="openCategory($event, 
                   parent)"
                   [style.background-color] = "this.selectedColor === (parent.categoryId * 100)  ? getSelectedRandomColor() : getUnSelectedRandomColor()"

                   >{{parent.name}}</div>
              </div>
                    <div class="theme-container">

                    <div class="theme-container" style=" padding-bottom: 0px !important; padding-top: 7px !important;">
                      <div fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="center center" class="content border-lighter">
                        <div fxFlex="100" fxFlex.gt-sm="100" fxLayout="column" fxLayoutAlign="center center"> 
                            <h2 *ngIf="this.selectedCategory" class="uppercase">{{this.selectedCategory.name}}</h2>
                        </div>
                    </div>

                    <div class="content border-lighter" [style.backgroundColor]="getSelectedRandomColor()" style="height: 380px;">

                        <div fxLayout="row wrap" fxLayoutAlign="space-between"> 
                            <div fxFlex="100" fxFlex.gt-sm="70" fxFlex.sm="45" style="column-count: 2;"> 
                              <ul class="ht-dropdown megamenu-two d-flex"
                              *ngFor="let parent of (childCategories$ | async)" style="list-style: none;">

                               <label [routerLink]="['/products']" [queryParams]="{categories: parent.categoryId}"
                               routerLinkActive="router-link-active">{{parent.name}}</label>
                             <li *ngFor="let child of parent.childrenCategories"
                             [routerLink]="['/products']" [queryParams]="{categories: child.categoryId}"
                               routerLinkActive="router-link-active">
                               {{child.name}}

                           </li>
                         </ul>
                            </div>



                            <div fxFlex="100" fxFlex.gt-sm="30" ngClass.lt-md="pt-5" style="background-size: contain !important;"
                            [style.background]="selectedCategoryUrl"> 

                            </div>
                        </div> 

                    </div>


                    </div> 
                    <div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="space-between center" >
                      <img *ngFor="let brand of (relatedBrandsList$ | async)"  [src]=" brand.thumbnail | safeHtml" style="width: 110px; height: 110px; border-radius: 50%;"/>
                    </div>                     
                  </div>                    
                 </div>   


        </mat-menu>

After applying this code, I noticed that the top and bottom edges of the menu panel are not reflecting the dynamic background color generated by my Angular code using the getUnSelectedRandomColor() method. The getUnSelectedRandomColor() function is defined as follows:

openCategory(evt, category: Category) {
    this.selectedCategory = category;
    this.selectedCategoryUrl = `url('../../assets/categories/${category.categoryId}.webp')`;
    this.childCategories$ = this.store.pipe(select(getChildCategories(category.categoryId)));
    this.relatedBrandsList$ = this.store.pipe(select(getRelatedBrands(category.categoryId)));
    this.selectedColor = category.categoryId * 100;
    }

  getSelectedRandomColor() {
    const color = 'hsl(' + this.selectedColor + ', 30%, 75%)';
    return color;
    }
  getUnSelectedRandomColor() {
      const color = 'hsl(' + this.selectedColor + ', 30%, 86%)';
      return color;
    }

What steps can I take to ensure that the dynamic background colors are applied to all parts of the menu panel?

Answer №1

Enhancing Angular 9 Menu Functionality

When dealing with menu panel items in Angular 9, it's important to target the panelId property of MatMenu to make changes effectively. By obtaining the panel id and manipulating the element accordingly, you can modify the desired attribute using decorators like ViewChild and Renderer2 service.

For a practical demonstration, consider this example where I demonstrate dynamically altering the background color of the panel based on mouseover events from the menu items: interactive demo

import { Component, ViewChild, Renderer2 } from '@angular/core';
import { MatMenu } from '@angular/material/menu/';

@Component({
  selector: 'my-app',
  template: './app.component.html',
})
export class AppComponent {
  @ViewChild('menu', {static: true}) menu: MatMenu

  constructor(private _renderer2: Renderer2) {
  }

  changeBackgroundPanel(colorValue: string) {
    const el = document.getElementById(this.menu.panelId);
    this._renderer2.setStyle(el, 'background', colorValue);
  }
}
<button mat-raised-button [matMenuTriggerFor]="menu" color="primary">Open Menu</button>
<mat-menu #menu="matMenu">
  <button mat-menu-item (mouseover)="changeBackgroundPanel('blue')">Blue</button>
  <button mat-menu-item (mouseover)="changeBackgroundPanel('orange')">Orange</button>
  <button mat-menu-item (mouseover)="changeBackgroundPanel('red')">Red</button>
</mat-menu>

[Alternative Approach for Angular 8]

Check out a working example tailored for Angular 8 here: interactive demo

Component:

import { Component, Renderer2 } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.scss' ]
})
export class AppComponent  {
  constructor(private _renderer2: Renderer2) {
  }

  changeBackgroundPanel(colorValue: string) {
    const el = document.getElementById('myPanelId');
    this._renderer2.setStyle(el, 'background', colorValue);
  }
}

Html:

<button mat-raised-button [matMenuTriggerFor]="menu" color="primary">Open Menu</button>
<mat-menu #menu="matMenu">
  <div id="myPanelId" class="menu-panel">
    <button mat-menu-item (mouseover)="changeBackgroundPanel('blue')">Blue</button>
    <button mat-menu-item (mouseover)="changeBackgroundPanel('orange')">Orange</button>
    <button mat-menu-item (mouseover)="changeBackgroundPanel('red')">Red</button>
  </div>
</mat-menu>

CSS:

.menu-panel {
  margin: -8px 0; 
  padding: 8px 0;
}

Answer №2

At last, the solution revealed itself:

::ng-deep .mat-menu-content{
            padding-top: 0px !important;
            padding-bottom: 0px !important;
          }

By applying the style mentioned above to remove the paddings, the white gaps vanished.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Relocate the number of records displayed per page next to the pagination controls in datatables

Currently, I am utilizing datatables to create tables effectively using their provided example. However, I am encountering difficulty in moving the "records per page" element, which is contained within a "span6" class of bootstrap. I understand that this ...

A guide on updating CSS content dynamically within ExtJS

In my resource folder, I have a CSS file that contains some values which I need to change or add based on certain conditions. However, I'm struggling to figure out how to achieve this. Here is an example of the code: triggers: { clear: { ...

Reusing components in Angular 2 to dynamically display various data on a single page based on the service response

Looking at my HTML <div> <section></section> <section></section> </div> My Component import {Component} from '@angular/core'; import {Observable} from 'rxjs/rx'; import {HTTP_PROVIDERS} from ...

Incorporating the Vidyard embedded player within an Angular application

The Vidyard Portal provides an embed code that looks like this: <!-- The script tag should be placed in the head of your page if possible --> <script src="https://play.vidyard.com/embed/v4.js" type="text/javascript" async>&l ...

Overflow issue with Bootstrap 4 cards on small screens

When working on my application, I find myself using the bootcard .card class quite frequently. However, I've noticed that when switching to mobile view, there is a significant overflow issue that causes a display bug and shifts my entire page out of ...

When using Angular with WebApi, it is important to decide whether the models' first letter should be

Completely new to working with Angular and I'm encountering an issue where the first letter of my result from the Webapi model is always uppercase, even though my Angular model's first letter is lowercase. User.ts export interface User exte ...

How to target labels in CSS that end with a colon (*:)

Can CSS target labels that end with an asterisk and colon combination? Is this achievable? Let me elaborate further as per your request: Apologies if my explanation was not clear. I am working with an HTML label element that may end with an asterisk and ...

What could be the reason for the meta viewport not functioning properly on Android devices with Cordova 5.1.1?

Ever since upgrading my app to cordova 5.1.1, I've noticed that the meta viewport no longer functions properly on Android devices. The app is not displaying correctly as a result. Despite trying various solutions, I am still facing this issue. Is ther ...

Encountering a hiccup with the Bootstrap navbar when attempting to create a collapsible feature

I recently obtained a code sample for a navigation bar from w3schools.com that utilizes bootstrap. The code is as follows: <nav class="navbar navbar-inverse"> <div class="container-fluid"> <div class="navbar-he ...

Vue.js does not support the usage of external JSON files directly within HTML documents

I'm encountering issues fetching data from an external JSON file for a specific variable. I suspect that the problem lies in using Vue.js within the HTML, as it seems to be having trouble interpreting my code correctly.:joy: jsfiddle Additionally, I ...

Button group malfunctions on smaller screens

After integrating a button group into my new website, I noticed that the first two buttons stop functioning properly on smaller screens. Surprisingly, if I remove the text-center div, all buttons cease to work entirely. Despite attempting various solution ...

Angular component: The selected property is not appearing set to false on the first click when using @

I am currently working on developing a set of accordion components. My goal is to have only one accordion open at a time out of the three available. Essentially, if one accordion is open and I click on another one, the open accordion should collapse. At t ...

Display title using a jQuery toolbar

Looking to spruce up a Toolbar with a title using jQuery UI. This is what I have so far: HTML: <div class="demo"> <span id="toolbar" class="ui-widget-header ui-corner-all"> <label>go to beginning</label> <button id= ...

Developing Electron applications using Angular-CLI

I am currently developing a desktop application using Electron paired with Angular2 (incorporating Angular-CLI). To utilize Bootstrap within my project, I made sure to include the necessary script files in angular-cli.json under apps[0].scripts as shown b ...

In the mobile view of the jumbotron, there is a noticeable blank area on the right side

I've searched high and low for a solution to this issue, but nothing seems to pinpoint the cause of the problem. The white space that's causing trouble is evident in the following image: https://i.sstatic.net/95Rh6.jpg Could you help me identif ...

Move the first column to the right using BS4

Currently, I am working with bootstrap4 and facing an issue where I need the first div column to float right on medium devices and above. However, on mobile devices, it should be shown first. This was easily achievable in bootstrap3 using a structure lik ...

Setting the x-api-key header with HttpInterceptor in Angular 4: A guide

I am attempting to use HttpInterceptor to set the header key and value, but I am encountering the following error: Failed to load https://example.com/api/agency: Response to preflight request doesn't pass access control check: No 'Access ...

creating a mixin for a box-shadow value of none in LESS CSS

I'm encountering a challenge with implementing the box-shadow mixin in LESS css. Here's the mixin for box-shadow: .boxShadow (@x, @y, @blur, @spread: 0, @alpha) { -webkit-box-shadow: @x @y @blur @spread rgba(0, 0, 0, @alpha); -moz-box-s ...

Stop ngOnChanges from being triggered after dispatching event (Angular 2+)

In Angular 2+, a custom two-way binding technique can be achieved by utilizing @Input and @Output parameters. For instance, if there is a need for a child component to communicate with an external plugin, the following approach can be taken: export class ...

What are some strategies for creating distinct identifiers for UI elements in Vaadin apps?

Typically, a Vaadin application assigns a sequential ID to each user interface component. However, these IDs are not ideal for test automation due to their dynamic generation and potential changes during runtime or when new components are added. For effec ...