Search code examples
vue.jscomboboxvuetify.js

Multiple Vuetify Comboboxes with extensible Items


hopefully someone can help me with this.

I'd like to have an app that does the following: The User can add multiple parts of a form including text inputs and comboboxes. The form is to get user input about firewall rules, so I need to check for a name, and in 2 comboboxes the user is supposed ot be able to select from pre-defined items but also should be able to extend the pre-defined items with new ones.

By binding the v-model="model" on both comboboxes, I get the same selected items (which I don't want), so for the second combobox I assining v-model="model2", that works and I can append new entries to the items list, which works fine. (this.items.push(this.model[this.model.length-1])) resp. this.items.push(this.model2[this.model2.length-1])

But how could I do this with a "v-for" for an unknown number of forms, as the user can increase the amount of forms by a button press?

Can I do something like v-model="model({{index}})?

<div id="app">
<v-app id="inspire" v-for="(rule, index) in rules">
    <v-form
            ref="form"
            v-model="valid"
            lazy-validation
    >
        <v-text-field
                v-model="name"
                :counter="10"
                :rules="nameRules"
                label="Name"
                required
        ></v-text-field>
        <v-combobox
                v-model="model"
                :items="items"
                :search-input.sync="search"
                hide-selected
                hint="Maximum of 5 tags"
                label="Add some tags"
                multiple
                persistent-hint
                small-chips
        >
            <template v-slot:no-data>
                <v-list-item>
                    <v-list-item-content>
                        <v-list-item-title>
                            No results matching "<strong>{{ search }}</strong>". Press <kbd>enter</kbd> to create a new one
                        </v-list-item-title>
                    </v-list-item-content>
                </v-list-item>
            </template>
        </v-combobox>
        <v-combobox
                v-model="model2"
                :items="items"
                :search-input.sync="search"
                hide-selected
                hint="Maximum of 5 tags"
                label="Add some tags"
                multiple
                persistent-hint
                small-chips
        >
            <template v-slot:no-data>
                <v-list-item>
                    <v-list-item-content>
                        <v-list-item-title>
                            No results matching "<strong>{{ search }}</strong>". Press <kbd>enter</kbd> to create a new one
                        </v-list-item-title>
                    </v-list-item-content>
                </v-list-item>
            </template>
        </v-combobox>
    </v-form>
</v-app>
<script>
new Vue({
    el: '#app',
    vuetify: new Vuetify(),
    data: () => ({
        items: ['All', '10.0.0.0/8', '192.168.0.0/16'],
        model: null,
        model2: null,
        search: null,
        valid: true,
        name: '',
        nameRules: [
            v => !!v || 'Name is required',
            v => (v && v.length <= 10) || 'Name must be less than 10 characters',
        ],
        select: null,
        checkbox: false,
        rules: [1, 2, 3]
    }),
    watch: {
        model(val) {
            //if (val.length > 5) {
            //    this.$nextTick(() => this.model.pop())
            //}
            this.items.push(this.model[this.model.length-1])
        },
        model2(val) {
            //if (val.length > 5) {
            //    this.$nextTick(() => this.model.pop())
            //}
            this.items.push(this.model2[this.model2.length-1])
        },
    }
})

I removed the buttons etc. and made the rules arrary with static 3 entries, as this is working already.

Thanks in advance!


Solution

  • You can create rules As an array of objects that contains the model1 model2 for each rule and bind them to the combobox v-model like so:

    data: () => ({
            // all your other data
            rules: [
               { Id: 1, model1: null, model2: null },
               { Id: 1, model1: null, model2: null },
            ]
        }),
    

    In your template:

    
    <v-combobox
         v-model="rule.model1"
         // all the rest
    
    />