Why is my *ngIf condition not recognizing the error and displaying the message when the condition is met? - validation

I have a custom validator that I am applying to an input field. My ngIf condition should display an error message if the form value has an error specific to the custom validator. It does not display the message, I cannot figure out why.
In my TS file:
export class ParentFinancialComponent implements OnInit {
// Set selected section value on load time.
selectedSectionGroup = {
sectionOne: false,
sectionTwo: true,
sectionThree: true,
sectionFour: true,
sectionFive: true,
sectionSix: true
};
public financialSectionTwo: FormGroup;
ngOnInit() {
this.initForm();
}
initForm() {
this.financialSectionTwo = this.formBuilder.group({
parents2017AdjustedGrossIncome: ['', [CustomValidators.onlyNumbers]],
parents2017IncomeTaxAmount: ['', [CustomValidators.onlyNumbers]],
parents2017TaxExemption: ['', [CustomValidators.onlyNumbers]]
});
get sectionTwo() { return this.financialSectionTwo.controls; }
}
In my HTML:
<div [hidden]="selectedSectionGroup.sectionTwo" class="tab-pane
fade show active"
id="{{financialSectionEnum.SECTION_TWO}}" role="tabpanel">
<form [formGroup]="financialSectionTwo">
<p class="section-header">Section II</p>
<div class="form-group row"
[hidden]="sectionOne.parentsIrsStatus.value === '3'">
<p class="col-lg-9"><b class="q-num">89)</b><span
[hidden]="sectionOne.parentsIrsStatus.value !== '1'"
class="form-required">*</span>Income for 2017?<i
class="fa fa-info-circle" aria-hidden="true"></i></p>
<div class="col-lg-3">
<label class="sr-only">Adjusted gross
income</label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">$</div>
</div>
<input
maxlength="9"
formControlName="parents2017AdjustedGrossIncome"
id="parents2017AdjustedGrossIncome"
type="text"
class="form-control col-3 col-lg-12"
data-hint="yes"
>
<div class="input-group-append">
<div class="input-group-text">.00</div>
</div>
<div
*ngIf="sectionTwo.parents2017AdjustedGrossIncome.touched &&
sectionTwo.parents2017AdjustedGrossIncome.errors.onlyNumbers"
class="alert text-danger m-0 p-0 col-md-12"
>
Enter an amount
</div>
</div>
</div>
If i enter an alphabet, I should get the error message "Enter an amount". I have other inputs that depend on multiple custom validators, so checking to see if the input field is just "invalid" will help me. I need the message to display only if a specific custom validator is triggered.

You didn't include the implementation for your custom validator: CustomValidators.onlyNumbers so can't say what is wrong with the logic... however, the following implementation could get what you wanted !!
validator:
CustomValidatorsOnlyNumbers(control: AbstractControl) {
var pattern = /^\d+$/;
if ( pattern.test(control.value) == true ){ return true;} else {
return { onlyNumbers: true };
}
}
relevant HTML:
<div class="tab-pane fade show active"
role="tabpanel">
<form [formGroup]="financialSectionTwo">
<p class="section-header">Section II</p>
<div class="form-group row" >
<p class="col-lg-9"><b class="q-num">89)</b><span
class="form-required">*</span>Income for 2017?<i
class="fa fa-info-circle" aria-hidden="true"></i></p>
<div class="col-lg-3">
<label class="sr-only">Adjusted gross
income</label>
<div class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">$</div>
</div>
<input
maxlength="9"
formControlName="parents2017AdjustedGrossIncome"
type="text"
class="form-control col-3 col-lg-12"
data-hint="yes"
>
<div class="input-group-append">
<div class="input-group-text">.00</div>
</div>
<div
*ngIf="financialSectionTwo.get('parents2017AdjustedGrossIncome').touched && financialSectionTwo.get('parents2017AdjustedGrossIncome').hasError('onlyNumbers')"
class="alert text-danger m-0 p-0 col-md-12"
>
Enter an amount
</div>
</div>
</div>
</div>
</form>
</div>
complete working stackblitz here

Related

how to scroll to first validation error message in livewire laravel

I am new in livewire. i am working on registration process of user. Register form is quite big and validations also working fine to me. The problem is when user submits the form validations came but user not able to see because submit button is at bottom and form is at top.
When i manually scroll to top error message is displaying. So what i want when user submits the form its will automatically go to first error message. Here is my code:
<form wire:submit.prevent="userRegister">
<div class="row">
<div class="col-md-3">
<label>First Name *</label>
</div>
<div class="col-md-9">
<input type="text" wire:model="register.first_name" placeholder="Enter First Name" required>
#error('register.first_name') <span class="text-danger">{{ $message }}</span> #enderror
</div>
</div>
<div class="row">
<div class="col-md-3">
<label>Last Name *</label>
</div>
<div class="col-md-9">
<input type="text" wire:model="register.last_name" placeholder="Enter Last Name">
#error('register.last_name') <span class="text-danger">{{ $message }}</span> #enderror
</div>
</div>
<div class="row">
<div class="col-md-3">
<label>Test 1 Name *</label>
</div>
<div class="col-md-9">
<input type="text" wire:model="register.test1_name" placeholder="Enter Last Name">
</div>
</div>
<div class="row">
<div class="col-md-3">
<label>Test 2 Name *</label>
</div>
<div class="col-md-9">
<input type="text" wire:model="register.test2_name" placeholder="Enter Last Name">
</div>
</div>
<div class="row">
<div class="col-md-3">
<label>Test 3 Name *</label>
</div>
<div class="col-md-9">
<input type="text" wire:model="register.test3_name" placeholder="Enter Last Name">
</div>
</div>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-9">
<!--<input type="submit" value="Edit" class="edt-sb">-->
<input wire:click="userRegister" type="submit" value="Submit" class="edt-sv">
</div>
</div>
</form>
My Register.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Register extends Component
{
public $register;
protected $rules = [
'register.first_name' => 'bail|required|max:50',
'register.last_name' => 'bail|required|max:50',
];
protected $messages = [
'register.first_name.required' => 'Please enter first name',
];
public function userRegister(){
$this->validate();
}
I want when user submits the form it will immediately scroll to first error message. Currently my validations work perfects for me. Do i need to use alpine js? for this.
Livewire errors will be saved in $errors bag so probably you can add an id to each field in your form and use alpinejs to focus the first element with the id present in the errors bag, something like:
<div x-data="{
'errors': {{ json_encode(array_keys($errors->getMessages())) }},
focusField(input) {
fieldError = document.getElementById(input);
if (fieldError) {
fieldError.focus({preventScroll:false});
}
},
}"
x-init="() => { $watch('errors', value => focusField(value[0])) }">
<input id="register.test3_name" type="text" wire:model="register.test3_name" placeholder="Enter Last Name">
</div>
I nearly faced the same issue but with success message not error messages, for error messages I used updated(), they are shown on real time for user while filling the fields.
My Class Component :
class FormSubmissions extends Component
{
public $city;
public $fullname;
protected $rules = [
'city' => 'required',
'fullname' => 'required',
];
public $successMessage;
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
public function submitForm()
{
$submission = $this->validate();
$this->successMessage = trans('site.success');
$this->resetForm();
}
public function resetForm()
{
$this->city = '';
$this->fullname = '';
}
}
My Blade template :
<div id="formSection" class="form-wrapper">
#if ($successMessage)
<div class="alert alert-success alert-dismissible fade show" role="alert">
{{ $successMessage }}
<button wire:click="$set('successMessage', null)" type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<script>
var elmnt = document.getElementById("formSection");
elmnt.scrollIntoView();
</script>
#endif
<form wire:submit.prevent="submitForm" action="/" method="POST">
...
</div>
So the small script added with success message allowed me to scroll back to top of my form Section #formSection.
If you are using <x-jet-input-error/> component for displaying errors, you can just modify resources/views/vendor/jetstream/components/input-error.blade.php (make sure you have published livewire views) file to below code:
#props(['for'])
<span x-data="{hasError: '{{$errors->get($for)[0] ?? ''}}' }"
x-init="()=> { $watch('hasError', (value)=> {
let errorDiv = document.getElementsByClassName('invalid-feedback')[0];
if(errorDiv){
errorDiv.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'nearest'});
}
})}">
#error($for)
<span {{ $attributes->merge(['class' => 'invalid-feedback d-block']) }} role="alert" style="font-size: inherit">
<strong>{{ $message }}</strong>
</span>
#enderror
</span>
Explanation : we use alpine to watch for changes in the validation message for the "$for" field. As soon as it changes (validation message shows up or vanishes), it looks for the error block and scrolls to it

