Commit c9000b0f authored by Mathias Chouet's avatar Mathias Chouet :spaghetti:
Browse files

Fix #188 Utiliser la touche TAB pour passer d'un champ à l'autre

Showing with 112 additions and 10 deletions
+112 -10
...@@ -20,7 +20,8 @@ ...@@ -20,7 +20,8 @@
<mat-card-content> <mat-card-content>
<ng-template ngFor let-p [ngForOf]="fields"> <ng-template ngFor let-p [ngForOf]="fields">
<param-field-line *ngIf="isInputField(p)" [param]=p (radio)=onRadioClick($event) (valid)=onParamLineValid() (inputChange)=onInputChange()> <param-field-line *ngIf="isInputField(p)" [param]=p (radio)=onRadioClick($event) (valid)=onParamLineValid()
(inputChange)=onInputChange() (tabPressed)="onTabPressed($event)">
</param-field-line> </param-field-line>
<select-field-line *ngIf="isSelectField(p)" [_select]=p> <select-field-line *ngIf="isSelectField(p)" [_select]=p>
......
...@@ -117,6 +117,10 @@ export class FieldSetComponent implements DoCheck { ...@@ -117,6 +117,10 @@ export class FieldSetComponent implements DoCheck {
@Output() @Output()
private radio = new EventEmitter<any>(); private radio = new EventEmitter<any>();
/** événement signalant un appui sur TAB ou SHIFT+TAB */
@Output()
protected tabPressed = new EventEmitter<any>();
private hasRadioFix(): boolean { private hasRadioFix(): boolean {
if (this._fieldSet.hasInputs) { if (this._fieldSet.hasInputs) {
switch (this._fieldSet.getInput(0).radioConfig) { switch (this._fieldSet.getInput(0).radioConfig) {
...@@ -209,6 +213,13 @@ export class FieldSetComponent implements DoCheck { ...@@ -209,6 +213,13 @@ export class FieldSetComponent implements DoCheck {
this.validChange.emit(); this.validChange.emit();
} }
/**
* Renvoie l'événement au composant du dessus
*/
public onTabPressed(event) {
this.tabPressed.emit(event);
}
public ngDoCheck() { public ngDoCheck() {
this.updateValidity(); this.updateValidity();
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<field-set *ngFor="let fs of fieldsets" class="fieldset-inner" [fieldSet]=fs <field-set *ngFor="let fs of fieldsets" class="fieldset-inner" [fieldSet]=fs
(radio)=onRadioClick($event) (validChange)=onFieldsetValid() (inputChange)=onInputChange() (radio)=onRadioClick($event) (validChange)=onFieldsetValid() (inputChange)=onInputChange()
(addFieldset)=onAddFieldset($event) (removeFieldset)=onRemoveFieldset($event) (addFieldset)=onAddFieldset($event) (removeFieldset)=onRemoveFieldset($event)
(moveFieldsetDown)=onMoveFieldsetDown($event) (moveFieldsetUp)=onMoveFieldsetUp($event)> (moveFieldsetDown)=onMoveFieldsetDown($event) (moveFieldsetUp)=onMoveFieldsetUp($event)
(tabPressed)="onTabPressed($event)">
</field-set> </field-set>
</mat-card-content> </mat-card-content>
...@@ -60,6 +60,10 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit { ...@@ -60,6 +60,10 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
@Output() @Output()
private inputChange = new EventEmitter(); private inputChange = new EventEmitter();
/** événement signalant un appui sur TAB ou SHIFT+TAB */
@Output()
protected tabPressed = new EventEmitter<any>();
private addStructure(after?: FieldSet) { private addStructure(after?: FieldSet) {
if (after) { if (after) {
this._container.addFromTemplate(0, after.indexAsKid()); this._container.addFromTemplate(0, after.indexAsKid());
...@@ -204,4 +208,11 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit { ...@@ -204,4 +208,11 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
const form = this._container.parent as FormulaireDefinition; const form = this._container.parent as FormulaireDefinition;
form.moveFieldsetDown(fs); form.moveFieldsetDown(fs);
} }
/**
* Renvoie l'événement au composant du dessus
*/
public onTabPressed(event) {
this.tabPressed.emit(event);
}
} }
...@@ -32,10 +32,14 @@ ...@@ -32,10 +32,14 @@
<!-- chapitres --> <!-- chapitres -->
<mat-card id="calc-card-field-sets" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px"> <mat-card id="calc-card-field-sets" fxFlex.gt-xs="1 0 400px" fxFlex.lt-sm="1 0 300px">
<ng-template ngFor let-fe [ngForOf]="formElements"> <ng-template ngFor let-fe [ngForOf]="formElements">
<field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe (radio)=onRadioClick($event) <field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe
(validChange)=OnFieldsetValid() (inputChange)=onInputChange()></field-set> (radio)=onRadioClick($event) (validChange)=OnFieldsetValid() (inputChange)=onInputChange()
(tabPressed)="onTabPressed($event)">
</field-set>
<fieldset-container *ngIf="isFieldsetContainer(fe)" [_container]=fe (radio)=onRadioClick($event) (validChange)=onFieldsetContainerValid()></fieldset-container> <fieldset-container *ngIf="isFieldsetContainer(fe)" [_container]=fe (radio)=onRadioClick($event)
(validChange)=onFieldsetContainerValid() (tabPressed)="onTabPressed($event)">
</fieldset-container>
</ng-template> </ng-template>
<mat-card-actions> <mat-card-actions>
......
import { Component, OnInit, DoCheck, OnDestroy, ViewChild, ViewChildren, QueryList, AfterViewChecked } from "@angular/core"; import { Component, OnInit, DoCheck, OnDestroy, ViewChild, ViewChildren, QueryList, AfterViewChecked, ElementRef, Renderer2 } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router"; import { ActivatedRoute, Router } from "@angular/router";
import { Observer, Session, ParamValueMode } from "jalhyd"; import { Observer, Session, ParamValueMode } from "jalhyd";
...@@ -98,7 +98,9 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, ...@@ -98,7 +98,9 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private confirmCloseCalcDialog: MatDialog private confirmCloseCalcDialog: MatDialog,
private _elementRef: ElementRef,
private renderer: Renderer2
) { ) {
super(); super();
this.intlService = ServiceFactory.instance.i18nService; this.intlService = ServiceFactory.instance.i18nService;
...@@ -308,7 +310,11 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, ...@@ -308,7 +310,11 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
// accumulator (valeur précédente du résultat) // accumulator (valeur précédente du résultat)
acc, acc,
// currentValue (élément courant dans le tableau) // currentValue (élément courant dans le tableau)
fieldset fieldset,
// currentIndex (indice courant dans le tableau)
currIndex,
// array (tableau parcouru)
array
) => { ) => {
return acc && fieldset.isValid; return acc && fieldset.isValid;
} }
...@@ -322,7 +328,11 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, ...@@ -322,7 +328,11 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
// accumulator (valeur précédente du résultat) // accumulator (valeur précédente du résultat)
acc, acc,
// currentValue (élément courant dans le tableau) // currentValue (élément courant dans le tableau)
fieldsetContainer fieldsetContainer,
// currentIndex (indice courant dans le tableau)
currIndex,
// array (tableau parcouru)
array
) => { ) => {
return acc && fieldsetContainer.isValid; return acc && fieldsetContainer.isValid;
} }
...@@ -357,6 +367,43 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit, ...@@ -357,6 +367,43 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
this._formulaire.resetResults([]); this._formulaire.resetResults([]);
} }
/**
* Passe d'un champ de saisie à l'autre lors de l'appui sur
* TAB, sans passer par les autres éléments d'interface
*/
public onTabPressed(event: any) {
// event source input id
const srcId = event.originalEvent.target.id;
// find all available inputs
const qs = "ngparam-input input.form-control";
let inputs: Node[] = Array.from(this._elementRef.nativeElement.querySelectorAll(qs));
// find calculated symbol if any, to exclude it from inputs list
let calcSymbol = "";
if (this._formulaire.currentNub.calculatedParam) {
calcSymbol = this._formulaire.currentNub.calculatedParam.symbol;
}
inputs = inputs.filter((i: any) => {
return i.id !== calcSymbol;
});
// find position among inputs list
const currentIndex = inputs.findIndex((i: any) => {
return i.id === srcId;
});
// focus previous / next input
let newIndex = currentIndex;
if (event.shift) {
newIndex = (newIndex === 0) ? (inputs.length - 1) : (newIndex - 1);
} else {
newIndex = (newIndex + 1) % inputs.length;
}
const elt = (inputs[newIndex] as HTMLElement);
elt.focus();
}
public openHelp() { public openHelp() {
window.open("assets/docs-fr/calculators/" + this._formulaire.helpLink + "/", "_blank"); window.open("assets/docs-fr/calculators/" + this._formulaire.helpLink + "/", "_blank");
} }
......
<mat-form-field> <mat-form-field>
<input matInput #inputControl="ngModel" class="form-control" type="text" inputmode="numeric" <input matInput #inputControl="ngModel" class="form-control" type="text" inputmode="numeric"
[id]="inputId" [name]="inputId" [disabled]="isDisabled" [(ngModel)]="uiValue" [placeholder]="title" [id]="inputId" [name]="inputId" [disabled]="isDisabled" [(ngModel)]="uiValue" [placeholder]="title"
(keydown.Tab)="onTabPressed($event, false)" (keydown.shift.Tab)="onTabPressed($event, true)"
pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$" required> pattern="^-?([0-9]*\.)?([0-9]+[Ee]-?)?[0-9]+$" required>
<mat-error>{{ errorMessage }}</mat-error> <mat-error>{{ errorMessage }}</mat-error>
......
...@@ -59,6 +59,12 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC ...@@ -59,6 +59,12 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
@Output() @Output()
protected change = new EventEmitter<any>(); protected change = new EventEmitter<any>();
/**
* événement signalant un appui sur TAB ou SHIFT+TAB
*/
@Output()
protected tabPressed = new EventEmitter<any>();
/** /**
* valeur saisie. * valeur saisie.
* Cette variable n'est modifiée que lorsqu'on affecte le modèle ou que l'utilisateur fait une saisie * Cette variable n'est modifiée que lorsqu'on affecte le modèle ou que l'utilisateur fait une saisie
...@@ -231,6 +237,14 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC ...@@ -231,6 +237,14 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
} }
} }
/**
* Renvoie l'événement au composant du dessus
*/
public onTabPressed(event, shift: boolean) {
this.tabPressed.emit({ originalEvent: event, shift: shift });
return false; // stops event propagation
}
private updateAll() { private updateAll() {
this.updateAndValidateUI(); this.updateAndValidateUI();
this.validateModel(); this.validateModel();
......
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
<!-- input de saisie de la valeur --> <!-- input de saisie de la valeur -->
<div fxFlex="1 0 120px"> <div fxFlex="1 0 120px">
<!-- composant pour gérer le cas général (valeur numérique à saisir) --> <!-- composant pour gérer le cas général (valeur numérique à saisir) -->
<ngparam-input [title]="param.title" [hidden]="! isRadioFixChecked" (change)="onInputChange($event)"></ngparam-input> <ngparam-input [title]="param.title" [hidden]="! isRadioFixChecked"
(change)="onInputChange($event)" (tabPressed)="onTabPressed($event)"></ngparam-input>
<!-- composant pour gérer le cas "paramètre calculé" --> <!-- composant pour gérer le cas "paramètre calculé" -->
<param-computed *ngIf="isRadioCalChecked" [title]="title" [param]="param"></param-computed> <param-computed *ngIf="isRadioCalChecked" [title]="title" [param]="param"></param-computed>
......
...@@ -127,6 +127,10 @@ export class ParamFieldLineComponent implements OnChanges { ...@@ -127,6 +127,10 @@ export class ParamFieldLineComponent implements OnChanges {
@Output() @Output()
private inputChange: EventEmitter<void>; private inputChange: EventEmitter<void>;
/** événement signalant un appui sur TAB ou SHIFT+TAB */
@Output()
protected tabPressed = new EventEmitter<any>();
/** true si la valeur saisie est valide */ /** true si la valeur saisie est valide */
private _isInputValid = false; private _isInputValid = false;
...@@ -266,6 +270,13 @@ export class ParamFieldLineComponent implements OnChanges { ...@@ -266,6 +270,13 @@ export class ParamFieldLineComponent implements OnChanges {
this.emitValidity(); this.emitValidity();
} }
/**
* Renvoie l'événement au composant du dessus
*/
public onTabPressed(event) {
this.tabPressed.emit(event);
}
/** /**
* émission d'un événement de validité * émission d'un événement de validité
*/ */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment