UX: Delay search query update until user has finished typing #1995
This commit is contained in:
parent
16caeef272
commit
426170a392
6 changed files with 98 additions and 60 deletions
|
@ -1,21 +1,22 @@
|
|||
<template>
|
||||
<v-form ref="form" lazy-validation
|
||||
dense autocomplete="off" class="p-photo-toolbar" accept-charset="UTF-8"
|
||||
@submit.prevent="filterChange">
|
||||
@submit.prevent="updateQuery">
|
||||
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
||||
<v-text-field v-model.lazy.trim="filter.q"
|
||||
<v-text-field :value="filter.q"
|
||||
class="input-search background-inherit elevation-0"
|
||||
solo hide-details clearable overflow single-line validate-on-blur
|
||||
autocorrect="off"
|
||||
autocapitalize="none"
|
||||
browser-autocomplete="off"
|
||||
solo hide-details clearable overflow single-line
|
||||
:label="$gettext('Search')"
|
||||
prepend-inner-icon="search"
|
||||
color="secondary-dark"
|
||||
@input="onChangeQuery"
|
||||
@change="updateQuery"
|
||||
@blur="updateQuery"
|
||||
@keyup.enter.native="updateQuery"
|
||||
@click:clear="clearQuery"
|
||||
@blur="filterChange"
|
||||
@change="filterChange"
|
||||
@keyup.enter.native="filterChange"
|
||||
></v-text-field>
|
||||
|
||||
<v-btn icon class="hidden-xs-only action-reload" :title="$gettext('Reload')" @click.stop="refresh">
|
||||
|
@ -177,6 +178,7 @@ export default {
|
|||
isFullScreen: !!document.fullscreenElement,
|
||||
config: this.$config.values,
|
||||
searchExpanded: false,
|
||||
q: this.filter.q ? this.filter.q : "",
|
||||
all: {
|
||||
countries: [{ID: "", Name: this.$gettext("All Countries")}],
|
||||
cameras: [{ID: 0, Name: this.$gettext("All Cameras")}],
|
||||
|
@ -239,8 +241,15 @@ export default {
|
|||
this.settings.view = name;
|
||||
this.filterChange();
|
||||
},
|
||||
onChangeQuery(val) {
|
||||
this.q = String(val);
|
||||
},
|
||||
clearQuery() {
|
||||
this.filter.q = '';
|
||||
this.q = '';
|
||||
this.updateQuery();
|
||||
},
|
||||
updateQuery() {
|
||||
this.filter.q = this.q.trim();
|
||||
this.filterChange();
|
||||
},
|
||||
showUpload() {
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
|
||||
<v-form ref="form" class="p-albums-search" lazy-validation dense @submit.prevent="updateQuery">
|
||||
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
||||
<v-text-field id="search"
|
||||
v-model.lazy.trim="filter.q"
|
||||
solo hide-details clearable overflow single-line
|
||||
<v-text-field :value="filter.q"
|
||||
solo hide-details clearable overflow single-line validate-on-blur
|
||||
class="input-search background-inherit elevation-0"
|
||||
:label="$gettext('Search')"
|
||||
browser-autocomplete="off"
|
||||
|
@ -15,10 +14,11 @@
|
|||
autocapitalize="none"
|
||||
prepend-inner-icon="search"
|
||||
color="secondary-dark"
|
||||
@click:clear="clearQuery"
|
||||
@blur="updateQuery"
|
||||
@input="onChangeQuery"
|
||||
@change="updateQuery"
|
||||
@blur="updateQuery"
|
||||
@keyup.enter.native="updateQuery"
|
||||
@click:clear="clearQuery"
|
||||
></v-text-field>
|
||||
|
||||
<v-overflow-btn v-model="filter.category"
|
||||
|
@ -254,6 +254,7 @@ export default {
|
|||
page: 0,
|
||||
selection: [],
|
||||
settings: settings,
|
||||
q: q,
|
||||
filter: filter,
|
||||
lastFilter: {},
|
||||
routeName: routeName,
|
||||
|
@ -285,10 +286,12 @@ export default {
|
|||
'$route'() {
|
||||
const query = this.$route.query;
|
||||
|
||||
this.filter.q = query["q"] ? query["q"] : "";
|
||||
this.filter.category = query["category"] ? query["category"] : "";
|
||||
this.lastFilter = {};
|
||||
this.routeName = this.$route.name;
|
||||
this.lastFilter = {};
|
||||
this.q = query["q"] ? query["q"] : "";
|
||||
this.filter.q = this.q;
|
||||
this.filter.category = query["category"] ? query["category"] : "";
|
||||
|
||||
this.search();
|
||||
}
|
||||
},
|
||||
|
@ -432,10 +435,6 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
clearQuery() {
|
||||
this.filter.q = '';
|
||||
this.search();
|
||||
},
|
||||
loadMore() {
|
||||
if (this.scrollDisabled) return;
|
||||
|
||||
|
@ -485,7 +484,16 @@ export default {
|
|||
this.listen = true;
|
||||
});
|
||||
},
|
||||
onChangeQuery(val) {
|
||||
this.q = String(val);
|
||||
},
|
||||
clearQuery() {
|
||||
this.q = '';
|
||||
this.updateQuery();
|
||||
},
|
||||
updateQuery() {
|
||||
this.filter.q = this.q.trim();
|
||||
|
||||
if (this.loading) return;
|
||||
|
||||
const query = {
|
||||
|
|
|
@ -3,22 +3,22 @@
|
|||
:infinite-scroll-disabled="scrollDisabled" :infinite-scroll-distance="1200"
|
||||
:infinite-scroll-listen-for-event="'scrollRefresh'">
|
||||
|
||||
<v-form ref="form" class="p-labels-search" lazy-validation dense @submit.prevent="updateQuery">
|
||||
<v-form ref="form" class="p-labels-search" lazy-validation dense @submit.stop.prevent>
|
||||
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
||||
<v-text-field id="search"
|
||||
v-model.lazy.trim="filter.q"
|
||||
<v-text-field :value="filter.q"
|
||||
solo hide-details clearable overflow single-line validate-on-blur
|
||||
class="input-search background-inherit elevation-0"
|
||||
solo hide-details clearable overflow
|
||||
:label="$gettext('Search')"
|
||||
prepend-inner-icon="search"
|
||||
browser-autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="none"
|
||||
color="secondary-dark"
|
||||
@click:clear="clearQuery"
|
||||
@blur="updateQuery"
|
||||
@input="onChangeQuery"
|
||||
@change="updateQuery"
|
||||
@blur="updateQuery"
|
||||
@keyup.enter.native="updateQuery"
|
||||
@click:clear="clearQuery"
|
||||
></v-text-field>
|
||||
|
||||
<v-btn icon class="action-reload" :title="$gettext('Reload')" @click.stop="refresh">
|
||||
|
@ -169,7 +169,7 @@ export default {
|
|||
const routeName = this.$route.name;
|
||||
const q = query['q'] ? query['q'] : '';
|
||||
const all = query['all'] ? query['all'] : '';
|
||||
const filter = {q: q, all: all};
|
||||
const filter = {"q": String(q), all: String(all)};
|
||||
const settings = {};
|
||||
|
||||
return {
|
||||
|
@ -186,6 +186,7 @@ export default {
|
|||
page: 0,
|
||||
selection: [],
|
||||
settings: settings,
|
||||
q: q,
|
||||
filter: filter,
|
||||
lastFilter: {},
|
||||
routeName: routeName,
|
||||
|
@ -198,12 +199,14 @@ export default {
|
|||
'$route'() {
|
||||
const query = this.$route.query;
|
||||
|
||||
this.filter.q = query['q'] ? query['q'] : '';
|
||||
this.filter.all = query['all'] ? query['all'] : '';
|
||||
this.lastFilter = {};
|
||||
this.routeName = this.$route.name;
|
||||
this.lastFilter = {};
|
||||
this.q = query['q'] ? query['q'] : '';
|
||||
this.filter.q = this.q;
|
||||
this.filter.all = query['all'] ? query['all'] : '';
|
||||
|
||||
this.search();
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.search();
|
||||
|
@ -324,10 +327,6 @@ export default {
|
|||
this.filter.all = "";
|
||||
this.updateQuery();
|
||||
},
|
||||
clearQuery() {
|
||||
this.filter.q = '';
|
||||
this.updateQuery();
|
||||
},
|
||||
addSelection(uid) {
|
||||
const pos = this.selection.indexOf(uid);
|
||||
|
||||
|
@ -417,7 +416,16 @@ export default {
|
|||
this.listen = true;
|
||||
});
|
||||
},
|
||||
onChangeQuery(val) {
|
||||
this.q = String(val);
|
||||
},
|
||||
clearQuery() {
|
||||
this.q = '';
|
||||
this.updateQuery();
|
||||
},
|
||||
updateQuery() {
|
||||
this.filter.q = this.q.trim();
|
||||
|
||||
if (this.loading) return;
|
||||
|
||||
const query = {
|
||||
|
|
|
@ -2,19 +2,20 @@
|
|||
<div v-infinite-scroll="loadMore" class="p-page p-page-errors" :infinite-scroll-disabled="scrollDisabled"
|
||||
:infinite-scroll-distance="1200" :infinite-scroll-listen-for-event="'scrollRefresh'">
|
||||
<v-toolbar flat :dense="$vuetify.breakpoint.smAndDown" class="page-toolbar" color="secondary">
|
||||
<v-text-field v-model.lazy.trim="filter.q"
|
||||
<v-text-field :value="filter.q"
|
||||
solo hide-details clearable overflow single-line validate-on-blur
|
||||
class="input-search background-inherit elevation-0"
|
||||
browser-autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="none"
|
||||
solo hide-details clearable overflow
|
||||
:label="$gettext('Search')"
|
||||
prepend-inner-icon="search"
|
||||
color="secondary-dark"
|
||||
@click:clear="clearQuery"
|
||||
@blur="updateQuery"
|
||||
@input="onChangeQuery"
|
||||
@change="updateQuery"
|
||||
@blur="updateQuery"
|
||||
@keyup.enter.native="updateQuery"
|
||||
@click:clear="clearQuery"
|
||||
></v-text-field>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon class="action-reload" :title="$gettext('Reload')" @click.stop="reload">
|
||||
|
@ -104,6 +105,7 @@ export default {
|
|||
dirty: false,
|
||||
loading: false,
|
||||
scrollDisabled: false,
|
||||
q: q,
|
||||
filter: {q},
|
||||
batchSize: 100,
|
||||
offset: 0,
|
||||
|
@ -119,7 +121,10 @@ export default {
|
|||
watch: {
|
||||
'$route'() {
|
||||
const query = this.$route.query;
|
||||
this.filter.q = query['q'] ? query['q'] : '';
|
||||
|
||||
this.q = query['q'] ? query['q'] : '';
|
||||
this.filter.q = this.q;
|
||||
|
||||
this.reload();
|
||||
}
|
||||
},
|
||||
|
@ -127,7 +132,16 @@ export default {
|
|||
this.loadMore();
|
||||
},
|
||||
methods: {
|
||||
onChangeQuery(val) {
|
||||
this.q = String(val);
|
||||
},
|
||||
clearQuery() {
|
||||
this.q = '';
|
||||
this.updateQuery();
|
||||
},
|
||||
updateQuery() {
|
||||
this.filter.q = this.q.trim();
|
||||
|
||||
if (this.loading) return;
|
||||
|
||||
const query = {};
|
||||
|
@ -146,10 +160,6 @@ export default {
|
|||
|
||||
this.$router.replace({query});
|
||||
},
|
||||
clearQuery() {
|
||||
this.filter.q = "";
|
||||
this.updateQuery();
|
||||
},
|
||||
showDetails(err) {
|
||||
this.details.err = err;
|
||||
this.details.show = true;
|
||||
|
|
|
@ -5,21 +5,20 @@
|
|||
|
||||
<v-form ref="form" class="p-people-search" lazy-validation dense @submit.prevent="updateQuery">
|
||||
<v-toolbar dense flat class="page-toolbar" color="secondary-light pa-0">
|
||||
<v-text-field id="search"
|
||||
v-model.lazy.trim="filter.q"
|
||||
<v-text-field :value="filter.q"
|
||||
solo hide-details clearable overflow single-line validate-on-blur
|
||||
class="input-search background-inherit elevation-0"
|
||||
solo hide-details
|
||||
:label="$gettext('Search')"
|
||||
prepend-inner-icon="search"
|
||||
browser-autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="none"
|
||||
clearable overflow
|
||||
color="secondary-dark"
|
||||
@click:clear="clearQuery"
|
||||
@blur="updateQuery"
|
||||
@input="onChangeQuery"
|
||||
@change="updateQuery"
|
||||
@blur="updateQuery"
|
||||
@keyup.enter.native="updateQuery"
|
||||
@click:clear="clearQuery"
|
||||
></v-text-field>
|
||||
|
||||
<v-divider vertical></v-divider>
|
||||
|
@ -213,6 +212,7 @@ export default {
|
|||
page: 0,
|
||||
selection: [],
|
||||
settings: settings,
|
||||
q: q,
|
||||
filter: filter,
|
||||
lastFilter: {},
|
||||
routeName: routeName,
|
||||
|
@ -244,10 +244,11 @@ export default {
|
|||
|
||||
const query = this.$route.query;
|
||||
|
||||
this.filter.q = query["q"] ? query["q"] : "";
|
||||
this.routeName = this.$route.name;
|
||||
this.q = query["q"] ? query["q"] : "";
|
||||
this.filter.q = this.q;
|
||||
this.filter.hidden = query["hidden"] ? query["hidden"] : "";
|
||||
this.filter.order = this.sortOrder();
|
||||
this.routeName = this.$route.name;
|
||||
|
||||
this.search();
|
||||
}
|
||||
|
@ -436,10 +437,6 @@ export default {
|
|||
this.busy = false;
|
||||
});
|
||||
},
|
||||
clearQuery() {
|
||||
this.filter.q = '';
|
||||
this.updateQuery();
|
||||
},
|
||||
addSelection(uid) {
|
||||
const pos = this.selection.indexOf(uid);
|
||||
|
||||
|
@ -531,7 +528,16 @@ export default {
|
|||
this.listen = true;
|
||||
});
|
||||
},
|
||||
onChangeQuery(val) {
|
||||
this.q = String(val);
|
||||
},
|
||||
clearQuery() {
|
||||
this.q = '';
|
||||
this.updateQuery();
|
||||
},
|
||||
updateQuery() {
|
||||
this.filter.q = this.q.trim();
|
||||
|
||||
if (this.loading || !this.active) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -4,14 +4,10 @@
|
|||
<div class="map-control">
|
||||
<div class="maplibregl-ctrl maplibregl-ctrl-group">
|
||||
<v-text-field v-model.lazy.trim="filter.q"
|
||||
solo hide-details clearable flat single-line validate-on-blur
|
||||
class="pa-0 ma-0 input-search"
|
||||
single-line
|
||||
solo
|
||||
flat
|
||||
:label="$gettext('Search')"
|
||||
prepend-inner-icon="search"
|
||||
clearable
|
||||
hide-details
|
||||
browser-autocomplete="off"
|
||||
autocorrect="off"
|
||||
autocapitalize="none"
|
||||
|
@ -56,6 +52,7 @@ export default {
|
|||
'$route'() {
|
||||
this.filter.q = this.query();
|
||||
this.lastFilter = {};
|
||||
|
||||
this.search();
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue