最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to validate a v-edit-dialog in a v-datatable - Stack Overflow

programmeradmin3浏览0评论

I'm new to vue.js and vuetify and currently trying to validate the input in a v-edit-dialog inside a v-datatable. The validation seems to work, however the save button does not get disabled and the user-input gets saved even when it's invalid. Is there a way to let the button be disabled or to prevent the saving of invalid data?

My datatable:

 <v-data-table dense :headers="headers" :items="sitesTable">
    <template v-slot:top>
        <v-spacer></v-spacer>

        <v-dialog v-model="dialog" max-width="500px">
            <v-card>
                <v-toolbar flat>
                    <v-toolbar-title v-model="title" class="primary--text">{{ title }} Site</v-toolbar-title>
                    <v-spacer></v-spacer>
                    <v-btn icon @click="close">
                        <v-icon>mdi-close</v-icon>
                    </v-btn>
                </v-toolbar>
                <v-card-text>
                    <v-container>
                        <FormTemplateSites v-bind:title="title" @dialog="!dialog"></FormTemplateSites>
                    </v-container>
                </v-card-text>
            </v-card>
        </v-dialog>
    </template>

    <template v-slot:item.name="props">
        <v-edit-dialog :return-value.sync="props.item.name" large persistent @save="saveName(props.item.name, props.item)">
            <div>{{ props.item.name }}</div>
            <template v-slot:input>
                <div class="mt-4 title">Update Name</div>
            </template>
            <template v-slot:input>
                <v-text-field v-model="props.item.name" :rules="required" label="Edit" single-line counter autofocus></v-text-field>
            </template>
        </v-edit-dialog>
    </template>

    <template v-slot:item.field="props">
        <v-edit-dialog :return-value.sync="props.item.field" large persistent @save="saveField(props.item.field, props.item)">
            <div>{{ props.item.field }}</div>
            <template v-slot:input>
                <div class="mt-4 title">Update Field</div>
            </template>
            <template v-slot:input>
                <v-text-field v-model="props.item.field" :rules="rules_vectors" label="Edit" single-line counter autofocus></v-text-field>
            </template>
        </v-edit-dialog>
    </template>

    <template v-slot:item.position="props">
        <v-edit-dialog :return-value.sync="props.item.position" large persistent @save="savePosition(props.item.position.x, props.item.position.y, props.item)">
            <div>{{ props.item.position }}</div>
            <template v-slot:input>
                <div class="mt-4 title">Update Position</div>
            </template>
            <template v-slot:input>
                <v-text-field v-model="props.item.position" label="Edit" single-line autofocus :rules="rules_vectors"></v-text-field>
            </template>
        </v-edit-dialog>
    </template>

    <template v-slot:item.actions="{ item }">
        <v-icon small class="mr-2" @click="editSite(item)">mdi-pencil</v-icon>
        <v-icon small @click="deleteItem(item)">mdi-delete</v-icon>
    </template>
</v-data-table>

My ponent:

data: () => ({
    title: '',
    dialog: false,
    required: [(v) => !!v || 'Required', ],
    rules_vectors: [
        (v) => !!v || 'Required',
        (v) => {
            try {
                v = JSON.parse(v)
                for (let item of v) {
                    if (!isNaN(item)) {
                        console.log(item)
                    } else {
                        return 'Invalid vector.'
                    }
                }
                return v.length === 2 || 'Invalid vector.'
            } catch (error) {
                console.log(error)
                return 'Invalid vector.'
            }
        },
    ],
    pagination: {},
    headers: [{
            text: 'Name',
            align: 'start',
            sortable: false,
            value: 'name',
        },
        {
            text: 'ID',
            align: 'start',
            sortable: false,
            value: 'id',
        },
        {
            text: 'Position',
            sortable: false,
            value: 'position',
        },
        {
            text: 'Field',
            sortable: false,
            value: 'field',
        },
        {
            text: 'Actions',
            value: 'actions',
            sortable: false,
        },
    ],
}),

    
    
   
   

I'm new to vue.js and vuetify and currently trying to validate the input in a v-edit-dialog inside a v-datatable. The validation seems to work, however the save button does not get disabled and the user-input gets saved even when it's invalid. Is there a way to let the button be disabled or to prevent the saving of invalid data?

