Drew13 Drew13 - 12 days ago 4
TypeScript Question

Angular2 revert table row's color back to original after deletion

Using Angular2, I have a striped table on my main page that when you click a row it changes color and when clicked again, goes back to the original color. When a row is currently clicked you can delete it. My problem is that when I delete a row that isn't the last row, after that row is deleted the row that was after it has the changed color.

For example, if I click and delete row 2, after deletion of row 2, row 3 is highlighted with the changed color. What I want is for no row to be highlighted after a deletion. Keep in mind that row 3 simply is being shown as clicked by having the highlighted color but in the code no row is programmatically represented as highlighted.

HTML from my main page where the table is (

#015939
green is my highlight color, even rows are
white
by default, odd rows are
#d3d3d3
grey by default) followed by the tag for the delete button child component with selector
deletebutton
:

mainpage.component.html


<tr *ngFor="let dPoint of theData; let idx=index; let even=even" (click)="onClick(dPoint, idx)" (row)="received($event)"
[style.backgroundColor]="clickedRow == idx ? '#015939' : (even ? 'white' : '#d3d3d3')" [style.color]="clickedRow == idx ? 'white' : '#015939'">
<td>{{dPoint.tDataPoint}}</td>
<td>{{dPoint.tICCP}}</td>
<td>{{dPoint.tStartDate}}</td>
<td>{{dPoint.tEndDate}}</td>
</tr>

<deletebutton [receivedRow]='toSend'></deletebutton>


HTML for the button that deletes the row that was clicked

deletebutton.component.html


//this HTML is represented by using deletebutton tag above
<button type="submit" class="btn" data-dismiss="modal" (click)="delete()" class="btn icon-trash tableButton"></button>


Typescript function from my main page that emits the row that was clicked:

@Component({
selector: 'main-page',
styleUrls: ['../app.component.css'],
templateUrl: 'mainpage.component.html'
})


export class MainPageComponent implements OnInit {

clickedRow:number;
toSend:DataTable;
@Output() row: EventEmitter<any> = new EventEmitter<any>();

onClick(message:DataTable, idx:any){
let d = message.tDataPoint;
let i = message.tICCP;
let s = message.tStartDate;
let e = message.tEndDate;
if(this.clickedRow == idx) {
this.clickedRow = -1;
this.toSend = null;
} else {
this.clickedRow = idx;
this.toSend = new DataTable(d, i, s, e);
}
this.row.emit(this.toSend);
}


Typescript function to delete the clicked row (a child component of my main page):

@Component({
selector: 'deletebutton',
templateUrl: './deletebutton.component.html',
styleUrls: ['../app.component.css']
})
export class DeletebuttonComponent implements OnInit {
@Input() receivedRow:DataTable;

delete(){
var count = 0;
var length = DPS.length;
if (this.receivedRow != null) {
for (let entry in DPS) {
if (DPS[entry].tDataPoint === this.receivedRow.tDataPoint) {
DPS.splice(parseInt(entry), 1);
} else if ((count === (length-1)) && (DPS[entry].tDataPoint !== this.receivedRow.tDataPoint)) {
alert("Please select a row first");
} else if (count !== length) {
count = count + 1;
}
}
}
}
}


Table before anything is clicked or deleted:
enter image description here

Table After row 2 is selected:
enter image description here

Table after row 2 is deleted:
enter image description here

I need the table to only be white and grey rows after deleting a row. Notice how in the 3rd screenshot, the new row 2 (which used to be row 3) is highlighted

I've tried working with
@Input
and
@Output
to somehow send the row that will be highlighted after deletion of the previous row to change
this.clickedRow
but can't seem to nail down the logic.

Answer

You don't even need to use deletebutton in mainpage.component.html. Just replace it with the HTML for the button.

<button type="submit" class="btn" data-dismiss="modal" (click)="delete()" class="btn icon-trash tableButton"></button>

Then move your delete function from deletebutton Typescript to your mainpage Typescript and add the line this.clickedRow = -1; and change receivedRow to toSend like this

delete(){
  var count = 0;
  var length = DPS.length;
  if (this.toSend != null) {
    for (let entry in DPS) {
      if (DPS[entry].tDataPoint === this.toSend.tDataPoint) {
        DPS.splice(parseInt(entry), 1);
        this.clickedRow = -1;
        this.deleted = true;
      } else if ((count === (length-1)) && (DPS[entry].tDataPoint !== this.toSend.tDataPoint)) {
        alert("Please select a row first");
      } else if (count !== length) {
        count = count + 1;
      }
    }
  }
}  

This way, after selecting a row and clicking the button, the delete function gets called from the same Typescript instead of having to work between two separate components.

Comments