Looks so simple, yet I don't know how to solve this efficiently.
I have two arrays activeClasses and doneClasses that each contain JavaScript Objects as their elements.
Each element should be able to be marked as "active" or "done" and should be deleted from the current, and added to the other array if its status changes after clicking "Save". How can I achieve this without mixing up my array indices? Behaviour is as expected except when selecting multiple elements:
https://stackblitz.com/edit/angular-etzocz?file=src%2Fapp%2Fapp.component.html
TS
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
activeChanged:Array<boolean> = [];
doneChanged:Array<boolean> = [];
toggleActive(i) {
this.activeChanged[i] = !this.activeChanged[i];
console.log('activeChanged:');
console.log(this.activeChanged);
}
toggleDone(i) {
this.doneChanged[i] = !this.doneChanged[i];
console.log('doneChanged:');
console.log(this.doneChanged);
}
save() {
var activeToBeDeleted:Array<number> = [];
var doneToBeDeleted:Array<number> = [];
//Check if active classes have changed
this.activeChanged.forEach(function (elem, index) {
//Has changed
if (elem) {
this.doneClasses.push(this.activeClasses[index]);
//Add to activeToBeDeleted
activeToBeDeleted.push(index)
}
}.bind(this))
//Check if done classes have changed
this.doneChanged.forEach(function (elem, index) {
//Has changed
if (elem) {
this.activeClasses.push(this.doneClasses[index]);
//Add to doneToBeDeleted
doneToBeDeleted.push(index)
}
}.bind(this))
console.log('before deletion')
console.log(this.activeClasses)
console.log(this.doneClasses)
//Delete array elements that were changed
activeToBeDeleted.forEach(function(elem) {
this.activeClasses.splice(elem,1)
}.bind(this))
doneToBeDeleted.forEach(function(elem) {
this.doneClasses.splice(elem,1);
}.bind(this))
console.log('after deletion')
console.log(this.activeClasses)
console.log(this.doneClasses)
//Rewrite activeChanged and doneChanged arrays again with false
this.activeChanged = new Array(this.activeClasses.length).fill(false)
this.doneChanged = new Array(this.doneClasses.length).fill(false)
}
//As from database
activeClasses:Array<Object> = [
{
name: 'test1'
},
{
name: 'test2'
}
];
doneClasses:Array<Object> = [
{
name: 'test3'
},
{
name: 'test4'
}
];
ngOnInit() {
//Fill activeChanged and doneChanged with false by default
this.activeChanged = new Array(this.activeClasses.length).fill(false)
this.doneChanged = new Array(this.doneClasses.length).fill(false)
}
}
HTML
<div *ngFor="let active_class of activeClasses; let i = index" style="background-color: blue; text-align: center; padding: 20px; color: white;">
<button *ngIf="!activeChanged[i]" (click)="toggleActive(i)">Mark as done</button>
<button *ngIf="activeChanged[i]" (click)="toggleActive(i)">Mark as active</button>
{{ active_class.name }}
</div>
<div *ngFor="let done_class of doneClasses; let i = index" style="background-color: red; text-align: center; padding: 20px; color: white;">
<button *ngIf="!doneChanged[i]" (click)="toggleDone(i)">Mark as active</button>
<button *ngIf="doneChanged[i]" (click)="toggleDone(i)">Mark as done</button>
{{ done_class.name }}
</div>
<button (click)="save()">Save</button>