Skip to content

Commit 21dae8c

Browse files
author
Daniel Latimer
committed
Support IE Indeterminate checkboxes for "All" option
IE handles indeterminate checkboxes "differently", it doesn't fire an onChange event when a checkbox goes from indeterminate to a determinate state. This issue is well documented on the jquery github issue: jquery/jquery#1698 The generally accepted solution is to use the onClick event instead of the onChange event. You can see this solution implemented in the google's angular material design library in their github link here: angular/components#3145 I applied a similar approach to normalize the events we listen to for the indeterminate all checkbox and commented why those things are done in the code so this issue won't regress.
1 parent f20b3e4 commit 21dae8c

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

src/lib/treeview.component.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
<div *ngIf="config.hasAllCheckBox || config.hasCollapseExpand" class="row row-all">
2424
<div class="col-12">
2525
<div class="form-check">
26-
<input type="checkbox" class="form-check-input" [(ngModel)]="item.checked" (ngModelChange)="onCheckedChange()" [indeterminate]="item.indeterminate"
27-
/>
26+
<input type="checkbox" class="form-check-input" [(ngModel)]="item.checked" [indeterminate]="item.indeterminate" (click)="onCheckedChange()"/>
2827
<label *ngIf="config.hasAllCheckBox" class="form-check-label" (click)="item.checked = !item.checked; onCheckedChange()">
2928
{{i18n.getAllCheckboxText()}}
3029
</label>

src/lib/treeview.component.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,34 @@ export class TreeviewComponent implements OnChanges {
100100
this.updateFilterItems();
101101
}
102102

103+
/**
104+
* IE has an issue where it does not send a change event for when an indeterminate checkbox changes to become determinate.
105+
* To work around this we explicity set it checked if it's indeterminate and we use the onClick event instead of onChange.
106+
*/
103107
onAllCheckedChange() {
104-
const checked = this.allItem.checked;
105-
this.filterItems.forEach(item => {
106-
item.setCheckedRecursive(checked);
107-
if (item instanceof FilterTreeviewItem) {
108-
item.updateRefChecked();
108+
this.standardizeEventOrder(() => {
109+
if (this.allItem.indeterminate) {
110+
this.allItem.checked = true;
109111
}
110-
});
111112

112-
this.raiseSelectedChange();
113+
const checked = this.allItem.checked;
114+
this.filterItems.forEach(item => {
115+
item.setCheckedRecursive(checked);
116+
if (item instanceof FilterTreeviewItem) {
117+
item.updateRefChecked();
118+
}
119+
});
120+
121+
this.raiseSelectedChange();
122+
})
123+
}
124+
125+
/**
126+
* IE performs the onClick event before the onChange event while Chrome and perform it in the other order.
127+
* By pushing the callback onto the event queue it will always be executed immediately after all pending events
128+
*/
129+
standardizeEventOrder(callback) {
130+
setTimeout(callback, 0);
113131
}
114132

115133
onItemCheckedChange(item: TreeviewItem, checked: boolean) {

0 commit comments

Comments
 (0)