aboutsummaryrefslogtreecommitdiffstats
path: root/src/angular/checklist
diff options
context:
space:
mode:
Diffstat (limited to 'src/angular/checklist')
-rw-r--r--src/angular/checklist/checklist.component.html.ts15
-rw-r--r--src/angular/checklist/checklist.component.ts50
-rw-r--r--src/angular/checklist/checklist.module.ts11
-rw-r--r--src/angular/checklist/models/Checklist.ts18
-rw-r--r--src/angular/checklist/models/ChecklistItem.ts17
5 files changed, 111 insertions, 0 deletions
diff --git a/src/angular/checklist/checklist.component.html.ts b/src/angular/checklist/checklist.component.html.ts
new file mode 100644
index 0000000..cb6f540
--- /dev/null
+++ b/src/angular/checklist/checklist.component.html.ts
@@ -0,0 +1,15 @@
+export default `
+<div *ngFor="let checkbox of checklistModel.checkboxes" #currentCheckbox>
+ <div class="checkbox-item">
+ <sdc-checkbox [label]="checkbox.label"
+ [(checked)]="checkbox.isChecked"
+ [disabled]="checkbox.disabled"
+ (checkedChange)="checkboxCheckedChange(checkbox, checklistModel)"
+ [ngClass]="{'semi-checked': !checkbox.isChecked && hasCheckedChild(currentCheckbox)}"></sdc-checkbox>
+ </div>
+ <div *ngIf="checkbox.subLevelChecklist" class="checkbox-sublist">
+ <sdc-checklist [checklistModel]="checkbox.subLevelChecklist"
+ (checkedChange)="childCheckboxChange($event, checkbox)"></sdc-checklist>
+ </div>
+</div>
+`;
diff --git a/src/angular/checklist/checklist.component.ts b/src/angular/checklist/checklist.component.ts
new file mode 100644
index 0000000..386cd3e
--- /dev/null
+++ b/src/angular/checklist/checklist.component.ts
@@ -0,0 +1,50 @@
+import { Component, EventEmitter, Input, Output } from "@angular/core";
+import { ChecklistModel } from "./models/Checklist";
+import { ChecklistItemModel } from "./models/ChecklistItem";
+import template from "./checklist.component.html";
+
+@Component({
+ selector: 'sdc-checklist',
+ template: template
+})
+export class ChecklistComponent {
+ @Input() public checklistModel: ChecklistModel;
+ @Output() public checkedChange: EventEmitter<ChecklistItemModel> = new EventEmitter<ChecklistItemModel>();
+
+ private checkboxCheckedChange(checkbox: ChecklistItemModel, currentChecklistModel: ChecklistModel, stopPropagation?: boolean) {
+ // push/pop the checkbox value
+ if (checkbox.isChecked) {
+ currentChecklistModel.selectedValues.push(checkbox.value);
+ }else {
+ const index: number = currentChecklistModel.selectedValues.indexOf(checkbox.value);
+ currentChecklistModel.selectedValues.splice(index, 1);
+ }
+ if (!stopPropagation) {
+ if (checkbox.subLevelChecklist &&
+ ((checkbox.isChecked && checkbox.subLevelChecklist.selectedValues.length < checkbox.subLevelChecklist.checkboxes.length) ||
+ (!checkbox.isChecked && checkbox.subLevelChecklist.selectedValues.length))) {
+ checkbox.subLevelChecklist.checkboxes.forEach((childCheckbox: ChecklistItemModel) => {
+ if (childCheckbox.isChecked !== checkbox.isChecked) {
+ childCheckbox.isChecked = checkbox.isChecked;
+ this.checkboxCheckedChange(childCheckbox, checkbox.subLevelChecklist);
+ }
+ });
+ }
+ }
+ // raise event
+ this.checkedChange.emit(checkbox);
+ }
+
+ private childCheckboxChange(updatedCheckbox: ChecklistItemModel, parentCheckbox: ChecklistItemModel) {
+ let updatedValues: any[] = parentCheckbox.subLevelChecklist.selectedValues;
+ if (parentCheckbox.isChecked !== (updatedValues.length === parentCheckbox.subLevelChecklist.checkboxes.length)) {
+ parentCheckbox.isChecked = updatedValues.length === parentCheckbox.subLevelChecklist.checkboxes.length;
+ this.checkboxCheckedChange(parentCheckbox, this.checklistModel, true);
+ }
+ this.checkedChange.emit(updatedCheckbox);
+ }
+
+ private hasCheckedChild(currentCheckbox: Element): boolean {
+ return !!currentCheckbox.querySelector(".sdc-checkbox__input:checked");
+ }
+}
diff --git a/src/angular/checklist/checklist.module.ts b/src/angular/checklist/checklist.module.ts
new file mode 100644
index 0000000..013bf9b
--- /dev/null
+++ b/src/angular/checklist/checklist.module.ts
@@ -0,0 +1,11 @@
+import { NgModule } from "@angular/core";
+import { ChecklistComponent } from "./checklist.component";
+import { CommonModule } from "@angular/common";
+import { FormElementsModule } from "../form-elements/form-elements.module";
+
+@NgModule({
+ declarations: [ChecklistComponent],
+ exports: [ChecklistComponent],
+ imports: [CommonModule, FormElementsModule]
+})
+export class ChecklistModule {}
diff --git a/src/angular/checklist/models/Checklist.ts b/src/angular/checklist/models/Checklist.ts
new file mode 100644
index 0000000..7b50dd3
--- /dev/null
+++ b/src/angular/checklist/models/Checklist.ts
@@ -0,0 +1,18 @@
+import { ChecklistItemModel } from "./ChecklistItem";
+
+export class ChecklistModel {
+ public selectedValues: any[];
+ public checkboxes: ChecklistItemModel[];
+ constructor(selectedValues: any[], checkboxes: ChecklistItemModel[]) {
+ this.selectedValues = selectedValues || [];
+ this.checkboxes = checkboxes;
+ // align the selected values list and checkboxes isChecked param
+ this.checkboxes.forEach((checkbox: ChecklistItemModel) => {
+ if (this.selectedValues.indexOf(checkbox.value) > -1) {
+ checkbox.isChecked = true;
+ }else if (checkbox.isChecked) {
+ this.selectedValues.push(checkbox.value);
+ }
+ });
+ }
+}
diff --git a/src/angular/checklist/models/ChecklistItem.ts b/src/angular/checklist/models/ChecklistItem.ts
new file mode 100644
index 0000000..e2d812a
--- /dev/null
+++ b/src/angular/checklist/models/ChecklistItem.ts
@@ -0,0 +1,17 @@
+import { ChecklistModel } from "./Checklist";
+import { isUndefined } from "util";
+
+export class ChecklistItemModel {
+ public label: string;
+ public value: any;
+ public disabled: boolean;
+ public isChecked: boolean;
+ public subLevelChecklist: ChecklistModel;
+ constructor(label: string, disabled?: boolean, isChecked?: boolean, subLevelChecklist?: ChecklistModel, value?: any) {
+ this.label = label;
+ this.disabled = disabled;
+ this.isChecked = isChecked;
+ this.value = isUndefined(value) ? label : value;
+ this.subLevelChecklist = subLevelChecklist;
+ }
+}