Boris
Boris

Reputation: 5176

How to make click event optional in an angular 2 *ngFor loop

I am making a weekly calendar, where users can click the days of the week in the calendar header to highlight the events on that day:

<thead>
    <tr>
        <td *ngFor="let day of days | async"
            (click)="highlightWeek(day)">{{day.header}}</td>
    </tr>
</thead>

I would like to make it so that when there are no when there are no events on a given day, then the header for that day is not clickable. This could be done in the component like so:

highlightWeek(day) {
    if (day.events.length > 0) {
        ...

But if I do this, then the browser still changes the form of the cursor from the arrow to the hand, whenever the user hovers over the empty day headers. I would like to only have the click event on the days where there are event, so this doesn't happen. Something like this:

<thead>
    <tr>
        <td *ngFor="let day of days | async"
            (if (day.events.length > 0)): (click)="highlightWeek(day)">{{day.header}}</td>
    </tr>
</thead>

But I don't know how to accomplish that.

Upvotes: 2

Views: 2621

Answers (5)

Abhishek Tewari
Abhishek Tewari

Reputation: 425

I came across this internetzer's solution today which conditionally prevents call to the event. logically and a condition with the event like below:

<td *ngFor="let day of days | async" 
  (click)="day.events.length > 0 && highlightWeek(day)">{{day.header}}</td>

Upvotes: 1

Peter Salomonsen
Peter Salomonsen

Reputation: 5683

Put the loop in an ng-container and then you can have one td displaying if it should be clickable and another if not. Like this:

<thead>
 <tr>
    <ng-container *ngFor="let day of days | async">
      <td (click)="highlightWeek(day)" style="cursor: pointer" *ngIf="day.events.length>0">
        {{day.header}}
      </td>
      <td *ngIf="day.events.length===0" style="cursor: default">{{day.header}}</td>
    </ng-container>
 </tr>
</thead>

Upvotes: 4

Piyush Patel
Piyush Patel

Reputation: 1240

create a class to show cursor which you want when there are no events

.no-events:hover{
    cursor:  not-allowed !important;
}

then assign that class in your template

<thead>
   <tr>
       <td [class.no-evets]="day.events.length > 0" *ngFor="let day of days | async"
        (click)="highlightWeek(day)">{{day.header}}</td>
   </tr>
</thead>

with that code your function will be called on click but the cursor will be shown which you defined.

Upvotes: 1

Alex Florin
Alex Florin

Reputation: 431

The cursor changes to pointer because of CSS rules, not because you have a binding on the click event. I think you want something like:

<td *ngFor="let day of days | async" 
    [ngStyle]="{ 'cursor': day.events.length > 0 ? 'pointer' : 'default' }"
    (click)="day.events.length === 0 || highlightWeek(day)">
    {{day.header}}
</td>

Upvotes: 2

Raed Khalaf
Raed Khalaf

Reputation: 2065

you can simply bind the disabled attribute on the td element as follows:

<td *ngFor="let day of days | async"
            (click)="highlightWeek(day)"
            [disabled]='day.events.length > 0? null : true'>
    {{day.header}}
</td>

Upvotes: 1

Related Questions