Reputation: 621
I have a table with some details. My problem is that in one of the columns I have buttons. For example, I click the button on line 0 but all buttons are enabled. Does anyone know how I can solve this?
Already tried to pass the line number, but so far unsuccessful :(
HTML
<div *dxTemplate="let data of 'cellTemplate'">
<button type="button" data-toggle="dropdown" class="btn ClassPlay">
<img src="./assets/play.svg" *ngIf="currentState=='pause'">
<img src="./assets/playV.svg" *ngIf="currentState=='start'">
</button>
<div class="dropdown-menu">
<a class="dropdown-item" *ngIf="currentState=='pause'" routerLinkActive="active"
(click)="currentState='start'; startTimer(data, data.rowIndex)">Start</a>
<a class="dropdown-item" *ngIf="currentState=='start'" routerLinkActive="active"
(click)="currentState='pause'; pauseTimer((data, data.rowIndex)">Pause</a>
</div>
<span class="timer">{{display}}</span>
</div>
Component.ts
startTimer(data,row) {
this.interval = setInterval(() => {
if (this.time === 0) {
this.time++;
} else {
this.time++;
}
this.display=this.transform( this.time)
}, 1000);
}
transform(value: number): string {
var sec_num = value;
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
return hours+':'+minutes+':'+seconds;
}
pauseTimer(data,row) {
clearInterval(this.interval);
}
What I Tried
<button type="button" data-toggle="dropdown" class="btn ClassPlay">
<img src="./assets/play.svg" *ngIf="currentState=='pause'">
<img src="./assets/playV.svg" *ngIf="currentState=='start' && currentRowIndex === data.rowIndex">
</button>
<div class="dropdown-menu">
<a class="dropdown-item" *ngIf="currentState=='pause'" routerLinkActive="active"
(click)="currentState='start'; startTimer(data)">Start</a>
<a class="dropdown-item" *ngIf="currentState=='start' && currentRowIndex === data.rowIndex" routerLinkActive="active"
(click)="currentState='pause'; pauseTimer(data)">Pause</a>
</div>
<span class="timer">{{currentRowIndex === data.rowIndex ? display : ''}}</span>
startTimer(data) {
this.currentRowIndex = data.rowIndex;
this.interval = setInterval(() => {
if (this.time === 0) {
this.time++;
} else {
this.time++;
}
this.display=this.transform( this.time)
}, 1000);
}
transform(value: number): string {
var sec_num = value;
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
return hours+':'+minutes+':'+seconds;
}
pauseTimer(data) {
this.currentRowIndex = data.rowIndex;
clearInterval(this.interval);
}
The only problem now is that when I click the start button all buttons on the other lines disappear and only reappear on the next line. Time is also wrong, I start the timeline on one line and when I start on the other, the time always keeps adding up and not starting over as it should
Upvotes: 5
Views: 472
Reputation: 593
Based on your code, my assumption is that you are always changing the same variable currentState
. Once you click the Start button (anchor) the first time like here
(click)="currentState='start'; ....//
you are setting the shared variable currentState
to the start value. Therefore all the ngIf
react to it. What you I believe you want to achieve is having something like a boolean value that express the current state for each row in the table.
Update: Here is an example of what I think you want to achieve
<div class="dropdown-menu">
<a class="dropdown-item" *ngIf="currentState=='pause'" routerLinkActive="active"
(click)="startTimer(data.rowIndex)">Start</a>
<a class="dropdown-item" *ngIf="currentState=='start'" routerLinkActive="active"
(click)="pauseTimer()">Pause</a>
</div>
And this should be your Component.ts
public dataArray: Array<DataItem>;
public timeArray: Array<number>;
public interval;
constructor() {
this.dataArray = // constructor of your data
// We create an array to keep track of the time for each element
// and fill the array initially with zeroes
this.timeArray = new Array(this.dataArray.length).fill(0);
}
// We need here to know the index in order to know what timer to increment in the array
startTimer(rowIndex) {
this.interval = setInterval(() => {
this.timeArray[rowIndex]++;
// The display will always show the current ongoing timer
this.display=this.transform(this.timeArray[rowIndex])
}, 1000);
}
pauseTimer(rowIndex) {
// alert(this.timeArray[rowIndex]) <-- just for test
clearInterval(this.interval); // Clears the interval
}
Update 2 From your last update, i believe you want also to show the display for each row. Here how to achieve it
<span class="timer">{{transform(timeArray[rowIndex])}}</span>
as you can see I don't use the display variable, but apply your transform function to the value of the rowIndex
Update 3 The solution to the last problem you posted is the following
.. *ngIf="currentState=='start' && currentRowIndex === data.rowIndex"
the && is returning true only for the current row, therefore only that one is displayed. Remove it like this
.. *ngIf="currentState=='start'"
and to reset the timer for the row when you press pause
pauseTimer(rowIndex) {
this.timeArray[rowIndex] = 0; // Add this line
clearInterval(this.interval); // Clears the interval
}
Upvotes: 1
Reputation: 4453
If I understand correctly your question, I can offer this solution.
<div *dxTemplate="let data of 'cellTemplate'">
<button type="button" data-toggle="dropdown" class="btn ClassPlay">
<img src="./assets/play.svg" *ngIf="currentState=='pause'">
<img src="./assets/playV.svg" *ngIf="currentState=='start' && currentRowIndex === data.rowIndex">
</button>
<div class="dropdown-menu">
<a class="dropdown-item" *ngIf="currentState=='pause'" routerLinkActive="active"
(click)="currentState='start'; startTimer(data, data.rowIndex)">Start</a>
<a class="dropdown-item" *ngIf="currentState=='start' && currentRowIndex === data.rowIndex"routerLinkActive="active"
(click)="currentState='pause'; pauseTimer()">Pause</a>
</div>
<span class="timer">{{currentRowIndex === data.rowIndex ? display : '00'}}</span>
</div>
and in .ts
currentRowIndex = null; // you need to define in your component
startTimer(index) {
this.currentRowIndex = index;
this.interval = setInterval(() => {
if (this.time === 0) {
this.time++;
} else {
this.time++;
}
this.display=this.transform( this.time)
}, 1000);
}
transform(value: number): string {
var sec_num = value;
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
return hours+':'+minutes+':'+seconds;
}
pauseTimer() {
this.currentRowIndex = null;
clearInterval(this.interval);
}
Upvotes: 1