Cannot get value from summernote ,when using ajax update

when i click edit button (i used modal bootstrap) all value exist except textarea with summernote.
if you input something(in summernote) and cancel it ,your value doesn't disappear ... it should be clear .
forgive me, my english so bad .
here is my modal form :
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" ><span aria-hidden="true">×</span></button>
<h3 class="modal-title">Formulir Berita</h3>
</div>
<div class="modal-body form">
<form action="#" id="form" class="form-horizontal">
<input type="hidden" value="" name="id_berita"/>
<div class="form-body">
<div class="form-group">
<label class="control-label col-md-2">Tanggal penulisan</label>
<div class="col-md-9">
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-calendar"></i>
</span>
<input name="tgl" placeholder="yyyy-mm-dd" class="form-control datepicker" type="text">
<span class="help-block"></span>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Judul</label>
<div class="col-md-9">
<input name="judul" placeholder="Judul" class="form-control" type="text">
<span class="help-block"></span>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Penulis</label>
<div class="col-md-9">
<input name="penulis" placeholder="Penulis" class="form-control" type="text">
<span class="help-block"></span>
</div>
</div>
<div class="form-group" id="photo-preview">
<label class="control-label col-md-2">Gambar</label>
<div class="col-md-4">
(Tidak ada gambar)
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2" id="label-photo">Unggah Foto </label>
<div class="col-md-7">
<div class="fileupload fileupload-new" data-provides="fileupload">
<div class="input-append">
<div class="uneditable-input">
<i class="fa fa-file fileupload-exists"></i>
<span class="fileupload-preview"></span>
</div>
<span class="btn btn-default btn-file">
<span class="fileupload-exists">Ganti Foto</span>
<span class="fileupload-new">Pilih File</span>
<input name="gambar" type="file" />
</span>
<span class="help-block"></span>
Remove
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Isi</label>
<div class="col-md-9">
<textarea name="isi" class="form-control" id="summernote" >
</textarea>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" id="btnSave" onclick="save()" class="btn btn-primary">Simpan</button>
<button type="button" class="btn btn-danger" data-dismiss="modal">Batal</button>
</div>
</div>
</div>
</div>
i 've been trying some code :
$('#summernote').summernote('code');
$('#summernote').summernote('reset');// and for resetting modal while Add Data
it doesn't happen anything
my ajax function :
function edit_berita(id)
{
save_method = 'update';
$('#form')[0].reset(); // reset form on modals
$('.form-group').removeClass('has-error'); // clear error class
$('.help-block').empty(); // clear error string
//Ajax Load data from ajax
$.ajax({
url : "<?php echo site_url('sistem/berita/ajax_edit/')?>/" + id,
type: "GET",
dataType: "JSON",
success: function(data){
// $('#summernote').summernote('code');
$('[name="id_berita"]').val(data.id_berita);
$('[name="tgl"]').datepicker('update',data.tgl);
$('[name="judul"]').val(data.judul);
$('[name="isi"]').val(data.isi);
$('[name="penulis"]').val(data.penulis);
$('#modal_form').modal('show'); // show bootstrap modal when complete loaded
$('.modal-title').text('Edit data'); // Set title to Bootstrap modal title
$('#photo-preview').show(); // show photo preview modal
if(data.gambar)
{
$('#label-photo').text(''); // label photo upload
$('#photo-preview div').html('<img src="'+base_url+'upload/berita/'+data.gambar+'" class="img-responsive" >'); // show photo
$('#photo-preview div').append('<input type="checkbox" name="remove_photo" value="'+data.gambar+'"/> Remove photo when saving'); // remove photo
}
else
{
$('#label-photo').text(''); // label photo upload
$('#photo-preview div').text('(Tidak ada gambar)');
}
},
error: function (jqXHR, textStatus, errorThrown)
{
alert('Error get data from ajax');
}
});
}
Text Area doesnot have value. jQuery .html() works in this case
$("textarea#summernote").html(data.isi);
Try to modify the summernote line like this :
$('#summernote').summernote('code', data.isi);
And to clear the content :
$('#summernote').summernote('code', '');
Please try this:
$("textarea#summernote").val(data.isi);
$( '[name="isi"]' ).val(data.isi);
$( '[name="isi"]' ).summernote();

How to set if else statement in script

-I wan't to do like this: if(!editMode) show create page else show update page because my create and edit using same form so I combine it.
-I'm learning online tutorial but the tutorial show create and edit seperately.
-Please Helps and Thank/.\
<template>
<div v-if="!edit">
<h1>Create Post</h1>
<form #submit.prevent="addPost">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Post Title:</label>
<input type="text" class="form-control" v-model="post.title">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Post Body:</label>
<textarea class="form-control" v-model="post.body" rows="5"></textarea>
</div>
</div>
</div><br />
<div class="form-group">
<button class="btn btn-primary">Create</button>
</div>
</form>
</div>
<div v-else>
<h1>Update Post</h1>
<form #submit.prevent="updatePost">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Post Title:</label>
<input type="text" class="form-control" v-model="post.title">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Post Body:</label>
<textarea class="form-control" v-model="post.body" rows="5"></textarea>
</div>
</div>
</div><br />
<div class="form-group">
<button class="btn btn-primary">Update</button>
</div>
</form>
</div>
</template>
<script>
export default {
data(){
return {
edit:false,
post:{}
}
},
},
//this is for create
methods: {
addPost(){
let uri = 'http://localhost:8000/post/create';
this.axios.post(uri, this.post).then((response) => {
this.$router.push({name: 'posts'});
});
},
},
//this is for get data before update
created() {
let uri = `http://localhost:8000/post/edit/${this.$route.params.id}`;
this.axios.get(uri).then((response) => {
this.post = response.data;
});
},
//this is for update post
updatePost() {
let uri = `http://localhost:8000/post/update/${this.$route.params.id}`;
this.axios.post(uri, this.post).then((response) => {
this.$router.push({name: 'posts'});
});
}
</script>
**I also set this in my app.js**
{
name: 'create',
path: '/create',
component: PostForm,
props: {editMode: false}
},
{
name: 'edit',
path: '/edit/:id',
component: PostForm,
props: {editMode: true}
}
My Error--->when I press edit btn show create page and using addPost function.
Result--> how to use if else to solve this.... Sorry I'm rookie in programming.
I believe you can simply have the js figure out the add or update.
<template>
<div>
<h1 v-if="!edit">Create Post</h1>
<h1 v-else>Update Post</h1>
<form #submit.prevent="postSomething">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Post Title:</label>
<input type="text" class="form-control" v-model="post.title">
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>Post Body:</label>
<textarea class="form-control" v-model="post.body" rows="5"></textarea>
</div>
</div>
</div><br />
<div class="form-group">
<button v-if="!edit" class="btn btn-primary">Create</button>
<button v-else class="btn btn-primary">Update</button>
</div>
</form>
</div>
</template>
and the js:
methods: {
postSomething(){
if(!this.edit){
this.addPost()
}else{
this.updatePost()
}
},
addPost(){
console.log('should add')
},
updatePost(){
console.log('should update')
}
}

close parent modal and open child modal on axios success response with laravel vue js

