Validate the checkbox with Vuelidate only when the specified property is set to true

I have a website login form where users may need to check a specific checkbox before logging in. Here is part of the Vue component code that handles this functionality:

<script setup lang="ts">
    import {ref, defineProps} from 'vue';
    import useVuelidate from '@vuelidate/core';
    import {required, sameAs, email as emailValidation, requiredIf, helpers} from '@vuelidate/validators';
    
    interface Props {
        showAcceptTermsBox: boolean;
    }
    
    const props = defineProps<Props>();
    
    const email = ref('');
    const acceptTerms = ref(false);
    
    const rules = computed(() => ({
        email: {
            required: helpers.withMessage('Please fill out e-mail', required),
            email: helpers.withMessage('Please fill out e-mail correctly', emailValidation)
        },
        acceptTerms: {
            required: helpers.withMessage('Please accept terms and conditions', requiredIf(() => props.showAcceptTermsBox)),
            sameAs: helpers.withMessage('Please accept terms and conditions', sameAs(true))
        }
    }));
    
    const v$ = useVuelidate(rules, {
        email,
        acceptTerms
    }, {
        $scope: false
    });
</script>

<template>
    <form>
        <label for="email">E-mail:</label>
        <input type="email" v-model="email" id="email" />
        <div v-if="showAcceptTermsBox">
            <input type="checkbox" v-model="acceptTerms" id="acceptterms" />
            <label for="acceptterms">Accept</label>
        </div>
        <button type="submit">Submit</button>
    </form>
</template>

The Checkbox will only appear if the showAcceptTermsBox property is set to true. I want the validation to apply only when the checkbox is visible but currently, it gets validated whether the property is true or false. Is there a way to conditionally validate the checkbox using something similar to requiredif with sameAs?

Note that the validation works fine for other fields like the email input. Any guidance on resolving this issue would be greatly appreciated.

Thank you!

Answer №1

If you want, a custom validator can be utilized to always output true whenever showAcceptTermsBox is switched to false. Here's how you can set it up:

acceptTerms: {
  checked: helpers.withMessage(
    "Please accept terms and conditions",
    (value: boolean) => (showAcceptTermsBox ? value : true)
  ),
},

