如何在两个属性上设置Vue / Vuetify自动完成过滤器?

时间:2019-02-06 20:22:11

标签: javascript typescript vue.js vuetify.js

背景

所以我有一个自动完成输入,可以用来搜索零件表。零件表具有标识列,零件号列,修订版列,描述列和其他一些信息列。

我可以使用它,因此在文本字段中键入时,自动完成选项会显示零件号,版本和说明。

Current Version pic 1

问题

但是我的目标是能够同时过滤零件号和描述。

我尝试修改 item-text =“ fpartno” ,但无法弄清楚如何使其与两个或多个属性一起使用。而且,我在网上找到的大多数解决方案只会影响选项的显示方式,而不会影响它们的过滤方式。

此外,删除项目文本也不起作用。

Current Version pic 2

代码

我将自动完成功能放入了“单页组件”中。我目前正在使用Typescript,但我也会接受使用javascript的答案。如果我可以使用理想的模板语法。

注意:属性 fcomment 包含描述,以防万一。

<template>
    <v-container fluid grid-list-xl>
        <v-layout wrap align-center>
            <v-flex xs12 sm6 d-flex>
                <v-autocomplete :items="inmastxs"
                                label="Part #"
                                item-value="identity_column"
                                item-text="fpartno"
                                cache-items
                                :search-input.sync="search"
                                solo>
                    <template slot="selection" slot-scope="data">
                        {{ data.item.fpartno }} - {{ data.item.frev }} ({{ data.item.fcomment }})
                    </template>
                    <template slot="item" slot-scope="data">
                        {{ data.item.fpartno }} - {{ data.item.frev }} ({{ data.item.fcomment }})
                    </template>

                </v-autocomplete>
            </v-flex>
        </v-layout>
    </v-container>
</template>

<script lang="ts">

    import Vue from 'vue'
    import { Component, Prop, Watch } from 'vue-property-decorator';
    import { inmastx } from '../../models/M2M/inmastx';
    import axios from 'axios';

    @Component({})
    export default class InMastxSearch extends Vue {
        private search: string = "";
        private PartNumber: string = "";
        private loading: boolean = false;
        private inmastxs: inmastx[] = [];

        @Watch('search')
        onPropertyChanged(value: string, oldValue: string) {
            this.fetchParts(value);
        }


        private mounted() {
            this.fetchParts("");
        }

        private fetchParts(value: string) {
            if (value == null) {
                value = "";
            }

            console.log(value);
            this.loading = true
            axios.get("../odata/inmastx?$orderby=fpartno,frev&$top=10&$filter=contains(fpartno,'" + value + "') or contains(fcomment,'" + value + "')")
                .then((response) => {
                    this.inmastxs = response.data.value;
                    console.log(this.inmastxs);
                })
                .catch(function (error) {
                    console.log(error);
                }).then(() => {
                    this.loading = false;
                });
        }
    }
</script>

如果您需要更多详细信息,请告诉我,谢谢。

3 个答案:

答案 0 :(得分:1)

所以我意识到我在使用错误的工具来完成这项工作。在阅读文档时,我一定错过了有关“组合框”的部分,其中包含了我所需的一切。

无论如何,将 v-autocomplete 更改为 v-combobox ,删除 item-text =“ fpartno” 并添加自定义过滤器,我需要的功能。

此处正常运行:

Fixed pic 1

下面是我更新的代码:

<template>
    <v-container fluid grid-list-xl>
        <v-layout wrap align-center>
            <v-flex xs12 sm6 d-flex>
                <v-combobox :items="inmastxs"
                                label="Part #"
                                item-value="identity_column"
                                :filter="PartRevDescFilter"
                                cache-items
                                :search-input.sync="search"
                                solo>
                    <template slot="selection" slot-scope="data">
                        {{ data.item.fpartno }} - {{ data.item.frev }} ({{ data.item.fcomment }})
                    </template>
                    <template slot="item" slot-scope="data">
                        {{ data.item.fpartno }} - {{ data.item.frev }} ({{ data.item.fcomment }})
                    </template>    
                </v-combobox>
            </v-flex>
        </v-layout>
    </v-container>
</template>

<script lang="ts">

    import Vue from 'vue'
    import { Component, Prop, Watch } from 'vue-property-decorator';
    import { inmastx } from '../../models/M2M/inmastx';
    import axios from 'axios';

    @Component({})
    export default class InMastxSearch extends Vue {
        private search: string = "";
        private PartNumber: string = "";
        private loading: boolean = false;
        private inmastxs: inmastx[] = [];

        @Watch('search')
        onPropertyChanged(value: string, oldValue: string) {
            this.fetchParts(value);
        }    

        private mounted() {
            this.fetchParts("");
        }

        private fetchParts(value: string) {
            if (value == null) {
                value = "";
            }
            this.loading = true
            axios.get("../odata/inmastx?$orderby=fpartno,frev&$top=10&$filter=contains(fpartno,'" + value + "') or contains(fcomment,'" + value + "')")
                .then((response) => {
                    this.inmastxs = response.data.value;
                })
                .catch(function (error) {
                    console.log(error);
                }).then(() => {
                    this.loading = false;
                });
        }

        private PartRevDescFilter(item: inmastx, queryText, itemText) {         
            return (item.fpartno.toLowerCase().includes(queryText.toLowerCase()) || item.frev.toLowerCase().includes(queryText.toLowerCase()) || item.fcomment.toLowerCase().includes(queryText.toLowerCase()));
        }
    }
</script>

因为问题的标题提到“自动完成而不是组合框”,我认为此答案不足以被视为最佳答案。除非“自动完成”一直是错误的工具。

答案 1 :(得分:1)

带走:

item-text="fpartno"

并使用:

no-filter="true"

答案 2 :(得分:1)

在这里晚了游戏,但是解决方案是绑定自定义过滤器

<v-autocomplete
  :filter="filterObject"
>

然后定义行为

  methods: {
    filterObject(item, queryText, itemText) {
      return (
        item.prop1.toLocaleLowerCase().indexOf(queryText.toLocaleLowerCase()) >
          -1 ||
        item.prop2.toLocaleLowerCase().indexOf(queryText.toLocaleLowerCase()) > -1
      );
    }
  }

v-autocomplete filter prop documentation提供了指向default ts implementation的链接。