User have to register through two steps. both steps have modal to fill details. for that i have two component ComponentA for first modal and componentB for second modal. Iwant to close first modal on axios success response and open second modal for second registration step.
<template>
<!--sction user-signup 1-->
<div class="signup">
<div class="modal" id="user-signup-1">
<div class="modal-dialog">
<div class="modal-content">
<button type="button" class="close" data-dismiss="modal">×</button>
<!-- Modal body -->
<div class="modal-body text-center" style="background:url(images/user-signup-bg.jpg) no-repeat left top; ">
<h2>SIGN UP</h2>
<h5 class="setp-tag">Step 1 of 2</h5>
<h6>Registered users have access to all MoneyBoy features. This is not a Moneyboy Profile.<br>
If you’d like to create a Moneyboy Profile please click here.</h6>
<form class="user-signup-form" action="./api/user/signup" method="POSt" #submit.prevent="addUser()">
<div class="form-group">
<label>Username</label>
<input type="text" name="username" v-model="username" placeholder="mohamed-ali" class="span3 form-control">
<span v-if="hidespan">5 - 20 characters. Letters A-Z and numbers 0-9 only. No spaces.
E.g. MikeMuscleNYC.</span>
<span v-if="errorinusername"> {{ errorinusername }}</span>
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" v-model="email" placeholder="mohamed-ali#gmail.com" class="span3 form-control">
<span v-if="errorinemail"> {{ errorinemail }}</span>
</div>
<div class="form-group">
<label>Create a password</label>
<input type="password" name="password" v-model="password" placeholder="**********" class="span3 form-control">
<span v-if="errorinusername"> {{ errorinpassword}}</span>
</div>
<div class="form-group turms">
<input name="" type="checkbox" value="1" v-model="checked" id="terms"><label for="terms">I am over 18 and agree to the
Terms & Conditions</label>
<!--<label><input type="checkbox" name="terms">I am over 18 and agree to the Terms & Conditions.</label>-->
<input type="submit" :disabled="!checked" value="SIGN UP NOW" class="btn btn-primary w-100">
</div>
<div class="form-group">
<p>If you’d like to create a Moneyboy Profile click here.</p>
</div>
<div class="clearfix"></div>
</form>
</div>
</div>
</div>
</div>
<usersignup2component #recordadded="openusersignup2modal()"></usersignup2component>
</div>
<!--sction user-signup 1-->
</template>
<!--sript -->
<script>
Vue.component('usersignup2component', require('./UserSignup2Component.vue').default);
export default {
data(){
return {
username: '',
email:'',
password:'',
checked: false,
errorinusername: '',
errorinemail: '',
errorinpassword: '',
hidespan: true,
}
},
methods:{
addUser(){
axios.post('./api/user/signup', {
username:this.username,
email:this.email,
password:this.password
})
.then((response) =>{
this.$emit('recordadded');
})
.catch((error) => {
console.log(error.response);
this.hidespan = false;
this.errorinusername = error.response.data.errors.username;
this.errorinemail = error.response.data.errors.email;
this.errorinpassword = error.response.data.errors.password;
});
},
openusersignup2modal(){
console.log('okkkkkkkkkkkkkk');
}
},
mounted() {
console.log('UserSignUp1Component mounted.')
}
}
</script>
What I am doing wrong. I tried to console.log() on openusersignup2modal method to see, if it this function ever called or not. Found no activity on openusersignup2modal()

vee-validate: Required only if a condition is met

