Change color of row items and/or buttons using arrays

So I have an idea for a little scrabble-like word game.

I have an array of strings such as

 this.tilerows = [
      ['a', 'b', 'c', 'etc', ' '],
      [' ', ' ', ' ', ' ', ' '],
      [' ', ' ', ' ', ' ', ' '], etc.

which I use to populate a grid of button items thus

<ion-row *ngFor="let list of tilerows; let i=index">
  <ion-col *ngFor="let t of list;let j=index">
      <button ion-button color="dark" outline  (click)="tileClick(i,j)" class="tileButton">{{t}}</button>  
 <!--ion-item color="{{tilerowsStatus(i,j)}}" (click)="tileClick(i,j)" >
     {{t}}
 </ion-item-->
</ion-col>
</ion-row>
 </ion-grid>

When any button on the grid is clicked the procedure tileClick(i,j) successfully updates the button’s string with the contents of this.tilerowsp[i][j]

image

What I want to do next is change the button’s color if it belongs to a correct answer (i.e. part of a legitimate word) before I ask scrabble fans in the family if it is at all fun to play. I can do the dictionary checking ok, but I haven’t found a solution to change the color of the button.

Remnants of my attempt are in the commented out part of the code above. I made a second array of the same dimensions called tilerowsStatus with color strings in it thus:

this.tilerowsStatus = [
    ['primary','dark','dark','dark','dark'],
    ['dark','light','dark','dark','dark'],
    ['dark','dark','dark','dark','dark'],

But nothing I do in the html will make it change color. I’ve tried a few ideas from the forums but nothing is working - the other examples don’t relate to arrays or ngFors.

Any ideas of links appreciated.

What about this:

<ion-item [color]="tilerowsStatus[i][j]" (click)="tileClick(i,j)" >

https://angular.io/api/common/NgStyle

1 Like

Thanks I’ve been playing with your suggestions.

<ion-item [color]="tilerowsStatus[i][j]" (click)="tileClick(i,j)" >

this doesnt do anything, but looks like it should eh?

NgStyle looks like the ticket, but…

<button ion-button [ngStyle]="{'background-color': tilerowsStatus(i,j)} " (click)="tileClick(i,j)" class="tileButton">{{t}}</button>  

Crashes, as does every other way I can think to reference the contents of tilerowsStatus. In this case the error message is "tilerowsStatus"is not a function - obviously trying to call a function with i,j as the parameters.

Without indeces it runs but doesn’t do anything. Same with square brackets.

The following code works to set all buttons the same color - buttonColor is set in the code to be “green” or “red”. (Can’t use the ionic “dark”, “light” etc.).

<button ion-button [ngStyle]="{'background-color': buttonColor} " (click)="tileClick(i,j)" class="tileButton">{{t}}</button>  

So NgStyle can access the value of buttonColor, but I can’t work out how to use i and j to access the contents of the 2D array.

Try to write a function where you pass i and j into and return the color name as string.

Use this function in the ngstyle.

Thanks Jacktoolsnet. That works for me now :slight_smile:

That’s a major help.

Don’t ever call functions from template expressions that are evaluated by change detection. It’s terribly inefficient. @hariman’s suggestion is vastly superior here: store the status in a multidimensional array and modify that array when something changes. That way Angular can do its job much better.

Yes the array should work too. Perhaps it was just a typo.

I can’t get the array first suggestion to work - e.g. adding to your code as below tells me - “Can’t bind to ‘color’ since it isn’t a known property of ‘button’.”

export class AppComponent {
  name = 'Angular';
  colors = ['green', 'red', 'yellow', 'blue'];
<button *ngFor="let color of colors; let i = index"; [color]="colors[i]">
	{{color}}
</button>

https://angular-t1q7rd.stackblitz.io

I modified my stackblitz.

Does [attr.color] work differently from [color]?

Yes [attr.color] doesn’t crash :slight_smile:

But it doesn’t show buttons!

Thanks it seems the array with ngstyle is the best working solution.