To get a better understanding, have a look at this example (you can switch showAcceptTermsBox in the component's props section).

Answer №2

Just a simple trick is all it takes, check it out below.

import {
  computed,
} from 'vue';

const rules = computed(() => {
  let dynamicRules: any = {
    username: {
      required: helpers.withMessage(
        'Please fill out username',
        required,
      ),
      unique: helpers.withMessage(
        'Username must be unique',
        uniqueValidation,
      ),
    },
  }
  // Add fields dynamically ✅
  if(props.showPasswordReset) {
    dynamicRules = {
      ...dynamicRules,
      passwordReset: {
        required: helpers.withMessage(
          'Please provide password reset information',
          requiredIf(() => props.showPasswordReset),
        ),
        confirmReset: helpers.withMessage(
          'Password reset confirmation needed',
          confirmReset(true),
        ),
      }
    }
  }
  return dynamicRules;
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

WebStorm raises an error saying "SyntaxError: Plugin '@typescript-eslint' failed to load as declared in '.eslintrc.cjs' » '@vue/eslint-config-typescript'."

Encountering an issue in WebStorm where every ts file in the project displays the error message: SyntaxError: Failed to load plugin '@typescript-eslint' declared in '.eslintrc.cjs » @vue/eslint-config-typescript': Unexpected token &a ...

Identify specific elements using CSS to easily target them with JavaScript later on

Currently, I am utilizing CSS selectors to target specific elements and now I want to be able to identify those elements using javascript. My approach involves setting the color of these elements in css and then retrieving them based on their color. Howeve ...

Utilizing the Kraken.com API to create a message signature with AngularJS

I'm currently tackling Angular2 and for my first project, I want to tap into the Kraken.com API. (I know, I could have chosen an easier task :) The "Public" calls are working smoothly, but I've hit a snag with the "Private" methods. (Those requi ...

How can I implement a scroll functionality to navigate to the next item in a Vuetify v-carousel?

I'm currently working on a front page layout using the v-carousel component and I am looking to achieve automatic scrolling to the next item without the need for arrows or delimiters. How can I make this happen? Below is my current code: <template ...

Looking for a demonstration using dust.js or handlebars.js in a two-page format with express3.x and node?

Currently, I am in the process of selecting a templating engine to use. While I have come across numerous single-page examples utilizing template engines, I am specifically searching for a practical example that demonstrates handling two distinct pages whi ...

How to create a basic calculator in AngularJS with two textboxes specifically designed for calculating squares?

My code snippet is as follows: <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script> </head> <body> <div ng-app="app"> <div ng-controller="Calcu ...

Utilizing v-data-iterator in Vuetify to display data fetched from an API in a table

After a long day of searching and experimenting, I've finally arrived here. Initially, I attempted to create a simple table with 2 columns using Row and iterate over the object to populate the left column with its keys. However, I hit a roadblock when ...

Converting an ISO date to a standard JS date: The straightforward approach

Can anyone help me with converting an ISO date to a Standard JS Date format? The specific format I need is: Mon `Jul 20 2020 14:29:52 GMT-0500 (Central Daylight Time)` I would appreciate any guidance on the best approach for achieving this. Thank you in a ...

The MUI multiple select feature is experiencing issues following the addition of a new button

I'm having trouble adding buttons below a select dropdown menu with a specific height. When I try to put the menu item inside a div, the multiple select stops working and I have no idea why. Can someone help me figure this out? Check out my CodeSandb ...

Show picture during the process of loading an external webpage

Utilizing a script to load an external page (external meaning a page within my website) inside a div. Loading the page takes time, so I want to display an image until the page is fully loaded. JAVASCRIPT function HideLoader() { $('#loader' ...

NodeJS JSON file write function not updating as expected

I'm working on a task that involves reading an existing JSON file, updating the value within it, and then saving it back. However, I've encountered the following error message: node:internal/modules/cjs/loader:944 throw err; ^ Error: Cannot ...

The error message received states: "materialize-css Uncaught TypeError: Vel is not defined as

My current setup involves webpack as the bundler/loader, and I've successfully loaded materialize css (js/css). However, when attempting to use the toast feature, an error is thrown: Uncaught TypeError: Vel is not a function The library is being inc ...

What is the best way to apply variables from a SCSS file to functions within a .vue file?

After following the steps provided in this link, I have successfully configured sass for my project. First, I installed sass using npm install -D sass-loader sass. Next, I created a file named variables.scss under the src directory: src/variables.scss $ ...

Changing the color of a Highcharts series bar according to its value

Playing around with Highcharts in this plunker has led me to wonder if it's possible to dynamically set the color of a bar based on its value. In my current setup, I have 5 bars that change values between 0 and 100 at intervals. I'd like the colo ...

Translate a portion of a painting by utilizing context.putImageData()

I am attempting to gradually fill a canvas with pieces of the original image. To achieve this, I need each square of the image to be filled in iteratively on the canvas. To optimize performance, my approach involves rendering the original image onto an of ...

How to implement scrollIntoView in Vue 3 with script setup

Having some trouble with scrolling to a specific element when clicked. I keep getting this error message. Uncaught TypeError: element.scrollIntoView is not a function Here is my script <script setup> import { ref } from 'vue' function goT ...

Tips on implementing computed properties in Vue.js while using TypeScript

There is a significant amount of documentation on how to utilize Vue.js with JavaScript, but very little information on using TypeScript. The question arises: how do you create computed properties in a vue component when working with TypeScript? According ...

Manipulating a prop class from a child component in Vue

I am still in the process of learning Vue and there is something I am struggling with. I have a component called WS.vue that assigns a class to a div (active) when a checkbox is clicked. Currently, the click event works fine and changes the class for each ...

AngularJS animate issue: TypeError - method 'classNameFilter' not found

When I added ngAnimate to my AngularJS app.js file as documented, I encountered a peculiar error: Object [object Object] has no method 'classNameFilter' - angular-animate.js:297 Any idea why this is happening? This is the code snippet where I ...

What is the best way to set up an on-change listener for material-ui's <CustomInput...>?

I'm currently utilizing the React dashboard created by Creative Tim. I have a question regarding how to set up an onChange listener for a Here is the code snippet for the custom input class: import React from "react"; import classNames from "classna ...