Dynamically change navbar color

#1

Hi,

I’m trying to dynamically style the nav-bar of the ionic 2 app i’m writing.

<ion-navbar class="girl" *navbar>
    <ion-title>Hallo {{userName}}!</ion-title>
</ion-navbar>

In css I have the class:

.girl {
  background-color: #E91E63;
}

This works fine for a button or any other element, but the navbar flashes purple briefly and then goes back to the default color. I’'ve tried adding the class in “onPageDidEnter()” but this does not work.

Any help to get me on the right track would be appreciated.

Thanks !

Changing button color or icon dynamically
#2

Hi @yannickvg,

From what I got for answer, there is no easy way. What I have done is this

<ion-navbar id="girl" *navbar>
    <ion-title>Hallo {{userName}}!</ion-title>
</ion-navbar>

In your ts file

  ngAfterViewInit() {
    this._app.getComponent('girl').elementRef.nativeElement.setAttribute('put the color you want here", true);
  }

In my app, I am using it because I want to change the navbar color dependently of what the user will do and it works fine. I would prefer to have something like below, but it is not implemented yet

 <ion-navbar [color]="theColor" *navbar>
    <ion-title>Hallo {{userName}}!</ion-title>
</ion-navbar>
1 Like
#3

Hi @icarus_31,

Thanks for your reply. While it is indeed not ideal, your solution works like a charm!

Your proposed syntax would be nice, let’s hope it gets implemented someday.

#4

So a simpler solution would be to use attributes instead of classes in this case.

So you could add a new property in your colors variable in app/theme/app.variables.scss

$colors: (
  primary:    #387ef5,
  secondary:  #32db64,
  danger:     #f53d3d,
  light:      #f4f4f4,
  dark:       #222,
  favorite:   #69BB7B,
  girl: #E91E63
);

Then you could do

<ion-navbar girl *navbar>
    <ion-title>Hallo {{userName}}!</ion-title>
</ion-navbar>

And it would apply the correct colors.

3 Likes
#5

Hi @mhartington,

This will work if you want that specific color for that specific nav-bar. If you need something that will change depending of something else, then there is no easy way for now to do that, right?

1 Like
#6

@mhartington

Your solution would be perfect if we could make the attribute somehow dynamic, based on some value.
I tried that in the beginning but never managed to do it.

If you know a way, I would be happy to learn it !

thanks,

Yannick

#7

I have a good solution: multiple ion-nav-bar

`<ion-navbar *navBar green *ngIf="greenCondition">
</ion-navbar>

<ion-navbar *navBar yellow  *ngIf="yellowCondition">
</ion-navbar>

<ion-navbar *navBar black *ngIf="blackCondition">
</ion-navbar>

<ion-navbar *navBar purple *ngIf="purpleCondition">
</ion-navbar>

`

but this solution become weird things for much more than 4 condition. After 4th ion-navbar header (5th in-navbar) showns under main page headerbar. I can not handle this.

#8

With beta 7, the solution below is not more working

this._app.getComponent(‘girl’).elementRef.nativeElement.setAttribute('put the color you want here", true);

Any clue?

The error is:

ORIGINAL EXCEPTION: TypeError: Cannot read property 'elementRef' of undefined

1 Like
#9

@icarus_31, @yannickvg:

You might be interested in this approach. I think you would be able to combine it with @mhartington’s suggestion of custom attributes to localize all DOM-fiddling to a single directive, getting it out of your application controller code.

import {Directive, Input, ElementRef, OnChanges, SimpleChange} from '@angular/core';

@Directive({
  selector: '[blankAttr]'
})
export class BlankAttr implements OnChanges {
  private _elem: HTMLElement;
  @Input('blankAttr') attrName:string;

  constructor(eref: ElementRef) {
    this._elem = eref.nativeElement;
  }

  ngOnChanges(changes: {[key: string]: SimpleChange}):void {
    let change = changes['attrName'];
    let pv = change.previousValue;
    if (pv) {
      this._elem.removeAttribute(pv);
    }
    this._elem.setAttribute(change.currentValue, '');
  }
}
import {BlankAttr} from "../../directives/blankattr";

@Page({
  templateUrl: 'build/pages/page1/page1.html',
  directives: [BlankAttr]
})
export class MyPage {
  navbarTheme:string;
  
  setNavbarTheme(theme:string): void {
    this.navbarTheme = theme;
  }
}
<ion-navbar *navbar [blankAttr]="navbarTheme">
  <ion-title>a page title</ion-title>
  <button>hello world</button>
</ion-navbar>
<ion-content padding>
  <button (click)="setNavbarTheme('primary')">primary</button>
  <button (click)="setNavbarTheme('secondary')">secondary</button>
  <button (click)="setNavbarTheme('dark')">dark</button>
  <button (click)="setNavbarTheme('light')">light</button>
  <button (click)="setNavbarTheme('danger')">danger</button>
</ion-content>
5 Likes
#10

Just to let you know that it is working as expected! Big thanks @rapopos

After upgrade to beta 7, this.app.getComponent returns undefined
#11

Update: the color attribute has been added to several components including the navbar and will be in the beta 12 release. See this issue for more information: https://github.com/driftyco/ionic/issues/7467

Make sure to check the changelog when beta 12 is released and follow the steps to upgrade. :slight_smile:

2 Likes
#12

Awesome news, this seems exactly how i wanted it to work!

Thanks, looking forward to the beta 12!

1 Like
#13

Works as expected! Thanks.

#14

Can I use the color attribute with colors that I don’t know ahead of time, i.e. colors that will be set dynamically by the user, or pulled from a database? Or do they have to be predefined SASS variables? I was expecting something like:

[color]="someColorSetByUser()"

3 Likes
#15

did you solve this ? @patrickmcd
i am running into the same issue
receiving the colors from an api

#16

Hello,
in prinziple you can use [style.color]=‘somecolor’. Somecolor is a variable holding a string representing a color like rgb(73, 2, 37).

You can use also ngstyle. With ngstyle you must take care how , and ‘’ are set.

Maybe this helps. https://scotch.io/tutorials/angular-2-classes-with-ngclass-and-ngstyle

How you show your user a color picker and make variable content persistent is the next callange.

Best regards, anna-liebt

1 Like
#17

thank you, this helped me.

#18

I solved this by using ngStyle and overriding a css class:

  <ion-navbar [ngStyle]="{'background-color': color}">
    <ion-title>{{name}}</ion-title>
  </ion-navbar>

The color value is dynamically set in the component.

  .toolbar-background {
    background: none;
  }

Hopes it helps anybody!

3 Likes
#19

I love you so much! LOL

#20

this worked for me, thank you