-1

UPDATE: I have read that in Angular, you cannot manipulate the DOM. What are you supposed to do then, what is best practice? I have tried using a timeout, NgZone, ChangeDetectionStrategy.OnPush, ChangeDetectorRef detectChanges() all with no success.

I have an html img element:

<img class="selected" id="icon-image-{{item.id}}" src="{{item.icon}}" height="75" width="75" />

and some sccs:

img.selected {
    -webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */
    filter: grayscale(100%);
}

When this loads, it applies the selected class, and makes the image grey as expected.

However, when I run the following typescrpt the image just stays grey:

let imgEl: HTMLElement = document.getElementById('icon-image-' + subCategoryModel.id);
imgEl.className = "";

When I log the className, it shows selected is there before, and has been removed after.

console.log(imgEl.classList);

Any ideas why, even though I remove a className, the style is not reflected?

When I look at the source code, it is not updating the DOM, but imgEl.classList is being changed. Do you know why?

Thanks

UPDATE:

Something strange, if I change the className in the DOM manually (in Firebug for example), it reflects the change. However, as soon as I click the image, it updates to what the original value was. It is as if the DOM is being refreshed.

If this is the case, then how is it possible to update the DOM dynamically? Because the DOM refresh just overwrites all changes.

Html

  <ion-row *ngFor="let trio of getTriples()">
    <ion-col *ngFor="let item of trio" (click)="itemTapped(item)">
      <center>
      <div class="row responsive-md">
        <img class="selected" id="icon-image-{{item.id}}" src="{{item.icon}}" height="75" width="75" />
      </div>
      </center>
    </ion-col>
  </ion-row>

Typescript

  itemTapped(subCategoryModel: SubCategoryModel) {
    let idx: number = this.isInArray(this.employeeModel.subCategories, subCategoryModel);
    let imgEl: HTMLElement = document.getElementById('icon-image-' + subCategoryModel.id);
    if (idx >= 0) {
      this.employeeModel.subCategories.splice(idx, 1);
      imgEl.setAttribute("class", "");
    } else {
      this.employeeModel.subCategories.push(subCategoryModel);
      imgEl.setAttribute("class", "selected");
    }
    console.log('icon-image-'+subCategoryModel.id+' ('+imgEl.id+'): ' + document.getElementById('icon-image-' + subCategoryModel.id).className);
  }
Richard
  • 8,193
  • 28
  • 107
  • 228
  • You'll need to create an [mcve]. Fundamentally, clearing `className` will remove all classes from an element, and thus remove any styling applied by those classes. – T.J. Crowder Aug 03 '16 at 17:37
  • "When I look at the source code, it is not updating the DOM, but imgEl.classList is being changed. Do you know why?" If you view source code in Firefox, you get the initial state of the page, not the latest, so any changes through JS are not reflected. I think Chrome may give you the latest. At any rate, if you just open the developer tools, that would be a live view of what the effectively HTML is. – VLAZ Aug 03 '16 at 17:47
  • Thanks, I will try in Chrome. I have added an UPDATE to the question I ask that says that the DOM seems to be reset. p.s. I am using Ionic 2. – Richard Aug 03 '16 at 17:58
  • Tried it in Chromes Developer Tools, and the DOM does not change when `imgEl.setAttribute("class", "");` is executed. – Richard Aug 03 '16 at 18:01
  • Is this a scope issue, am I updating the wrong document? What's the answer, I'm confused. Appreciate any help. I do a simplified version in jsfiddle and it works, so I think this maybe has something to do with Ionic2? – Richard Aug 03 '16 at 18:08
  • How do you do `$scope.$apply()` in Ionic2 typescript? – Richard Aug 03 '16 at 18:51

3 Answers3

1

This is a solution:

html

      <img class="item-stable" id="icon-image-{{item.id}}" src="{{item.icon}}" height="75" width="75" (click)="toggleItem(item)" [class.item-selected]="item === itemShown"/>

ts

  isItemShown(item: SubCategoryModel) {
    return this.itemShown === item;
  }

  toggleItem(item: SubCategoryModel) {
    if (this.isItemShown(item)) {
      this.itemShown = null;
    } else {
      this.itemShown = item;
    }
  }
Richard
  • 8,193
  • 28
  • 107
  • 228
0

Try assigning a deselected class to the element.

Add the required css to that.

Somewhat like this

let imgEl: HTMLElement = document.getElementById('icon-image-' subCategoryModel.id);
imgEl.className = "deselected";

css

img.deselected {
  /* your css here */
}
Vishak Kavalur
  • 449
  • 1
  • 5
  • 12
0

You can try using ng-class.

Documentation here

A simple example

Vishak Kavalur
  • 449
  • 1
  • 5
  • 12