【问题标题】:Vee validate - repeat form - checkboxVee 验证 - 重复表单 - 复选框
【发布时间】:2021-11-07 08:51:48
【问题描述】:

我有一个简单的表单,其中包含一些输入来获取联系人详细信息。可以使用提供的添加按钮重复该表单。如果要添加多个联系人,用户必须选择一个主要联系人。我有一个自定义验证器。 当添加几行并取消选择所有主要联系人复选框然后选择一个时,就会出现我的问题。 - 此时,我希望之前显示的所有错误都消失。出于某种原因,双向数据绑定似乎不起作用,或者我一定做错了什么。假设我对其他字段进行了更多验证,我该如何解决与主要联系人复选框相关的验证错误?

<template>
  <div id="app">
    <b-col md="12">
      <ValidationObserver ref="contactValidation">
        <b-row
          v-for="(item, index) in contactDtos"
          :id="item.id"
          :key="item.id"
          ref="row"
        >
          <b-col md="3">
            <!-- First Name -->
            <b-form-group>
              <ValidationProvider
                #default="{ errors }"
                name="First name"
                vid="FirstName"
              >
                <b-form-input
                  id="'firstName' + item.id"
                  v-model="item.firstName"
                  :state="errors.length > 0 ? false : null"
                  placeholder="First Name"
                />
                <small class="text-danger">{{ errors[0] }}</small>
              </ValidationProvider>
            </b-form-group>
          </b-col>
          <b-col md="3">
            <!-- Last Name -->
            <b-form-group>
              <ValidationProvider
                #default="{ errors }"
                name="Last name"
                vid="LastName"
              >
                <b-form-input
                  id="'lastName' + item.id"
                  v-model="item.lastName"
                  :state="errors.length > 0 ? false : null"
                  placeholder="Last Name"
                />
                <small class="text-danger">{{ errors[0] }}</small>
              </ValidationProvider>
            </b-form-group>
          </b-col>
          <b-col md="3" class="mt-2">
            <!-- Primary contact -->
            <b-form-group>
              <ValidationProvider
                #default="{ errors }"
                :rules="{ chk_primary_contact: [contactDtos, item.id] }"
                name="Primary contact"
                vid="PrimaryContact"
              >
                <b-form-checkbox
                  v-model="item.primaryContact"
                  :checked="item.primaryContact"
                  :state="errors.length > 0 ? false : null"
                >
                  Primary contact
                </b-form-checkbox>
                <small class="text-danger">{{ errors[0] }}</small>
              </ValidationProvider>
            </b-form-group>
          </b-col>
          <b-col md="2" class="mt-2">
            <b-row>
              <b-col v-if="index + 1 == contactDtos.length" cols="6">
                <b-button
                  :v-if="false"
                  variant="outline-primary"
                  class="rounded-circle"
                  @click="contactFormRepeat"
                >
                  Add
                </b-button>
              </b-col>
              <b-col
                v-if="index + 1 == contactDtos.length && contactDtos.length > 1"
                cols="6"
              >
                <b-button
                  variant="outline-danger"
                  class="rounded-circle"
                  @click="removeContactForm(index)"
                >
                  Delete
                </b-button>
              </b-col>
            </b-row>
          </b-col>
          <b-col cols="12">
            <hr />
          </b-col>
        </b-row>
      </ValidationObserver>
    </b-col>
  </div>
</template>

<script>
import { extend, ValidationProvider, ValidationObserver } from "vee-validate";
import {
  BRow,
  BCol,
  BFormGroup,
  BFormInput,
  BFormCheckbox,
  BButton,
  // BFormInvalidFeedback,
} from "bootstrap-vue";

export const validatorPrimaryContact = (chkValue, [contactDtos, id]) => {
  console.log(id);
  if (contactDtos === undefined || id === undefined) return true;

  if (chkValue) {
    contactDtos.forEach((x) => {
      if (x.id !== id) {
        // remove if multiple check boxes are checked.
        x.primaryContact = false;
      }
    });
    const contactCount = contactDtos.filter((x) => x.primaryContact === true);
    if (contactCount.length === 1) {
      return true;
    }
    return false;
  } else {
    const contactCount = contactDtos.filter((x) => x.primaryContact === true);
    if (contactCount.length === 0) {
      return false;
    } else {
      return true;
    }
  }
};

extend("chk_primary_contact", {
  validate: validatorPrimaryContact,
  message: "Please select a primary contact",
});

export default {
  name: "App",
  components: {
    ValidationProvider,
    ValidationObserver,
    BRow,
    BCol,
    BFormGroup,
    BFormInput,
    BFormCheckbox,
    BButton,
  },
  data() {
    return {
      contactDtos: [
        {
          id: 1,
          firstName: "",
          LastName: "",
          primaryContact: true,
        },
      ],
    };
  },
  methods: {
    contactFormRepeat() {
      const { length } = this.contactDtos;
      this.contactDtos.push({
        id: length + 1,
        firstName: "",
        lastName: "",
        contactEmail: "",
        contactPhone: "",
        primaryContact: false,
      });
    },
    removeContactForm(index) {
      this.contactDtos.splice(index, 1);
      if (this.contactDtos.length === 1) {
        this.contactDtos[0].primaryContact = true;
      }
    },
  },
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

请找到沙盒here

任何帮助将不胜感激!

【问题讨论】:

    标签: vue.js vee-validate


    【解决方案1】:

    您找到解决方案了吗? 由于未触发您单击的复选框以外的其他复选框, 自己手动删除错误怎么样?

    为复选框验证提供程序提供ref 以及触发复选框时 删除其他复选框错误。像这样的...

    template:

    <ValidationProvider
                    :ref="`PrimaryContact${index}`"
                    #default="{ errors }"
                    :rules="{ chk_primary_contact: [contactDtos, item.id] }"
                    name="Primary contact"
                    vid="PrimaryContact"
                  >
                    <b-form-checkbox
                      v-model="item.primaryContact"
                      :checked="item.primaryContact"
                      :state="errors.length > 0 ? false : null"
                      @change="onChange(index)"
                    >
                      Primary contact
                    </b-form-checkbox>
                    <small class="text-danger">{{ errors[0] }}</small>
                  </ValidationProvider>
    

    `方法:

    onChange(ref) {
          console.info(ref);
          for (let i = 0; i < this.contactDtos.length; i++) {
            console.info(`i == ${i}`);
            if (i !== ref) {
              this.$refs[`PrimaryContact${i}`][0].errors = [];
            }
          }
        },
    

    【讨论】:

    • 抱歉延迟回来,我用完全不同的方法解决了这个问题,但很高兴知道是否有办法解决这个问题。我试过你的建议,但没有奏效。 codesandbox.io/s/check-box-vee-validate-suggetion1-b1clv
    • @ecasper 您是否在复选框验证提供程序中使用 :ref="PrimaryContact${index}" 而不是 ref="'Primary contact' + item.id" ...?
    • 我的错!我以错误的方式引用它“'主要联系人'+ item.id”。你的建议有效!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    • 2017-05-04
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    相关资源
    最近更新 更多