I'm using Vuejs2 and vee-validate for form validation. It's a great package, however I'm struggling to implement a conditional required field.
When a particular radio option is selected, I want two select fields to be required. And when that radio is not selected, I want the two select fields to be optional.
I've tried using the attach and detach methods. I can successfully detach the validation. And I can see when I attach a field it appears in the fields object. But it's not picked up by the validator.
Here is my code:
<template>
<form class="ui form" role="form" method="POST" action="/activate" v-on:submit.prevent="onSubmit" :class="{ 'error': errors.any() }">
<div class="ui segment">
<h4 class="ui header">Basic Company Information</h4>
<div class="ui message">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
<div class="field" :class="{ 'error': errors.has('name') }">
<div class="ui labeled input">
<label class="ui label" for="name">
Company
</label>
<input id="name" type="text" name="name" v-validate="'required'" v-model="name">
</div>
</div>
<div class="ui error message" v-show="errors.has('name')">
<p>{{ errors.first('name') }}</p>
</div>
<div class="grouped fields" :class="{ 'error': errors.has('organisation_type_id') }">
<label for="organisation_type_id">Organisation type</label>
<div class="field">
<div class="ui radio checkbox">
<input class="hidden" type="radio" name="organisation_type_id" value="1" data-vv-as="organisation type" v-validate="'required'" v-model="organisation_type">
<label>Buyer</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input class="hidden" type="radio" name="organisation_type_id" value="2" checked>
<label>Seller</label>
</div>
</div>
</div>
<div class="ui error message" v-show="errors.has('organisation_type_id')">
<p>{{ errors.first('organisation_type_id') }}</p>
</div>
<div v-show="organisation_type == '2'">
<div class="field" :class="{ 'error': errors.has('countries[]') }">
<label for="countries">Countries</label>
<select class="ui fluid search dropdown" id="countries" name="countries[]" multiple data-vv-as="countries" v-validate="'required'">
<option v-for="country in countries" :value="country.value">{{ country.text }}</option>
</select>
</div>
<div class="ui error message" v-show="errors.has('countries[]')">
<p>{{ errors.first('countries[]') }}</p>
</div>
<div class="ui message field-description">
<p>Select all the countries you export to.</p>
</div>
<div class="field" :class="{ 'error': errors.has('ciphers[]') }">
<label for="ciphers">Ciphers</label>
<select class="ui fluid search dropdown" id="ciphers" name="ciphers[]" multiple data-vv-as="ciphers" v-validate="'required'">
<option v-for="cipher in ciphers" :value="cipher.value">{{ cipher.text }}</option>
</select>
</div>
<div class="ui error message" v-show="errors.has('ciphers[]')">
<p>{{ errors.first('ciphers[]') }}</p>
</div>
<div class="ui message field-description">
<p>Select all the ciphers you support.</p>
</div>
</div> <!-- End organisation_type_id -->
<button class="ui fluid green button" type="submit">Continue</button>
</div> <!-- .ui.segment -->
</form>
</template>
<script>
export default {
props: ['countriesJson', 'ciphersJson'],
data() {
return {
name: null,
organisation_type: '2',
countries: [],
ciphers: [],
}
},
watch: {
organisation_type: function(value) {
var vm = this
if (value == '2') {
vm.$validator.attach('countries[]', 'required');
const select = document.getElementById('countries');
select.addEventListener('change', function() {
vm.$validator.validate('required', this.value);
});
vm.$validator.attach('ciphers[]', 'required');
const select = document.getElementById('ciphers');
select.addEventListener('change', function() {
vm.$validator.validate('required', this.value);
});
} else {
vm.$validator.detach('countries[]')
vm.$validator.detach('ciphers[]')
}
},
},
mounted() {
this.countries = JSON.parse(this.countriesJson)
this.ciphers = JSON.parse(this.ciphersJson)
},
methods: {
onSubmit: function(e) {
this.$validator.validateAll().then(success => {
e.target.submit()
}).catch(() => {
return
})
}
}
}
</script>
May be you mean something like this?
<input id="name"
type="text"
name="name"
v-validate="{ required: this.isRequired }"
v-model="name">
Where "isRequired" is computed field, which depend from condition
<input id="name"
type="text"
name="name"
v-validate=" isRequired ? 'required' : '' "
v-model="name">
In my case it worked by giving above condition.. Also it is helpful in case of multiple validation rules... e.g. 'required|integer|between:18,99'..
Adding {} will break the expression
you can simply use
v-validate="`required_if:${condition}`"

Resources