Skip to content

Commit

Permalink
feat: автодополнение для фильтра
Browse files Browse the repository at this point in the history
- всегда подставляет =1 в конец
- ищет от последнего результата (на пустом результате ничего не ищет)
- теперь фильтрует не по мере набора, а по ентеру
- некрасиво вылазит при открытии страницы
  • Loading branch information
popstas committed Dec 10, 2018
1 parent 8f45ba7 commit 10caa05
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Читаемая таблица по умолчанию (входит по ширине в экран)
- Возможность вывести в таблицу любое интересующее поле (всего их около 70)
- Фильтрация по любому полю, сохранение фильтров в урле
- Автодополнение для фильтра
- Быстрый фильтр по домену
- Сортировка по любому полю
- Подсветка результатов валидации site-info (каждая колонка)
Expand Down
70 changes: 66 additions & 4 deletions components/Toolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,35 @@
></FieldGroup>
</div>

<input
<el-autocomplete
class="filter__query"
placeholder="query"
v-model="q"
autofocus
title="Например:
engine:bitrix prod:1"
v-bind:style="{width: filterWidth + 'px'}"
>
ref="input"

:fetch-suggestions="queryComplete"
@select="querySelect"
@keyup.enter.native="queryChangeAction"
></el-autocomplete>

<div class="filter__query-tags">
<el-tag closable
v-for="tag in queryParts" :key="tag"
v-if="tag != ''"
:disable-transitions="false"
@close="handleTagClose(tag)"
v-html="tag.replace(/=1$/, '').replace('=', ' = ')"
></el-tag>
</div>

<div class="filter-presets">filters:
<FilterPresetButton
:preset="preset"
@click="q = preset.q"
@click="q = preset.q; queryChangeAction()"
v-for="preset in filterPresets"
:key="preset.name"
:class="{ 'filter-presets__button_active': preset.q == q }"
Expand All @@ -58,6 +73,15 @@
</div>
</template>

<style lang="scss">
.el-autocomplete-suggestion {
min-width: 360px;
}
.el-tag {
margin: 0 5px;
}
</style>

<script>
import _ from "lodash";
import columnPresets from "~/assets/js/presets/columns.conf";
Expand All @@ -72,6 +96,7 @@ export default {
data() {
return {
q: "",
lastQ: "",
columnPresets: columnPresets,
filterPresets: filterPresets,
routerProcess: false,
Expand All @@ -84,6 +109,10 @@ export default {
return this.$store.state.tests;
},
queryParts() {
return this.q.split('&');
},
// раскладывает поля по группам, с дублированием
fieldGroups() {
let groups = { unnamed: { name: "", fields: [] } };
Expand Down Expand Up @@ -117,7 +146,8 @@ export default {
watch: {
q(val) {
this.debouncedQueryChangeAction(); // задержка после ввода фильтра
this.lastQ = this.q;
// this.debouncedQueryChangeAction(); // задержка после ввода фильтра
}
},
Expand All @@ -127,9 +157,18 @@ export default {
methods: {
queryChangeAction() {
this.q = this.normalizeQuery(this.q);
this.$emit("changeFilter", this.q);
},
normalizeQuery(q) {
const parts = q.split('&');
const normalizedParts = parts.map(part => {
return part.replace(/^([a-z_0-9]+)$/, '$1=1'); // prod => prod=1
});
return normalizedParts.join('&');
},
// сворачивает/разворачивает одну группу
changeGroupOpened(group) {
this.fieldGroupsOpened[group.name] =
Expand Down Expand Up @@ -165,9 +204,32 @@ export default {
return this.fields.findIndex(column => {
return field && column.name == field.name;
});
},
// autocomplete of query
queryComplete(q, cb){
const parts = q.split('&');
const lastPart = parts[parts.length - 1];
const matchFields = this.availableFields.filter(filter => filter.name.includes(lastPart));
const sortedFields = matchFields.sort((a,b) => (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0));
cb(sortedFields.map(field => { return { value: field.name }}));
},
// выбор автодополнения
querySelect(q){
this.$refs.input.focus();
let parts = this.lastQ.split('&');
parts[parts.length - 1] = q.value;
this.q = parts.join('&');
this.queryChangeAction();
}
},
handleTagClose(tag) {
console.log('remove tag: ', tag);
this.q = this.q.replace(tag + '&', '').replace('&' + tag, '').replace(tag, '');
},
mounted() {
// filter init
if (this.$route.query["q"]) this.q = this.$route.query["q"];
Expand Down

0 comments on commit 10caa05

Please sign in to comment.