Dynamically selecting themes in an Angular application based on user input

Experimenting with an angular project where users can choose themes from a dropdown menu to modify the appearance of the application using this handy tutorial

Utilizing :host-context for this purpose

Encountering an issue where the selected themes are not being applied correctly, and I'm at a loss as to what could be causing it. Here's the code snippet:

app.component.html

<!--The following content is just a placeholder and can be updated by you.-->
<div [ngClass]="theme">
  <nav class="navbar fixed-top navbar-light justify-content-center headerColor">
    <a class="navbar-brand" href="#">Socxo Themes</a>
  </nav>
  <div class="content">
    <div class="row topClass">
      <div class="col">
        <select name="selectTheme" [(ngModel)]="theme" (change)="setTheme(theme)">
          <option value="default">Default</option>
          <option value="one">Theme 1</option>
          <option value="two">Theme 2</option>
        </select>
      </div>
    </div>
  </div>
</div>

app.component.ts

export class AppComponent {
  title = 'app';
  theme = "default";

  setTheme(themeName:string)
  {
    this.theme=themeName;
  }
}

Initially focusing on theming the navbar

Below is the app.component.css file

@import "./app.component.1.css";
@import "./app.component.2.css";
@import "./app.component.3.css";
.content{
    margin-top:55px;
    text-align: center;
}
.topClass{
    margin-top:70px;
}

.headerColor{
    border:1px solid;
}

In ./app.component.1,2,3.css, I've included the CSS properties for different themes as shown below

:host-context(.one).headerColor{
    background-color: chocolate;
}
:host-context(.two).headerColor{
    background-color: chocolate;
}
:host-context(.default).headerColor{
    background-color: chocolate;
}

When selecting an option from the dropdown, the value of the theme variable changes but the corresponding class fails to load

Any help or guidance on this matter would be greatly appreciated.

Answer №1

Utilizing the :host-context() function allows for the application of styles to external host elements. As stated in the documentation:

The :host-context() selector searches for a CSS class within any ancestor of the component host element, all the way up to the document root.

In your scenario, you are attempting to style an element within the same component. To achieve this, follow these steps:

Create a navigation component and transfer your navigation bar code into it.

Add the theme styles specific to the navigation component inside its own stylesheet.

@import "../app.component.1.css";
 @import "../app.component.1.css";
 @import "../app.component.2.css";


Update your appComponent.html as shown below:

<div [ngClass]="theme">
  <nav-comp></nav-comp>
  <div class="content">
    <div class="row topClass">
      <div class="col">
        <select name="seletTheme" [(ngModel)]="theme" (change)="setTheme(theme)">
          <option value="default">Default</option>
          <option value="one">Theme 1</option>
          <option value="two">Theme 2</option>
        </select>
      </div>
    </div>
  </div>
</div>

Your code will now be compatible with :host-context(), but remember to include a space after the function, like :host-context(.one) .headerColor. In the provided code snippet, there is no space following the function.

If your intention is solely to modify the color of the nav bar using this method, simply adjust all your theme stylesheets as demonstrated below:

.one .headerColor{
  background-color: chocolate;
}
.two .headerColor{
  background-color: chocolate;
}
.default .headerColor{
  background-color: chocolate;
}

Answer №2

Below is the resolution to your issue:

Follow these steps:

Include a data member in the class:

classNames="default";

Add the host in the component decorator like so:

 @Component({
//Make sure to add host after the template property
        host:{    
            '[class]' : 'classNames' 
          }
    })

Next, modify your setTheme function as shown below:

    setTheme(themeName:string)
      {
//update the host (classNames) dynamically here
      this.classNames=themeName;
      this.theme=themeName;
      }

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

Is there a way to showcase images next to each other within an array in Angular 8, like having 2 images in a row and then another 2 in the next row?

Here is the HTML code I created and tested: <div class="row"> <div *ngFor="let url of urls" class="col-md-6"> <img [src]="url" alt="Image not found" height="250px" width="350px" (click)="imageClick(url)"> </div> < ...

Determining the dimensions of knockout-rendered elements

I've implemented knockout to display a list of clickable elements functioning as radio buttons. However, when too many elements are added horizontally, it overflows off the page. Currently, I'm breaking them into multiple rows, but this doesn&apo ...

Changing the border color of an HTML input is easy with these simple steps:

As part of an educational project, I am developing a login-registration system using HTML, CSS, and PHP. The system will include various HTML text boxes and elements. My goal is to change the border color of a textbox to green when I input something into ...

Is it possible to create dynamic backgrounds using Twitter Bootstrap's responsiveness?

Is there a way to create a responsive image arrangement for backgrounds on a website? Imagine having different background images load based on various screen resolutions. Additionally, it would be advantageous to specify different behaviors such as having ...

The Main Page is always the default destination when navigating with Angular Router

Having an issue with Angular Router (Angular 11). Here is my routing configuration: {path: '', redirectTo: '/login', pathMatch: 'full'} {path: 'login', component: LoginComponent} {path: 'verdicts', componen ...

Ways to modify the alignment of specific inline-block elements inside a DIV

Is there a way to align two inline-block elements to the left and one to the right without changing their display property? I am looking for a CSS solution, but would also consider using jQuery if necessary. In simple terms, I want the first two buttons ...

Continuing the process of uploading the file

In my development of a single page application that allows users to upload photos, I have encountered a dilemma. What happens if a user is uploading multiple photos and then closes the browser? When they log back in, I want the browser to automatically c ...

I need to figure out how to incorporate a specific feature into my personal list by leveraging Javascript

Looking at the list below, it's a simple one that allows users to add and remove items while also changing their order using buttons. However, I want to enhance this feature by removing the "up" button for the first item and the "down" button for the ...

Tips for resolving the issue: "Encountered error loading module script..." in Angular 8 and Electron 5

I have been working on developing an Electron 5 app using Angular 8. Despite following numerous online tutorials, I keep encountering the same error. Initially, I set up a new project and ran ng serve --open, which successfully displayed the default angul ...

What is the process for altering the active color of a materialize icon?

Currently working on a web application for my school project and incorporating the Materialize framework. However, I'm having trouble modifying the default teal color of the active icon. https://i.sstatic.net/9eEfM.jpg ...

Can the styling and variables of Bootstrap4 be altered dynamically?

I have recently started working on a project that utilizes Bootstrap4 for design and layout. However, there is now a need for the ability to change certain core styles (such as font-face, primary color, and background color) dynamically at runtime. Curren ...

Execute an Angular 7 Single Page Application directly through the file:// protocol

I've been diving into tutorials on SPA and client-side routing, but I'm still struggling to grasp it fully. How can I configure the router to function without a web server? For example: file:///C:/cxr/CXR-WebViews/dist/CXR-WebViews/index.html#/p ...

What could be the reason behind the frequent appearance of multiple calls in Fiddler upon initiating a SignalR connection

As I set up a signalr connection from my angular front-end to an Asp.Net Core back-end, multiple calls are being made when starting the connection. The issue arises with the first call not completing, which poses a problem for our end-to-end tests. Attemp ...

Unable to locate external CSS files in Firefox using the absolute file path

On my website, I have included the following line in the <head> section: <link type="text/css" href="C:/myApps/app1/images/css/12.02/main.css" rel="stylesheet" /> Upon viewing the page in Firefox 11.0, it appears that the main.css file is not ...

Ensure that the two background images are identical in size and content

Can someone assist me with achieving vertical equality for two background images like in this example image? Currently, I have the following styling applied: background-repeat: no-repeat, repeat-x, repeat-y; background-position: 925px center; However, t ...

Arrange the items in the Navbar

Can someone please help me with a glitch I'm experiencing that is causing my Navbar items to not align properly? (See Navbar preview) I have attempted to fix it by adjusting the margin and padding manually, but my lack of Bootstrap knowledge has hin ...

Navigate to the homepage section using a smooth jQuery animation

I am looking to implement a scrolling feature on the homepage section using jquery. The challenge is that I want the scrolling to work regardless of the page I am currently on. Here is the HTML code snippet: <ul> <li class="nav-item active"> ...

Animation displayed on page load before running

Is there a way to ensure that my animation runs smoothly without any lag or jankiness, either while the page is loading or immediately after loading? I have attempted to preload the images using a preload tag in the header of my HTML, but unfortunately, t ...

(NG2-CHARTS) Unable to connect to the Chart Type as it is not recognized as a valid property for binding

I encountered an issue with my Chart Component where I am seeing the error message below. I have successfully imported ChartsModule into my app.module.ts file, but I am unsure why this error is occurring? Can't bind to 'ChartType' since ...

Condition-triggered Jquery Sticky navigation dynamically enables scrolling functionality

After successfully implementing a sticky navigation that works flawlessly, I am now looking to make it activate only when the browser width is less than or equal to 770px. This is my current code: $j = jQuery.noConflict(); $j(document).ready(function() ...