I'm working on a appointment booking app, where I'm displaying time slots for appointments using *ngFor to loop.
html
<div *ngFor="let item of allTimeSlots">
<div class="col-sm-3">
<div class="choice" data-toggle="wizard-slot" [attr.disabled]="item.status" (click)="slotSelected($event)">
<input type="radio" name="slot" value="{{item.timeSlot}}">
<span class="icon">{{item.timeSlot}}</span> {{item.status}}
</div>
</div>
</div>
typescript
for (var index = 0; index < this.totalMinutes; index += 15, i++) {
this.allTimeSlots[i] = new allTimeSlots("", false);
this.allTimeSlots[i].timeSlot = (hour <= 12 ? hour : hour - 12) + ":" + (minute <= 9 ? ("0" + minute) : minute) + " " + ampm;
this.bookedTimeSlots.forEach(element => {
if (this.allTimeSlots[i].timeSlot == element) {
this.allTimeSlots[i].status = true;
}
});
}
Here's screen shot of time slots which displays true if the time slot is booked and false if available for debugging purpose.

When I run this code it doesn't throw any error but all the div elements created by *ngFor are disabled. I tried to use *ngIf instead of disabled, it works pretty well. But the problem is I want to display whether the time slot is available or not.
Div element cannot be disabled like form controls. You can disable form controls in div instead.
To disable elements just use attribute disabled rather than true or false. To enable it again, you need to remove the disabled attribute. In your code [attr. disabled] is setting the value to true or false, what you need is just use [disabled] instead of [attr.
The syntax is *ngFor="let <value> of <collection>" . <value> is a variable name of your choosing, <collection> is a property on your component which holds a collection, usually an array but anything that can be iterated over in a for-of loop.
document. getElementById(divID). style['pointer-events'] = 'none'; The above code disabled all the children properly.
Disabled cannot be used for a div element and only applied to the below elements
<button>
<fieldset>
<input>
<keygen>
<optgroup>
<option>
<select>
<textarea>
See this
So for your issue, you can handle it by using:
<div
class="choice"
data-toggle="wizard-slot"
[class.disabled]="item.status"
(click)="slotSelected($event)">
<input
type="radio"
name="slot"
value="{{item.timeSlot}}"
[disabled]="item.status">
<span class="icon">{{item.timeSlot}}</span> {{item.status}}
</div>
and you should be adding styles
.disabled {
cursor: not-allowed;
}
Use [disabled] instead of [attr.disabled]
This is because [attr.disabled]="false" will add disabled="false" to the element which in html, will still disable the element
<button>Not Disabled</button>
<button [disabled]="false">Not Disabled</button>
<button disabled></button>
<button disabled="true"></button>
<button disabled="false"></button>
<button [attr.disabled]="true"></button>
<button [attr.disabled]="false"></button>
<button [disabled]="true"></button>
disabled will disable an element whether it is true or false, it's presence means that the element will be disabled. Angular will not add the disabled element at all for [disabled]="variable" if variable is false.
As you mentioned in your comment, you are using div elements and not buttons, which angular 2 doesn't recognise the disabled element of. I would recommend using a button if you are going to be capturing click events but if not you could do something like:
<div [ngClass]="{ 'disabled': item.status }"></div>
and have a CSS class to show the time slot as booked.
More information on [ngClass] is available in the documentation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With