如何验证动态创建的输入

时间:2017-11-23 07:01:05

标签: javascript validation vuejs2 vuetify.js

我有一个选择输入,在选择一个值时,应根据最初选择的值生成另一组输入。我遇到的问题是验证。如果我单独关注每个特定输入,验证工作正常。我需要的是一种验证所有输入字段的方法。现在我已经有一个名为validateAllInputs()的函数,它在我工作的另一个页面上工作,尽管该页面上的输入字段本质上是静态的。当我在这个页面使用相同的代码但是我一直收到错误“ _this。$ refs [f] .validate不是函数

这是我的HTML代码。

<div id="app">
    <v-app>
        <v-content>
            <v-container grid-list-md>
                <div class="title grey--text">CASE</div>
                <div class="display-2" style="font-family: Oswald;">RECORD OF CASES CLOSED</div>

                <p>&nbsp;</p>

                <v-snackbar
                        :timeout="timeout"
                        :top="y === 'top'"
                        :bottom="y === 'bottom'"
                        :right="x === 'right'"
                        :left="x === 'left'"
                        :multi-line="mode === 'multi-line'"
                        :vertical="mode === 'vertical'"
                        v-model="snackbar"
                >
                    Saved
                    <v-btn flat color="pink" @click.native="snackbar = false">Close</v-btn>
                </v-snackbar>

                <v-card>
                    <v-card-text>

                        <v-layout>
                            <v-flex xs1 class="text-xs-center pt-4">
                                <v-icon color="blue-grey lighten-2">label</v-icon>
                            </v-flex>
                            <v-flex xs4>
                                <v-menu
                                        lazy
                                        :close-on-content-click="false"
                                        v-model="menu01"
                                        transition="scale-transition"
                                        offset-y
                                        full-width
                                        :nudge-right="40"
                                        max-width="290px"
                                        min-width="290px"
                                >
                                    <v-text-field
                                            slot="activator"
                                            label="Case Closing Date"
                                            v-model="date02"
                                            append-icon="event"
                                            readonly
                                    ></v-text-field>
                                    <v-date-picker
                                            v-model="date02"
                                            no-title
                                            scrollable
                                            actions
                                    >
                                        <template scope="{ save, cancel }">
                                            <v-card-actions>
                                                <v-spacer></v-spacer>
                                                <v-btn flat color="blue" @click="cancel">Cancel</v-btn>
                                                <v-btn flat color="blue" @click="save">OK</v-btn>
                                            </v-card-actions>
                                        </template>
                                    </v-date-picker>
                                </v-menu>
                            </v-flex>
                            <v-flex xs6>
                            </v-flex>
                            <v-flex xs1 class="text-xs-center pt-4">
                            </v-flex>
                        </v-layout>

                        <v-layout>
                            <v-flex xs1 class="text-xs-center pt-4">
                                <v-icon color="blue-grey lighten-2">label</v-icon>
                            </v-flex>
                            <v-flex xs4>
                                <v-select label="How Many Cases Closed?" :items="counter_1_to_20" v-model="countCases" autocomplete></v-select>
                            </v-flex>
                        </v-layout>

                    </v-card-text>
                </v-card>

                <template v-if="countCases != null">
                    <br />
                    <v-card v-for="i in countCases" ref="form">
                            <v-card-text>
                                <v-layout>
                                    <!-- <v-flex xs1 class="text-xs-center pt-4">
                                        <v-icon color="blue-grey lighten-2">label</v-icon>
                                    </v-flex> -->
                                    <v-flex xs1 class="text-xs-center pt-2">
                                        <v-btn color="blue darken-1" fab dark small class="elevation-0" style="z-index: 0;">{{i}}</v-btn>
                                    </v-flex>
                                    <v-flex xs10>
                                        <v-layout>
                                            <v-flex xs12>
                                                <v-text-field name="caseTitle"  ref="caseTitle" v-model="data.caseTitle[i-1]" :rules="[rules.required]" label="Case Title"></v-text-field>
                                            </v-flex>
                                        </v-layout>

                                        <v-layout>
                                            <v-flex xs1 class="text-xs-center pt-4">
                                                <v-icon color="blue-grey lighten-2">trending_flat</v-icon>
                                            </v-flex>
                                            <v-flex xs6>
                                                <v-text-field name="caseRefNumber" ref="caseRefNumber" v-model="data.caseRefNumber[i-1]" :rules="[rules.required]" label="Case Ref Number"></v-text-field>
                                            </v-flex>
                                        </v-layout>

                                        <v-layout>
                                            <v-flex xs1 class="text-xs-center pt-4">
                                                <v-icon color="blue-grey lighten-2">trending_flat</v-icon>
                                            </v-flex>
                                            <v-flex xs6>
                                                <v-select name="validityPeriod" ref="validityPeriod" v-model="data.validityPeriod[i-1]" :rules="[rules.required]" label="Validity Period" :items="optionsValidityPeriod"></v-select>
                                            </v-flex>
                                        </v-layout>

                                        <v-layout>
                                            <v-flex xs1 class="text-xs-center pt-4">
                                                <v-icon color="blue-grey lighten-2">trending_flat</v-icon>
                                            </v-flex>
                                            <v-flex xs6>
                                                <!-- <v-select label="Officer I/C for Tender"></v-select> -->
                                                <v-flex xs12>
                                                    <v-select
                                                            name="officerIC"
                                                            label="Officer I/C for Case"
                                                            v-bind:items="optionsOfficers"
                                                            item-text="name"
                                                            item-value="name"
                                                            max-height="auto"
                                                            autocomplete
                                                            :rules="[rules.required]"
                                                            ref="officerIC"
                                                            v-model="data.officerIC[i-1]"
                                                    >
                                                        <template slot="item" scope="data">
                                                            <template v-if="typeof data.item !== 'object'">
                                                                <v-list-tile-content v-text="data.item"></v-list-tile-content>
                                                            </template>
                                                            <template v-else>
                                                                <v-list-tile-content>
                                                                    <v-list-tile-title v-html="data.item.name"></v-list-tile-title>
                                                                    <v-list-tile-sub-title v-html="data.item.dept"></v-list-tile-sub-title>
                                                                </v-list-tile-content>
                                                            </template>
                                                        </template>
                                                    </v-select>
                                                </v-flex>
                                            </v-flex>
                                        </v-layout>
                                        <br/>
                                    </v-flex>
                                </v-layout>
                            </v-card-text>
                    </v-card>
                    <br />

                    <v-card class="blue-grey darken-2 white--text" dark>
                        <v-card-text>

                            <br /><br />

                            <v-layout>
                                <v-flex xs10>
                                    <v-btn color="orange" @click="validateAllInputs()">Add Case</v-btn>
                                </v-flex>
                            </v-layout>

                        </v-card-text>
                    </v-card>

                </template>

            </v-container>

        </v-content>

        <br /><br />

    </v-app>
