9
votes

Comment avoir un filtre de saisie semi-automatique Vue / Vuetify sur deux propriétés?

Contexte

J'ai donc une entrée de saisie semi-automatique vuetify que j'utilise pour rechercher une table de pièces. La table des pièces a une colonne d'identité, une colonne de numéro de pièce, une colonne de révision, une colonne de description et quelques autres colonnes d'informations.

Je l'ai fait fonctionner, donc les options de saisie semi-automatique affichent le numéro de pièce, la rév. Et les descriptions lors de la saisie dans le champ de texte, filtre les pièces par numéro de pièce.

 Current Version pic 1

Problem

Mais mon objectif est d'être capable de filtrer à la fois le numéro de pièce et la description.

J'ai essayé de modifier item-text = "fpartno" mais je n'arrive pas à comprendre comment le faire fonctionner avec deux ou plus de propriétés. Et la plupart des solutions que j'ai trouvées en ligne n'affectent que la façon dont les options sont affichées et non la façon dont elles sont filtrées.

La suppression de élément-texte ne fonctionne pas non plus.

 Current Version pic 2

Code

J'ai mis ma saisie semi-automatique dans le composant de page unique. J'utilise actuellement Typescript mais j'accepterai également une réponse qui utilise javascript. Si je peux simplement utiliser la syntaxe du modèle, ce serait idéal.

Remarque: la propriété fcomment contient la description au cas où quelqu'un serait confus. p>

<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>

Si vous avez besoin de plus de détails, faites-le moi savoir, et merci d'avance.


0 commentaires

3 Réponses :


4
votes

J'ai donc réalisé que j'utilisais le mauvais outil pour le travail. En lisant la documentation, j'ai dû manquer la section concernant la liste déroulante qui a tout ce dont j'ai besoin.

Quoi qu'il en soit, changer v-autocomplete en v-combobox en supprimant item-text = "fpartno" et l'ajout d'un filtre personnalisé a donné à mon composant la fonctionnalité dont j'avais besoin.

Ici, il fonctionne correctement:

 Correction de l'image 1

Voici mon code mis à jour:

<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>

Parce que le titre de la question mentionne Autocomplete pas combobox, je ne pense pas que cela La réponse suffit pour être considérée comme la meilleure réponse. À moins que la saisie semi-automatique ne soit toujours le mauvais outil.


0 commentaires

3
votes

À emporter:

no-filter="true"

et utiliser:

item-text="fpartno"


0 commentaires

8
votes

En retard dans le jeu ici mais la solution est de lier un filtre personnalisé

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

puis de définir le comportement

<v-autocomplete
  :filter="filterObject"
>

Le v-autocomplete filter prop documentation fournit un lien vers le implémentation ts par défaut .


0 commentaires