MOBILE-4565 a11y: Search box must alert of minimum required length
parent
8c3697a579
commit
540beee17e
|
@ -2407,6 +2407,7 @@
|
||||||
"core.search.allcategories": "local_moodlemobileapp",
|
"core.search.allcategories": "local_moodlemobileapp",
|
||||||
"core.search.allcourses": "search",
|
"core.search.allcourses": "search",
|
||||||
"core.search.empty": "local_moodlemobileapp",
|
"core.search.empty": "local_moodlemobileapp",
|
||||||
|
"core.search.err_minlength": "form",
|
||||||
"core.search.filtercategories": "local_moodlemobileapp",
|
"core.search.filtercategories": "local_moodlemobileapp",
|
||||||
"core.search.filtercourses": "local_moodlemobileapp",
|
"core.search.filtercourses": "local_moodlemobileapp",
|
||||||
"core.search.filterheader": "search",
|
"core.search.filterheader": "search",
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
<core-search-box *ngIf="searchEnabled" (onSubmit)="search($event)" (onClear)="clearSearch()"
|
<core-search-box *ngIf="searchEnabled" (onSubmit)="search($event)" (onClear)="clearSearch()"
|
||||||
[placeholder]="'core.courses.search' | translate" [searchLabel]="'core.courses.search' | translate" [autoFocus]="searchMode"
|
[placeholder]="'core.courses.search' | translate" [searchLabel]="'core.courses.search' | translate" [autoFocus]="searchMode"
|
||||||
searchArea="CoreCoursesSearch" />
|
searchArea="CoreCoursesSearch" [lengthCheck]="1" />
|
||||||
|
|
||||||
<core-loading [hideUntil]="loaded">
|
<core-loading [hideUntil]="loaded">
|
||||||
<ng-container *ngIf="searchMode && searchTotal > 0">
|
<ng-container *ngIf="searchMode && searchTotal > 0">
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
<ion-input [attr.aria-label]="placeholder" type="search" name="search" [(ngModel)]="searchText" [placeholder]="placeholder"
|
<ion-input [attr.aria-label]="placeholder" type="search" name="search" [(ngModel)]="searchText" [placeholder]="placeholder"
|
||||||
[autocorrect]="autocorrect" [spellcheck]="spellcheck" [core-auto-focus]="autoFocus" [disabled]="disabled" role="searchbox"
|
[autocorrect]="autocorrect" [spellcheck]="spellcheck" [core-auto-focus]="autoFocus" [disabled]="disabled" role="searchbox"
|
||||||
(ionFocus)="focus($event)">
|
(ionFocus)="focus($event)">
|
||||||
<ion-button slot="end" fill="clear" type="submit" [attr.aria-label]="searchLabel"
|
<ion-button slot="end" fill="clear" type="submit" [attr.aria-label]="searchLabel" [disabled]="disabled || !searchText">
|
||||||
[disabled]="disabled || !searchText || (searchText.length < lengthCheck)">
|
|
||||||
<ion-icon name="fas-magnifying-glass" slot="icon-only" aria-hidden="true" />
|
<ion-icon name="fas-magnifying-glass" slot="icon-only" aria-hidden="true" />
|
||||||
</ion-button>
|
</ion-button>
|
||||||
<ion-button *ngIf="showClear" slot="end" fill="clear" [attr.aria-label]="'core.clearsearch' | translate"
|
<ion-button *ngIf="showClear" slot="end" fill="clear" [attr.aria-label]="'core.clearsearch' | translate"
|
||||||
|
@ -11,6 +10,11 @@
|
||||||
<ion-icon name="fas-delete-left" slot="icon-only" aria-hidden="true" flip-rtl />
|
<ion-icon name="fas-delete-left" slot="icon-only" aria-hidden="true" flip-rtl />
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ion-input>
|
</ion-input>
|
||||||
|
<ion-item *ngIf="showLengthAlert" class="core-search-alert text-danger ion-text-wrap" role="alert">
|
||||||
|
<ion-label>
|
||||||
|
{{ 'core.search.err_minlength' | translate : {'$a': {'format': lengthCheck} } }}
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
<ion-list class="core-search-history" [hidden]="!historyShown">
|
<ion-list class="core-search-history" [hidden]="!historyShown">
|
||||||
<ion-item button class="ion-text-wrap" *ngFor="let item of history" (click)="historyClicked($event, item.searchedtext)" tabindex="0"
|
<ion-item button class="ion-text-wrap" *ngFor="let item of history" (click)="historyClicked($event, item.searchedtext)" tabindex="0"
|
||||||
[detail]="true">
|
[detail]="true">
|
||||||
|
|
|
@ -35,8 +35,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.core-search-history {
|
.core-search-history {
|
||||||
max-height: calc(-120px + 80vh);
|
max-height: calc(-120px + 80vh);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
|
@ -62,6 +62,7 @@ export class CoreSearchBoxComponent implements OnInit {
|
||||||
searchText = '';
|
searchText = '';
|
||||||
history: CoreSearchHistoryDBRecord[] = [];
|
history: CoreSearchHistoryDBRecord[] = [];
|
||||||
historyShown = false;
|
historyShown = false;
|
||||||
|
showLengthAlert = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.onSubmit = new EventEmitter<string>();
|
this.onSubmit = new EventEmitter<string>();
|
||||||
|
@ -86,14 +87,17 @@ export class CoreSearchBoxComponent implements OnInit {
|
||||||
* @param e Event.
|
* @param e Event.
|
||||||
*/
|
*/
|
||||||
submitForm(e?: Event): void {
|
submitForm(e?: Event): void {
|
||||||
e && e.preventDefault();
|
e?.preventDefault();
|
||||||
e && e.stopPropagation();
|
e?.stopPropagation();
|
||||||
|
|
||||||
if (this.searchText.length < this.lengthCheck) {
|
if (this.searchText.length < this.lengthCheck) {
|
||||||
// The view should handle this case, but we check it here too just in case.
|
this.showLengthAlert = true;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.showLengthAlert = false;
|
||||||
|
|
||||||
if (this.searchArea) {
|
if (this.searchArea) {
|
||||||
this.saveSearchToHistory(this.searchText);
|
this.saveSearchToHistory(this.searchText);
|
||||||
}
|
}
|
||||||
|
@ -147,6 +151,7 @@ export class CoreSearchBoxComponent implements OnInit {
|
||||||
clearForm(): void {
|
clearForm(): void {
|
||||||
this.searched = '';
|
this.searched = '';
|
||||||
this.searchText = '';
|
this.searchText = '';
|
||||||
|
this.showLengthAlert = false;
|
||||||
this.onClear.emit();
|
this.onClear.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,6 @@
|
||||||
"globalsearch": "Global search",
|
"globalsearch": "Global search",
|
||||||
"noresults": "No results for \"{{$a}}\"",
|
"noresults": "No results for \"{{$a}}\"",
|
||||||
"noresultshelp": "Check for typos or try using different keywords",
|
"noresultshelp": "Check for typos or try using different keywords",
|
||||||
|
"err_minlength": "You must enter at least {{$a.format}} characters here.",
|
||||||
"resultby": "By {{$a}}"
|
"resultby": "By {{$a}}"
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<ion-row class="ion-no-padding ion-wrap">
|
<ion-row class="ion-no-padding ion-wrap">
|
||||||
<ion-col class="ion-no-padding" size="12" size-sm="6" [attr.col-sm-6]="collections && collections.length > 1 ? '' : null">
|
<ion-col class="ion-no-padding" size="12" size-sm="6" [attr.col-sm-6]="collections && collections.length > 1 ? '' : null">
|
||||||
<core-search-box (onSubmit)="searchTags($event)" (onClear)="searchTags('')" [initialSearch]="query" [disabled]="searching"
|
<core-search-box (onSubmit)="searchTags($event)" (onClear)="searchTags('')" [initialSearch]="query" [disabled]="searching"
|
||||||
autocorrect="off" [spellcheck]="false" [autoFocus]="false" [lengthCheck]="0" searchArea="CoreTag" />
|
autocorrect="off" [spellcheck]="false" [autoFocus]="false" [lengthCheck]="1" searchArea="CoreTag" />
|
||||||
</ion-col>
|
</ion-col>
|
||||||
<ion-col class="ion-no-padding" size="12" size-sm="6" *ngIf="collections && collections.length > 1">
|
<ion-col class="ion-no-padding" size="12" size-sm="6" *ngIf="collections && collections.length > 1">
|
||||||
<core-combobox [selection]="collectionId" (onChange)="searchTags(query, $event)" [disabled]="searching">
|
<core-combobox [selection]="collectionId" (onChange)="searchTags(query, $event)" [disabled]="searching">
|
||||||
|
|
Loading…
Reference in New Issue