</div>

这是我的剧本

 export default({
data () {
  return {
    drawer: null,
    items: [
      { title: 'Home', icon: 'dashboard', url: 'tt.html' },
      { title: 'About', icon: 'question_answer', url: 'tt.html' },
    ],
    e1: 0,

    snackbar: false,
    y: 'top',
    x: 'middle',
    mode: '',
    timeout: 1600,
    text: 'Saved',

    data: {
      caseTitle: [],
      caseRefNumber: [],
      validityPeriod: [],
      officerIC: [],
    },

    date02: null,
    menu01: null,

    countCases: null,

    formHasErrors: false,


    rules: {
      required: value => !!value || 'Required.',
    },

    counter_1_to_20: [
      1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    ],

    optionsValidityPeriod: [
      '90 days', '120 days',
    ],
    optionsOfficers: [
      {
        header: 'Department 1',
      },
      {
        name: 'John',
        dept: 'Senior Detective',
      },
      {
        name: 'Smith',
        dept: 'Junior Detective',
      },
      {
        divider: true,
      },
      {
        header: 'Department 2',
      },
      {
        name: 'Mary',
        dept: 'Senior Detective',
      },
    ],
  }
},
computed: {
  form() {
    return {
      officerIC: this.data.officerIC,
      caseTitle: this.data.caseTitle,
      caseRefNumber: this.data.caseRefNumber,
      validityPeriod: this.data.validityPeriod,
    };
  },
},
methods: {
  validateAllInputs() {
    this.formHasErrors = false;
    Object.keys(this.form).forEach(f => {
      if (this.$refs[f].validate(true) === false) {
        this.formHasErrors = true;
        this.$refs[f].validate(true);
        this.text = 'Please rectify errors before proceeding.';
        this.snackbar = true;
      }
    });

    if (this.formHasErrors === false) {
      this.text = 'Saved';
      this.snackbar = true;
    }
  },
}

});

1 个答案:

答案 0 :(得分:1)

将您要验证的输入放在v-form内,然后拨打this.$refs.form.validate()

https://vuetifyjs.com/components/forms#example-2

v-form将为您处理动态创建的输入,如果它们不存在,它们将不会包含在验证中。

PR中有一个基本的例子,我改进了这个功能:
https://github.com/vuetifyjs/vuetify/pull/1581
https://codepen.io/anon/pen/VzRKEW?editors=1010