1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2025-01-14 14:43:17 +08:00

improving search behaviour (hitting enter runs search, left arrow inserts hint) #237

This commit is contained in:
Patrik J. Braun 2021-04-01 23:11:01 +02:00
parent 39c4c7fc02
commit 8422e4c29f
2 changed files with 34 additions and 8 deletions

View File

@ -77,11 +77,15 @@ export class AutoCompleteService {
return this.textSearchKeywordsMap[tokens[0]] || null;
}
private getPrefixLessSearchText(text: string): string {
public getPrefixLessSearchText(text: string): string {
const tokens = text.split(':');
if (tokens.length !== 2) {
return text;
}
// make sure autocomplete works for 'keyword:"' searches
if (tokens[1].charAt(0) === '"' || tokens[1].charAt(0) === '(') {
return tokens[1].substring(1);
}
return tokens[1];
}
@ -120,7 +124,8 @@ export class AutoCompleteService {
if (text.prev !== this._searchQueryParserService.keywords.and) {
return [{
text: this._searchQueryParserService.keywords.and,
queryHint: this._searchQueryParserService.keywords.and
queryHint: this._searchQueryParserService.keywords.and,
notSearchable: true
}];
} else {
return [];
@ -130,11 +135,13 @@ export class AutoCompleteService {
.filter(key => key.startsWith(text.current))
.map(key => ({
text: key,
queryHint: key
queryHint: key,
notSearchable: true
}));
}
}
export interface RenderableAutoCompleteItem extends IAutoCompleteItem {
queryHint: string;
notSearchable?: boolean; // prevent triggering search if it is not a full search term
}

View File

@ -128,8 +128,15 @@ export class GallerySearchFieldComponent implements ControlValueAccessor, Valida
if ($event.target.selectionStart !== this.rawSearchText.length) {
return;
}
this.rawSearchText = this.SearchHint;
this.onChange();
// if no item selected, apply hint
if (this.highlightedAutoCompleteItem < 0) {
this.rawSearchText = this.SearchHint;
this.onChange();
return;
}
// force apply selected autocomplete item
this.applyAutoComplete(this.autoCompleteRenders[this.highlightedAutoCompleteItem]);
}
applyAutoComplete(item: AutoCompleteRenderItem) {
@ -140,6 +147,14 @@ export class GallerySearchFieldComponent implements ControlValueAccessor, Valida
this.emptyAutoComplete();
}
searchAutoComplete(item: AutoCompleteRenderItem) {
this.applyAutoComplete(item);
if (!item.notSearchable) {
this.search.emit();
}
}
setMouseOverAutoCompleteItem(i: number) {
this.highlightedAutoCompleteItem = i;
}
@ -158,11 +173,13 @@ export class GallerySearchFieldComponent implements ControlValueAccessor, Valida
}
OnEnter($event: any) {
// no autocomplete shown, just search whatever is there.
if (this.autoCompleteRenders.length === 0 || this.highlightedAutoCompleteItem === -1) {
this.search.emit();
return;
}
this.applyAutoComplete(this.autoCompleteRenders[this.highlightedAutoCompleteItem]);
// search selected autocomplete
this.searchAutoComplete(this.autoCompleteRenders[this.highlightedAutoCompleteItem]);
}
public onTouched(): void {
@ -223,7 +240,7 @@ export class GallerySearchFieldComponent implements ControlValueAccessor, Valida
private showSuggestions(suggestions: RenderableAutoCompleteItem[], searchText: string) {
this.emptyAutoComplete();
suggestions.forEach((item: RenderableAutoCompleteItem) => {
const renderItem = new AutoCompleteRenderItem(item.text, searchText, item.type, item.queryHint);
const renderItem = new AutoCompleteRenderItem(item.text, this._autoCompleteService.getPrefixLessSearchText(searchText), item.type, item.queryHint, item.notSearchable);
this.autoCompleteRenders.push(renderItem);
});
}
@ -241,8 +258,9 @@ class AutoCompleteRenderItem {
public postText = '';
public type: SearchQueryTypes;
public queryHint: string;
public notSearchable: boolean;
constructor(public text: string, searchText: string, type: SearchQueryTypes, queryHint: string) {
constructor(public text: string, searchText: string, type: SearchQueryTypes, queryHint: string, notSearchable = false) {
const preIndex = text.toLowerCase().indexOf(searchText.toLowerCase());
if (preIndex > -1) {
this.preText = text.substring(0, preIndex);
@ -253,6 +271,7 @@ class AutoCompleteRenderItem {
}
this.type = type;
this.queryHint = queryHint;
this.notSearchable = notSearchable;
}
}