My datatable:

 <v-data-table dense :headers="headers" :items="sitesTable">
    <template v-slot:top>
        <v-spacer></v-spacer>

        <v-dialog v-model="dialog" max-width="500px">
            <v-card>
                <v-toolbar flat>
                    <v-toolbar-title v-model="title" class="primary--text">{{ title }} Site</v-toolbar-title>
                    <v-spacer></v-spacer>
                    <v-btn icon @click="close">
                        <v-icon>mdi-close</v-icon>
                    </v-btn>
                </v-toolbar>
                <v-card-text>
                    <v-container>
                        <FormTemplateSites v-bind:title="title" @dialog="!dialog"></FormTemplateSites>
                    </v-container>
                </v-card-text>
            </v-card>
        </v-dialog>
    </template>

    <template v-slot:item.name="props">
        <v-edit-dialog :return-value.sync="props.item.name" large persistent @save="saveName(props.item.name, props.item)">
            <div>{{ props.item.name }}</div>
            <template v-slot:input>
                <div class="mt-4 title">Update Name</div>
            </template>
            <template v-slot:input>
                <v-text-field v-model="props.item.name" :rules="required" label="Edit" single-line counter autofocus></v-text-field>
            </template>
        </v-edit-dialog>
    </template>

    <template v-slot:item.field="props">
        <v-edit-dialog :return-value.sync="props.item.field" large persistent @save="saveField(props.item.field, props.item)">
            <div>{{ props.item.field }}</div>
            <template v-slot:input>
                <div class="mt-4 title">Update Field</div>
            </template>
            <template v-slot:input>
                <v-text-field v-model="props.item.field" :rules="rules_vectors" label="Edit" single-line counter autofocus></v-text-field>
            </template>
        </v-edit-dialog>
    </template>

    <template v-slot:item.position="props">
        <v-edit-dialog :return-value.sync="props.item.position" large persistent @save="savePosition(props.item.position.x, props.item.position.y, props.item)">
            <div>{{ props.item.position }}</div>
            <template v-slot:input>
                <div class="mt-4 title">Update Position</div>
            </template>
            <template v-slot:input>
                <v-text-field v-model="props.item.position" label="Edit" single-line autofocus :rules="rules_vectors"></v-text-field>
            </template>
        </v-edit-dialog>
    </template>

    <template v-slot:item.actions="{ item }">
        <v-icon small class="mr-2" @click="editSite(item)">mdi-pencil</v-icon>
        <v-icon small @click="deleteItem(item)">mdi-delete</v-icon>
    </template>
</v-data-table>

My ponent:

data: () => ({
    title: '',
    dialog: false,
    required: [(v) => !!v || 'Required', ],
    rules_vectors: [
        (v) => !!v || 'Required',
        (v) => {
            try {
                v = JSON.parse(v)
                for (let item of v) {
                    if (!isNaN(item)) {
                        console.log(item)
                    } else {
                        return 'Invalid vector.'
                    }
                }
                return v.length === 2 || 'Invalid vector.'
            } catch (error) {
                console.log(error)
                return 'Invalid vector.'
            }
        },
    ],
    pagination: {},
    headers: [{
            text: 'Name',
            align: 'start',
            sortable: false,
            value: 'name',
        },
        {
            text: 'ID',
            align: 'start',
            sortable: false,
            value: 'id',
        },
        {
            text: 'Position',
            sortable: false,
            value: 'position',
        },
        {
            text: 'Field',
            sortable: false,
            value: 'field',
        },
        {
            text: 'Actions',
            value: 'actions',
            sortable: false,
        },
    ],
}),

    
    
   
   
Share Improve this question asked Sep 25, 2020 at 14:58 GemGem 811 silver badge4 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

I had the same question

Is there a way to let the button be disabled or to prevent the saving of invalid data?

I found a way to de-couple the item value passed from the editted value and "prevent the saving of invalid data".

By using a seperate data field editName and linking the v-text-field to this, you can set the value on open and check and set it on save, without the item value being polluted by invalid values.

So

  1. the v-model for the v-text-field is v-model="editName"
  2. the v-edit-dialog has @open which sets the edit value - @open="editName = props.item.name"
  3. you check the this.editName on save in your saveName(props.item)

as in

  <v-data-table dense :headers="headers" :items="sitesTable">    
    <template v-slot:item.name="props">
      <v-edit-dialog           
            large 
        persistent 
            @save="saveName(props.item)"
            @open="editName = props.item.name"
        >
        <div>{{ props.item.name }}</div>
        <template v-slot:input>
          <div class="mt-4 title">Update Name</div>
        </template>
        <template v-slot:input>
          <v-text-field 
                      v-model="editName" 
                      :rules="required" 
                      label="Edit" 
                      single-line 
                      counter 
                      autofocus
                  ></v-text-field>
        </template>
      </v-edit-dialog>
    </template>
  </v-data-table>

on Save

saveName(item) {
  if (this.validate(this.editName) {
    item.name = this.editName
   
    ...
  }
}

Edit. I removed the :return-value.sync="props.item.name" attribute on v-data-table as it seemed to be over-riding the setting of item.name in the saveName() function

I ran into the same thing and with some searching it turns out v-edit-dialog is going to be removed in v3 ... which doesn't help us now, but I did e up with a nimble solution that might work for you too.

<v-form v-model="isFormValid">
  <v-data-table
      :headers="headers"
      :items="items"
      item-key="ID"
  >
    <template v-slot:item.column="{ item }">
      <v-text-field
          v-model="itemData"
          :rules="[validationRulesHere]"
          required
      ></v-text-field>
    </template>
  </v-data-table>
  <v-btn :disabled="!isFormValid">Save</v-btn>
</v-form>

I wrapped the whole table in a form and used it to overall tell me if everything in the table was correct.

发布评论

评论列表(0)

  1. 暂无评论