Skip to content
Snippets Groups Projects
Commit cd7bbb01 authored by Mathias Chouet's avatar Mathias Chouet
Browse files

Merge branch '188-utiliser-la-touche-tab-pour-passer-d-un-champ-a-l-autre' into 'master'

Resolve "Utiliser la touche TAB pour passer d'un champ à l'autre"

Closes #188, #158, and #173

See merge request !41
parents fe4b13f1 21462af4
No related branches found
No related tags found
1 merge request!41Resolve "Utiliser la touche TAB pour passer d'un champ à l'autre"
Showing
with 175 additions and 26 deletions
54-ameliorer-le-filtre-de-choix-des-parametres-pouvant-etre-lies
master
......@@ -7,13 +7,16 @@ var fs = require('fs');
date_last_commit = require('child_process')
.execSync('git log -1 --format=%cd --date=short')
.toString().trim()
version = require('child_process')
.execSync('git describe')
.toString().trim()
var sFileName = "src/date_revision.ts";
fs.writeFile(sFileName, `export const nghydDateRev = "${date_last_commit}";\n`, function(err) {
fs.writeFile(sFileName, `export const nghydDateRev = "${date_last_commit}";\nexport const nghydVersion = "${version}";\n`, function(err) {
if(err) {
return console.log(err);
}
console.log(`File ${sFileName} saved with date ${date_last_commit}`);
});
\ No newline at end of file
console.log(`File ${sFileName} saved with date ${date_last_commit}, version ${version}`);
});
......@@ -53,8 +53,7 @@
</div>
<button mat-icon-button id="new-calculator" routerLink="/list" (click)="sidenav.close()">
<mat-icon *ngIf="calculators.length > 0">add_box</mat-icon>
<mat-icon *ngIf="calculators.length === 0">home</mat-icon>
<mat-icon *ngIf="currentRoute != '/list'">add_box</mat-icon>
</button>
<div id="toolbar-bottom-spacer"></div>
......@@ -96,8 +95,18 @@
</a>
<div class="hyd_version">
JaLHyd version: {{ getDateRevision()[0] }}<br/>
ngHyd version: {{ getDateRevision()[1] }}
<div class="jalhyd-version">
<span class="version">
JaLHyd: <span class="value">{{ revisionInfo.jalhyd.version }}</span>
</span>
<span class="date">updated {{ revisionInfo.jalhyd.date }}</span>
</div>
<div class="nghyd-version">
<span class="version">
ngHyd: <span class="value">{{ revisionInfo.nghyd.version }}</span>
</span>
<span class="date">updated {{ revisionInfo.nghyd.date }}</span>
</div>
</div>
</div>
</mat-sidenav>
......
......@@ -216,6 +216,22 @@ button:focus {
color: #888888;
padding: 0 2em 1em 0;
text-align: right;
.jalhyd-version {
margin-bottom: 0.6em;
}
.version {
display: block;
> .value {
font-weight: bold;
}
}
.date {
font-size: 0.8em;
}
}
.closebtn {
......
......@@ -3,7 +3,7 @@ import { Router, Event, NavigationEnd, ActivationEnd } from "@angular/router";
import { MatSidenav, MatToolbar, MatDialog, MatIconRegistry } from "@angular/material";
import { DomSanitizer } from "@angular/platform-browser";
import { Observer, jalhydDateRev, CalculatorType, Session } from "jalhyd";
import { Observer, jalhydDateRev, jalhydVersion, CalculatorType, Session } from "jalhyd";
import { environment } from "../environments/environment";
import { I18nService } from "./services/internationalisation/internationalisation.service";
......@@ -13,7 +13,7 @@ import { FormulaireDefinition } from "./formulaire/definition/form-definition";
import { ServiceFactory } from "./services/service-factory";
import { HttpService } from "./services/http/http.service";
import { ApplicationSetupService } from "./services/app-setup/app-setup.service";
import { nghydDateRev } from "../date_revision";
import { nghydDateRev, nghydVersion } from "../date_revision";
import { DialogConfirmEmptySessionComponent } from "./components/dialog-confirm-empty-session/dialog-confirm-empty-session.component";
import { DialogLoadSessionComponent } from "./components/dialog-load-session/dialog-load-session.component";
......@@ -172,6 +172,10 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
return this._currentFormId;
}
public get currentRoute(): string {
return this.router.url;
}
public setActiveCalc(uid: string) {
this._calculators.forEach((calc) => {
calc.active = (calc.uid === uid);
......@@ -407,9 +411,17 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
});
}
public getDateRevision(): string[] {
const dr: string[] = [jalhydDateRev, nghydDateRev];
return dr;
public get revisionInfo(): any {
return {
jalhyd: {
date: jalhydDateRev,
version: jalhydVersion,
},
nghyd: {
date: nghydDateRev,
version: nghydVersion
}
};
}
/**
......
......@@ -20,7 +20,8 @@
<mat-card-content>
<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>
<select-field-line *ngIf="isSelectField(p)" [_select]=p>
......
......@@ -117,6 +117,10 @@ export class FieldSetComponent implements DoCheck {
@Output()
private radio = new EventEmitter<any>();
/** événement signalant un appui sur TAB ou SHIFT+TAB */
@Output()
protected tabPressed = new EventEmitter<any>();
private hasRadioFix(): boolean {
if (this._fieldSet.hasInputs) {
switch (this._fieldSet.getInput(0).radioConfig) {
......@@ -209,6 +213,13 @@ export class FieldSetComponent implements DoCheck {
this.validChange.emit();
}
/**
* Renvoie l'événement au composant du dessus
*/
public onTabPressed(event) {
this.tabPressed.emit(event);
}
public ngDoCheck() {
this.updateValidity();
}
......
......@@ -8,6 +8,7 @@
<field-set *ngFor="let fs of fieldsets" class="fieldset-inner" [fieldSet]=fs
(radio)=onRadioClick($event) (validChange)=onFieldsetValid() (inputChange)=onInputChange()
(addFieldset)=onAddFieldset($event) (removeFieldset)=onRemoveFieldset($event)
(moveFieldsetDown)=onMoveFieldsetDown($event) (moveFieldsetUp)=onMoveFieldsetUp($event)>
(moveFieldsetDown)=onMoveFieldsetDown($event) (moveFieldsetUp)=onMoveFieldsetUp($event)
(tabPressed)="onTabPressed($event)">
</field-set>
</mat-card-content>
......@@ -60,6 +60,10 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
@Output()
private inputChange = new EventEmitter();
/** événement signalant un appui sur TAB ou SHIFT+TAB */
@Output()
protected tabPressed = new EventEmitter<any>();
private addStructure(after?: FieldSet) {
if (after) {
this._container.addFromTemplate(0, after.indexAsKid());
......@@ -204,4 +208,11 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
const form = this._container.parent as FormulaireDefinition;
form.moveFieldsetDown(fs);
}
/**
* Renvoie l'événement au composant du dessus
*/
public onTabPressed(event) {
this.tabPressed.emit(event);
}
}
......@@ -32,10 +32,14 @@
<!-- chapitres -->
<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">
<field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe (radio)=onRadioClick($event)
(validChange)=OnFieldsetValid() (inputChange)=onInputChange()></field-set>
<field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe
(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>
<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 { Observer, Session, ParamValueMode } from "jalhyd";
......@@ -98,7 +98,9 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
constructor(
private route: ActivatedRoute,
private router: Router,
private confirmCloseCalcDialog: MatDialog
private confirmCloseCalcDialog: MatDialog,
private _elementRef: ElementRef,
private renderer: Renderer2
) {
super();
this.intlService = ServiceFactory.instance.i18nService;
......@@ -308,7 +310,11 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
// accumulator (valeur précédente du résultat)
acc,
// currentValue (élément courant dans le tableau)
fieldset
fieldset,
// currentIndex (indice courant dans le tableau)
currIndex,
// array (tableau parcouru)
array
) => {
return acc && fieldset.isValid;
}
......@@ -322,7 +328,11 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
// accumulator (valeur précédente du résultat)
acc,
// currentValue (élément courant dans le tableau)
fieldsetContainer
fieldsetContainer,
// currentIndex (indice courant dans le tableau)
currIndex,
// array (tableau parcouru)
array
) => {
return acc && fieldsetContainer.isValid;
}
......@@ -357,6 +367,43 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
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() {
window.open("assets/docs-fr/calculators/" + this._formulaire.helpLink + "/", "_blank");
}
......
<mat-form-field>
<input matInput #inputControl="ngModel" class="form-control" type="text" inputmode="numeric"
[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>
<mat-error>{{ errorMessage }}</mat-error>
......
import { Input, Output, EventEmitter, ChangeDetectorRef, OnChanges, ViewChild } from "@angular/core";
import { NgModel } from "@angular/forms";
import { BaseComponent } from "../base/base.component";
import { isNumeric } from "jalhyd";
import { isNumeric, Structure } from "jalhyd";
import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
import { NgParameter } from "../../formulaire/ngparam";
import { I18nService } from "../../services/internationalisation/internationalisation.service";
......@@ -37,11 +37,18 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
* id de l'input, utilisé notamment pour les tests
*/
public get inputId() {
let id = "input-1";
let id = "error-in-inputId";
if (this._model) {
// unique input id based on parameter symbol
if (this._model instanceof NgParameter) {
id = (this._model as NgParameter).symbol;
const param = this._model as NgParameter;
id = param.symbol;
// if inside a nested Structure, prefix with Structure position
// to disambiguate
const nub = param.paramDefinition.parentNub;
if (nub && nub instanceof Structure) {
id = nub.findPositionInParent() + "_" + id;
}
}
}
return id;
......@@ -59,6 +66,12 @@ export abstract class GenericInputComponent extends BaseComponent implements OnC
@Output()
protected change = new EventEmitter<any>();
/**
* événement signalant un appui sur TAB ou SHIFT+TAB
*/
@Output()
protected tabPressed = new EventEmitter<any>();
/**
* valeur saisie.
* Cette variable n'est modifiée que lorsqu'on affecte le modèle ou que l'utilisateur fait une saisie
......@@ -231,6 +244,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() {
this.updateAndValidateUI();
this.validateModel();
......
......@@ -4,7 +4,8 @@
<!-- input de saisie de la valeur -->
<div fxFlex="1 0 120px">
<!-- 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é" -->
<param-computed *ngIf="isRadioCalChecked" [title]="title" [param]="param"></param-computed>
......
......@@ -127,6 +127,10 @@ export class ParamFieldLineComponent implements OnChanges {
@Output()
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 */
private _isInputValid = false;
......@@ -266,6 +270,13 @@ export class ParamFieldLineComponent implements OnChanges {
this.emitValidity();
}
/**
* Renvoie l'événement au composant du dessus
*/
public onTabPressed(event) {
this.tabPressed.emit(event);
}
/**
* émission d'un événement de validité
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment