From 070d6081ba1871c8684c6b8ed65cd691ec4ecf21 Mon Sep 17 00:00:00 2001 From: heli-Berry Date: Thu, 12 Dec 2024 10:14:54 +0100 Subject: [PATCH] =?UTF-8?q?Issue=20#521:=20lux-stepper-large:=20die=20weit?= =?UTF-8?q?er/zur=C3=BCck-Buttons=20des=20Steppers=20sollen=20auf=20"aria-?= =?UTF-8?q?disabled"=20umgestellt=20werden.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stepper-large-example-data.service.ts | 2 + .../stepper-large-example.component.html | 25 ++++++++++- .../stepper-large-example.component.ts | 15 +++++++ ...rge-example-step-fin-button.component.html | 9 ++++ ...large-example-step-fin-button.component.ts | 8 ++++ ...ge-example-step-next-button.component.html | 9 ++++ ...arge-example-step-next-button.component.ts | 8 ++++ ...ge-example-step-prev-button.component.html | 9 ++++ ...arge-example-step-prev-button.component.ts | 8 ++++ ...r-large-extern-step-example.component.html | 9 ++++ ...per-large-extern-step-example.component.ts | 12 ++++- .../lux-stepper-large.component.html | 6 ++- .../lux-stepper-large.component.ts | 44 ++++++++++++++----- 13 files changed, 148 insertions(+), 16 deletions(-) diff --git a/src/app/demo/components-overview/stepper-large-example/stepper-large-example-data.service.ts b/src/app/demo/components-overview/stepper-large-example/stepper-large-example-data.service.ts index 23c75d20..8fc69744 100644 --- a/src/app/demo/components-overview/stepper-large-example/stepper-large-example-data.service.ts +++ b/src/app/demo/components-overview/stepper-large-example/stepper-large-example-data.service.ts @@ -5,6 +5,7 @@ import { LUX_STEPPER_LARGE_DEFAULT_NEXT_BTN_CONF, LUX_STEPPER_LARGE_DEFAULT_PREV_BTN_CONF } from '../../../modules/lux-layout/lux-stepper-large/lux-stepper-large-model/lux-stepper-large-button-info'; +import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; @Injectable({ providedIn: 'root' @@ -14,6 +15,7 @@ export class StepperLargeExampleDataService { nextButtonConfig: LuxStepperLargeButtonInfo = JSON.parse(JSON.stringify(LUX_STEPPER_LARGE_DEFAULT_NEXT_BTN_CONF)); finButtonConfig: LuxStepperLargeButtonInfo = JSON.parse(JSON.stringify(LUX_STEPPER_LARGE_DEFAULT_FIN_BTN_CONF)); luxStepValidationActive = true; + showErrorMessage = new BehaviorSubject(false); constructor() {} } diff --git a/src/app/demo/components-overview/stepper-large-example/stepper-large-example.component.html b/src/app/demo/components-overview/stepper-large-example/stepper-large-example.component.html index 2a04fd0e..44c5667b 100644 --- a/src/app/demo/components-overview/stepper-large-example/stepper-large-example.component.html +++ b/src/app/demo/components-overview/stepper-large-example/stepper-large-example.component.html @@ -2,12 +2,14 @@

Beispiel für lux-stepper-large

@@ -18,6 +20,12 @@

Validierung

Weiter-Button immer aktiv und nur die Veto-Funktionen können das Navigieren zum nächsten Schritt verhindern.

+ +

+ Um die Barrierefreiheit zu verbessern kann anstatt den Weiter Button zu deaktivieren, das Attribut + aria-disabled verwendet werden. Der Button bleibt immer aktiv, es wird jedoch bei einem Fehler im Schritt nicht weiter + navigiert und ein Output-Event wird geworfen. +

Füllschritte 1 bis 5

@@ -44,7 +52,22 @@

Einwilligung

class="lux-max-width-96" > - + + + +

Bitte korrigieren oder vervollständigen Sie Ihre Angaben in den gekennzeichneten Feldern, um diesen Step abzuschließen.

+
diff --git a/src/app/demo/components-overview/stepper-large-example/stepper-large-example.component.ts b/src/app/demo/components-overview/stepper-large-example/stepper-large-example.component.ts index d12ed20b..a8a7294c 100644 --- a/src/app/demo/components-overview/stepper-large-example/stepper-large-example.component.ts +++ b/src/app/demo/components-overview/stepper-large-example/stepper-large-example.component.ts @@ -5,6 +5,7 @@ import { LuxStepperLargeSelectionEvent } from '../../../modules/lux-layout/lux-s import { LuxStepperLargeComponent } from '../../../modules/lux-layout/lux-stepper-large/lux-stepper-large.component'; import { LuxSnackbarService } from '../../../modules/lux-popups/lux-snackbar/lux-snackbar.service'; import { StepperLargeExampleDataService } from './stepper-large-example-data.service'; +import { LuxToggleAcComponent } from '../../../modules/lux-form/lux-toggle-ac/lux-toggle-ac.component'; @Component({ selector: 'lux-stepper-large-example', @@ -13,6 +14,7 @@ import { StepperLargeExampleDataService } from './stepper-large-example-data.ser }) export class StepperLargeExampleComponent { @ViewChild(LuxStepperLargeComponent) stepper!: LuxStepperLargeComponent; + @ViewChild('requiredCheck') toggle!: LuxToggleAcComponent; allowed = false; stepValidationActive = true; @@ -21,6 +23,8 @@ export class StepperLargeExampleComponent { maxWidth = this.options[0]; completed = true; theme = ''; + luxA11YMode = false; + showError = false; constructor(public dataService: StepperLargeExampleDataService, private router: Router, private snackbar: LuxSnackbarService, private themeService: LuxThemeService) { this.theme = themeService.getTheme().name; @@ -34,6 +38,8 @@ export class StepperLargeExampleComponent { if (this.currentStepIndex == 1) { this.dataService.luxStepValidationActive = this.stepValidationActive; } + + this.dataService.showErrorMessage.next(false); } onFinish() { @@ -53,4 +59,13 @@ export class StepperLargeExampleComponent { this.router.navigate([currentUrl]); }, snackbarDuration); } + + onStepNotComplete(currentStepNumber: number) { + this.toggle.formControl.markAsTouched(); + this.showError = true; + + this.dataService.showErrorMessage.next(true); + + } + } diff --git a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-fin-button.component.html b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-fin-button.component.html index fe138a03..ceaaaac4 100644 --- a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-fin-button.component.html +++ b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-fin-button.component.html @@ -31,4 +31,13 @@

{{ luxTitle }}

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

+ +

Bitte korrigieren oder vervollständigen Sie Ihre Angaben in den gekennzeichneten Feldern, um diesen Step abzuschließen.

+
diff --git a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-fin-button.component.ts b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-fin-button.component.ts index b1f94aec..c8deb54a 100644 --- a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-fin-button.component.ts +++ b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-fin-button.component.ts @@ -23,6 +23,8 @@ interface StepperLargeFinButtonDummyForm { }) export class StepperLargeExampleStepFinButtonComponent extends LuxStepperLargeStepComponent implements OnInit, OnDestroy { form: FormGroup; + showErrorMessage = false; + currentStepIndex = 3; subscriptions: Subscription[] = []; @@ -51,6 +53,12 @@ export class StepperLargeExampleStepFinButtonComponent extends LuxStepperLargeSt this.luxCompleted = this.form.valid; }) ); + + this.subscriptions.push( + this.dataService.showErrorMessage.subscribe((value) => { + this.showErrorMessage = value; + }) + ); } createVetoPromise(event: LuxStepperLargeClickEvent): Promise { diff --git a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-next-button.component.html b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-next-button.component.html index cdde74b5..c6f56fc8 100644 --- a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-next-button.component.html +++ b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-next-button.component.html @@ -30,4 +30,13 @@

{{ luxTitle }}

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

+ +

Bitte korrigieren oder vervollständigen Sie Ihre Angaben in den gekennzeichneten Feldern, um diesen Step abzuschließen.

+
diff --git a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-next-button.component.ts b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-next-button.component.ts index cb339ea7..b3fc06e2 100644 --- a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-next-button.component.ts +++ b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-next-button.component.ts @@ -23,6 +23,8 @@ interface StepperLargeNextButtonDummyForm { }) export class StepperLargeExampleStepNextButtonComponent extends LuxStepperLargeStepComponent implements OnInit, OnDestroy { form: FormGroup; + showErrorMessage = false; + currentStepIndex = 2; subscriptions: Subscription[] = []; @@ -51,6 +53,12 @@ export class StepperLargeExampleStepNextButtonComponent extends LuxStepperLargeS this.luxCompleted = this.form.valid; }) ); + + this.subscriptions.push( + this.dataService.showErrorMessage.subscribe((value) => { + this.showErrorMessage = value; + }) + ); } createVetoPromise(event: LuxStepperLargeClickEvent): Promise { diff --git a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-prev-button.component.html b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-prev-button.component.html index cdde74b5..c6f56fc8 100644 --- a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-prev-button.component.html +++ b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-prev-button.component.html @@ -30,4 +30,13 @@

{{ luxTitle }}

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

+ +

Bitte korrigieren oder vervollständigen Sie Ihre Angaben in den gekennzeichneten Feldern, um diesen Step abzuschließen.

+
diff --git a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-prev-button.component.ts b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-prev-button.component.ts index be4b8515..4607ebd3 100644 --- a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-prev-button.component.ts +++ b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-example-step-prev-button.component.ts @@ -23,6 +23,8 @@ interface StepperLargePrevButtonDummyForm { }) export class StepperLargeExampleStepPrevButtonComponent extends LuxStepperLargeStepComponent implements OnInit, OnDestroy { form: FormGroup; + showErrorMessage = false; + currentStepIndex = 1; subscriptions: Subscription[] = []; @@ -51,6 +53,12 @@ export class StepperLargeExampleStepPrevButtonComponent extends LuxStepperLargeS this.luxCompleted = this.form.valid; }) ); + + this.subscriptions.push( + this.dataService.showErrorMessage.subscribe((value) => { + this.showErrorMessage = value; + }) + ); } createVetoPromise(event: LuxStepperLargeClickEvent): Promise { diff --git a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-extern-step-example.component.html b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-extern-step-example.component.html index c8c86e42..de13e999 100644 --- a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-extern-step-example.component.html +++ b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-extern-step-example.component.html @@ -15,4 +15,13 @@

{{ luxTitle }}

sea takimata sanctus est Lorem ipsum dolor sit amet.

+ +

Bitte korrigieren oder vervollständigen Sie Ihre Angaben in den gekennzeichneten Feldern, um diesen Step abzuschließen.

+
diff --git a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-extern-step-example.component.ts b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-extern-step-example.component.ts index 804a1906..a5d7526a 100644 --- a/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-extern-step-example.component.ts +++ b/src/app/demo/components-overview/stepper-large-example/steps/stepper-large-extern-step-example.component.ts @@ -1,5 +1,7 @@ import { AfterViewInit, ChangeDetectorRef, Component, OnInit } from '@angular/core'; import { LuxStepperLargeStepComponent } from '../../../../modules/lux-layout/lux-stepper-large/lux-stepper-large-subcomponents/lux-stepper-large-step/lux-stepper-large-step.component'; +import { StepperLargeExampleDataService } from '../stepper-large-example-data.service'; +import { Subscription } from 'rxjs/internal/Subscription'; @Component({ selector: 'lux-stepper-large-extern-step-example', @@ -7,8 +9,10 @@ import { LuxStepperLargeStepComponent } from '../../../../modules/lux-layout/lux providers: [{ provide: LuxStepperLargeStepComponent, useExisting: StepperLargeExternStepExampleComponent }] }) export class StepperLargeExternStepExampleComponent extends LuxStepperLargeStepComponent implements OnInit, AfterViewInit { + showErrorMessage = false; + subscriptions: Subscription[] = []; - constructor(private cdr: ChangeDetectorRef) { + constructor(private cdr: ChangeDetectorRef,public dataService: StepperLargeExampleDataService) { super(); } @@ -16,6 +20,12 @@ export class StepperLargeExternStepExampleComponent extends LuxStepperLargeStepC if (!this.luxTitle) { this.luxTitle = 'Lorem ipsum 4711'; } + + this.subscriptions.push( + this.dataService.showErrorMessage.subscribe((value) => { + this.showErrorMessage = value; + }) + ); } ngAfterViewInit() { diff --git a/src/app/modules/lux-layout/lux-stepper-large/lux-stepper-large.component.html b/src/app/modules/lux-layout/lux-stepper-large/lux-stepper-large.component.html index b0d37ddb..00daa937 100644 --- a/src/app/modules/lux-layout/lux-stepper-large/lux-stepper-large.component.html +++ b/src/app/modules/lux-layout/lux-stepper-large/lux-stepper-large.component.html @@ -87,7 +87,8 @@ [luxIconShowRight]="luxNextButtonConfig.iconShowRight" [luxColor]="luxNextButtonConfig.color" [luxRaised]="true" - [luxDisabled]="luxStepValidationActive && (!steps.get(luxCurrentStepNumber) || !steps.get(luxCurrentStepNumber)!.luxCompleted)" + [luxDisabled]="luxA11YMode ? false : (luxStepValidationActive && (!steps.get(luxCurrentStepNumber) || !steps.get(luxCurrentStepNumber)!.luxCompleted))" + [attr.aria-disabled] = "!luxA11YMode ? false : (luxStepValidationActive && (!steps.get(luxCurrentStepNumber) || !steps.get(luxCurrentStepNumber)!.luxCompleted))" (luxClicked)="onNextStep()" *ngIf="!isLastStep" > @@ -99,8 +100,9 @@ [luxColor]="luxFinButtonConfig.color" [luxRaised]="true" [luxDisabled]=" - luxStepValidationActive && (!steps.get(luxCurrentStepNumber) || !steps.get(luxCurrentStepNumber)!.luxCompleted || isFinished) + luxA11YMode ? false : (luxStepValidationActive && (!steps.get(luxCurrentStepNumber) || !steps.get(luxCurrentStepNumber)!.luxCompleted || isFinished)) " + [attr.aria-disabled] = "!luxA11YMode ? false : (luxStepValidationActive && (!steps.get(luxCurrentStepNumber) || !steps.get(luxCurrentStepNumber)!.luxCompleted || isFinished))" (luxClicked)="onFinStep()" *ngIf="isLastStep" > diff --git a/src/app/modules/lux-layout/lux-stepper-large/lux-stepper-large.component.ts b/src/app/modules/lux-layout/lux-stepper-large/lux-stepper-large.component.ts index ac34fdc6..81f450ff 100644 --- a/src/app/modules/lux-layout/lux-stepper-large/lux-stepper-large.component.ts +++ b/src/app/modules/lux-layout/lux-stepper-large/lux-stepper-large.component.ts @@ -23,6 +23,7 @@ export class LuxStepperLargeComponent implements OnInit, AfterContentInit, OnDes @ContentChildren(LuxStepperLargeStepComponent) steps!: QueryList; @Input() luxStepValidationActive = true; + @Input() luxA11YMode = true; @Input() luxPrevButtonConfig = LUX_STEPPER_LARGE_DEFAULT_PREV_BTN_CONF; @Input() luxNextButtonConfig = LUX_STEPPER_LARGE_DEFAULT_NEXT_BTN_CONF; @Input() luxFinButtonConfig = LUX_STEPPER_LARGE_DEFAULT_FIN_BTN_CONF; @@ -30,6 +31,7 @@ export class LuxStepperLargeComponent implements OnInit, AfterContentInit, OnDes @Output() luxStepperFinished = new EventEmitter(); @Output() luxStepChanged = new EventEmitter(); @Output() luxCurrentStepNumberChange = new EventEmitter(); + @Output() luxStepNotComplete = new EventEmitter(); _luxCurrentStepNumber = 0; @@ -105,6 +107,10 @@ export class LuxStepperLargeComponent implements OnInit, AfterContentInit, OnDes } onPrevStep() { + if (this.luxStepValidationActive && this.luxA11YMode && !this.steps.get(this.luxCurrentStepNumber)!.luxCompleted) { + this.luxStepNotComplete.emit(this._luxCurrentStepNumber); + } + const newIndex = this.getPrevIndex(this.luxCurrentStepNumber); const event: LuxStepperLargeClickEvent = { @@ -125,6 +131,11 @@ export class LuxStepperLargeComponent implements OnInit, AfterContentInit, OnDes } onNextStep() { + if (this.luxStepValidationActive && this.luxA11YMode && !this.steps.get(this.luxCurrentStepNumber)!.luxCompleted) { + this.luxStepNotComplete.emit(this._luxCurrentStepNumber); + return; + } + const newIndex = this.getNextIndex(this.luxCurrentStepNumber); const event: LuxStepperLargeClickEvent = { @@ -145,6 +156,11 @@ export class LuxStepperLargeComponent implements OnInit, AfterContentInit, OnDes } onFinStep() { + if (this.luxStepValidationActive && this.luxA11YMode && !this.steps.get(this.luxCurrentStepNumber)!.luxCompleted) { + this.luxStepNotComplete.emit(this._luxCurrentStepNumber); + return; + } + const event: LuxStepperLargeClickEvent = { stepper: this, newIndex: this.luxCurrentStepNumber, @@ -203,19 +219,23 @@ export class LuxStepperLargeComponent implements OnInit, AfterContentInit, OnDes } onNavLink(stepIndex: number) { - if ((!this.luxStepValidationActive) || (this.steps.get(this.luxCurrentStepNumber)!.luxCompleted === true )) { - const event: LuxStepperLargeClickEvent = { stepper: this, newIndex: stepIndex, newStep: this.steps.get(stepIndex)!, source: 'nav' }; - const vetoPromise = this.steps.get(this.luxCurrentStepNumber)!.luxVetoFn(event); - - vetoPromise - .then((veto) => { - if (veto === LuxVetoState.navigationAccepted) { - this.luxCurrentStepNumber = stepIndex; - this.cursorPos = -1; - } - }) - .catch((err) => console.error(err)); + if (this.luxStepValidationActive && this.luxA11YMode && !this.steps.get(this.luxCurrentStepNumber)!.luxCompleted) { + this.luxStepNotComplete.emit(this._luxCurrentStepNumber); + if (stepIndex > this.luxCurrentStepNumber) { + return; + } } + const event: LuxStepperLargeClickEvent = { stepper: this, newIndex: stepIndex, newStep: this.steps.get(stepIndex)!, source: 'nav' }; + const vetoPromise = this.steps.get(this.luxCurrentStepNumber)!.luxVetoFn(event); + + vetoPromise + .then((veto) => { + if (veto === LuxVetoState.navigationAccepted) { + this.luxCurrentStepNumber = stepIndex; + this.cursorPos = -1; + } + }) + .catch((err) => console.error(err)); } onOpenMobileOverlay() {