I need to valid files type programmatically and next do something:
<template>
<ValidationObserver
ref="form"
tag="form"
type="form"
autocomplete="off"
#submit.prevent="submit()"
>
<div class="box-body">
<div class="row">
<div class="col-lg-8 col-md-6 col-xs-12">
<ValidationProvider
v-slot="{ errors, validate }"
rules="ext:csr"
ref="csr"
:name="$t('central_system.administration.ssl_certifications.csr').toLowerCase()"
>
<div
class="form-group"
:class="{'has-error': errors.length}"
>
<label for="csr">{{ $t('central_system.administration.ssl_certifications.csr') }}</label>
<input
id="csr"
required
type="file"
#change="validate"
#blur="getCsrInfo($event,'csr')"
>
<FormErrorSpan :errors="errors" />
</div>
</ValidationProvider>
.
.
.
<script>
import { ValidationObserver, ValidationProvider, extend } from 'vee-validate'
import { required, confirmed, integer, ext } from 'vee-validate/dist/rules'
import FormErrorSpan from '#/components/Base/templates/forms/FormErrorSpan'
.
.
.
methods: {
async getCsrInfo(event, certyficateItem) {
//UNFORTUNATELLY THIS ALWAYS RETURN TRUE
console.log(await this.$refs.csr.validate())
SSLCertificatesAPI
.getCsrInfo(event.target.files[0])
.then(data => {
this.previewFn(data.data.info)
this.getFileContent(event, certyficateItem)
})
},
.
.
.
As I understand await this.$refs.csr.validate() should return me false, then the file has the wrong extension. but unfortunately, it's always true.
I tried to call validate and getCsrInfo($event,'csr') in one #change, but validation wasn't working then too.
I got it!I found that validate metod in #input work perfectly here.
<ValidationProvider
v-slot="{ errors, validate }"
rules="ext:csr"
ref="csr"
:name="$t('central_system.administration.ssl_certifications.csr').toLowerCase()"
>
<div
class="form-group"
:class="{'has-error': errors.length}"
>
<label for="csr">{{ $t('central_system.administration.ssl_certifications.csr') }}</label>
<input
id="csr"
required
type="file"
//THATS WORK
#input="validate"
#change="getCsrInfo($event,'csr')"
>
<FormErrorSpan :errors="errors" />
</div>
</ValidationProvider>
Related
I added Vue Stripe on my vue2 Project and I have 2 similar errors on my code :
Property 'redirectToCheckout' does not exist on type 'Vue | Element | (Vue | Element)[]'.
Property 'publishableKey' does not exist on type 'CombinedVueInstance<Vue, unknown, unknown, unknown, Readonly<Record<never, any>>>'.
I followed the documentation on their website and everything is similar as their code so I don't know why I have those errors.
Screenshots
Here is my code if you want to check
<template >
<div class="section form-degustation-section" style="padding-top:150px">
<div class="mycontain form-degustation-contain" >
retrouner aux calendrier des soirées
<div class="soiree-text-presentation-contain">
<h1>{{ degustation[0].title }}</h1>
<p>{{ degustation[0].description }}</p>
</div>
<div class="soiree-form-contain">
<h2>Formulaire de réservation</h2>
<div class="w-form">
<div id="wf-form-soirees-degustation" name="wf-form-soirees-degustation" data-name="soirees degustation" action="https://natureetvins.foxycart.com/cart" method="post">
<label for="name">Nom et prénom</label>
<input type="text" class="w-input" maxlength="256" name="name" data-name="Name" placeholder="Ecrivez votre nom et prénom" id="name" data-kwimpalastatus="alive" data-kwimpalaid="1626170679038-0">
<label for="email">Email Address</label>
<input type="email" class="w-input" maxlength="256" name="email" data-name="Email" placeholder="Ecrivez votre adresse email" id="email" required="" data-kwimpalastatus="alive" data-kwimpalaid="1626170679038-1">
<label for="email-2">Téléphone</label>
<input type="text" class="w-input" maxlength="256" name="field" data-name="Field" placeholder="Ecrivez votre numéro de téléphone" id="field" required="" data-kwimpalastatus="alive" data-kwimpalaid="1626170679038-2">
<label for="quantity" >Quantité</label>
<input v-model="lineItems[0].quantity" type="number" class="w-input" maxlength="256" placeholder="Combien de places voulez vous acheter ?" required="">
<div class="w-embed">
<input type="hidden" name="name" value="Name">
<input type="hidden" name="prix" value="Prix">
<input type="hidden" name="image" value="Image">
</div>
<div class="event-cta-contain">
<div>
<stripe-checkout
ref="checkoutRef"
mode="payment"
:pk="publishableKey"
:line-items="lineItems"
:success-url="successURL"
:cancel-url="cancelURL"
/>
<button #click="submit()" class="cta-button w-button">Payer</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { StripeCheckout } from "#vue-stripe/vue-stripe";
import axios from "axios";
import Vue from 'vue';
export default Vue.extend({
components: {
StripeCheckout,
},
data() {
this.publishableKey = "pk_test_51JAWNYJ3Er0D2qeQ9y9P0RXOsZPfxGC9VVour44gRX2NNiP2CBAzV0NECWsupE5WZhybNBT8TX5TDG5XUOHxg8rg00rMplGIhK";
return {
degustation: [{
}],
id_product: this.$route.params.id as string,
loading: false,
lineItems:[
{
price: "price_1JChqzJ3Er0D2qeQ8cZhp2RM",
quantity: 1 ,
}],
successURL: "http://google.fr",
cancelURL: "http://google.fr",
};
},
mounted() {
axios
.get(`http://localhost:3000/api/v1/degustations/${this.id_product}`)
.then((response) => (this.degustation = response.data));
},
methods: {
submit() {
this.$refs.checkoutRef.redirectToCheckout()
},
},
});
</script>
Do I need to import something else or ?
A couple of things are happening here.
First, keep in mind that if you want to access the publishableKey in the template then you should add it in the object that you're returning in the data() function.
Try to do some checking before accessing checkoutRef, try this:
if (this.$refs.checkoutRef) {
this.$refs.checkoutRef.redirectToCheckout()
}
I'm just starting to learn laravel+vue. I was able to follow a tutorial from this yt: https://www.youtube.com/watch?v=JZDmBWRPWlw. Though it seems outdated, I was still able to follow his steps. I'm using the laravel-mix 6.0.6 and vue 2.6.12.
Using inspect element>network, I can see that I'm throwing the correct error message in array.
{"component":"Users\/Create","props":{"app":{"name":"Laravel"},"errors":{"name":"The name field is required.","email":"The email field is required."}},"url":"\/users\/create","version":"207fd484b7c2ceeff7800b8c8a11b3b6"}
But somehow it is not displaying the complete error message. Right now it just show the first letter of the sentence. LOL. Sample error message is: The email field is required and it will just display the letter "T". Below is my Create.vue. Basically it is just a user create form with simple validation.
Create.vue
<template>
<layout>
<div class="container">
<div class="col-md-6">
<div v-if="Object.keys(errors).length > 0" class="alert alert-danger mt-4">
{{ errors[Object.keys(errors)[0]][0] }}
</div>
<form action="/users" method="POST" class="my-5" #submit.prevent="createUser">
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" id="name" placeholder="Name" v-model="form.name">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="text" class="form-control" id="email" placeholder="Email" v-model="form.email">
</div>
<div class="form-group">
<label for="name">Password</label>
<input type="password" class="form-control" id="password" placeholder="Password" v-model="form.password">
</div>
<button type="submit" class="btn btn-primary">Create User</button>
</form>
</div>
</div>
</layout>
</template>
<script>
import Layout from '../../Shared/Layout'
export default {
props: ['errors'],
components: {
Layout,
},
data() {
return {
form: {
name: '',
email: '',
password: '',
}
}
},
methods: {
createUser() {
this.$inertia.post('/users', this.form)
.then(() => {
// code
})
}
}
}
</script>
Edit:
I have this error on my console
[Vue warn]: Error in v-on handler: "TypeError: Cannot read property
'then' of undefined"
found in
---> at resources/js/Pages/Users/Create.vue
Your error call is probably getting only the first letter due to [0]. Try to change to:
{{ errors[Object.keys(errors)[0]] }}
Strings can also be read as arrays. If you do this:
$a = "TEST";
echo $a[0];
That would print only T.
That is probably the problem.
I have this code in my vue template
<div class="form-row" :class="{'was-validated': this.checkPassword()}">
<div class="col-6">
<label>Password</label>
<input :type="showPassword ? 'text' : 'password'" class="form-control" ref="password" required v-model="password">
<div class="valid-feedback" v-if="!error">
Password match
</div>
<div class="invalid-feedback" v-else>
Password not match
</div>
</div>
<div class="col-6">
<label>Confirm password</label>
<div class="input-group">
<input :type="showPassword ? 'text' : 'password'" class="form-control" ref="passwordCheck" required v-model="passwordCheck" #change="checkPassword()">
<div class="input-group-append">
<button class="btn btn-secondary" #click.prevent="copyToClipboard()"><i class="fas fa-clipboard"></i></button>
</div>
</div>
</div>
</div>
I want to show like the bootstrap4 documentation a green input field if the password matches or a red one if the password aren't matching. I'm trying by adding the was-validated class to the form-row if the demanded method return true but when the view where the password inputs are rendered the two input fields are always red. How I can fix this to give the correct feedback to the user?
Please always share all the relevant parts of the component otherwise, it's hard to tell where the problem resides. Here, you haven't shared your <script> section. Anyway, I guess this should put you on the right track.
<template>
<div class="form-row" :class="{'was-validated': this.checkPassword()}">
<div class="col-6">
<label>Password</label>
<label>
<input :type="showPassword ? 'text' : 'password'" class="form-control" :class="getPasswordClass()"
ref="password" required v-model="password">
</label>
</div>
<div class="col-6">
<label>Confirm password</label>
<div class="input-group">
<label>
<input :type="showPassword ? 'text' : 'password'" class="form-control" :class="getPasswordClass()"
ref="passwordCheck" required v-model="passwordCheck" #input="checkPassword()">
</label>
<div class="input-group-append">
<button class="btn btn-secondary" #click.prevent="copyToClipboard()"><i
class="fas fa-clipboard"></i></button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
password: null,
passwordCheck: null,
error: true,
showPassword: true,
}
},
methods: {
checkPassword() {
this.error = this.password !== this.passwordCheck;
},
getPasswordClass() {
if (!this.password || !this.passwordCheck) {
return '';
}
return this.error ? 'is-invalid' : 'is-valid'
},
copyToClipboard() {
//
}
}
}
</script>
So, in my opinion, you should only set the dynamic class (is-valid or is-invalid) when both inputs are provided. In this example I've added that to both password and passwordCheck fields but I think it's enough to just apply it to the passwordCheck because that's the one checked against the password.
If you only want to check after user leaves the field you could adjust the code like this:
In the template remove:
:class="{'was-validated': this.checkPassword()}"
And update:
#blur="checkPassword()
In the data() add:
blurred: false,
In the methods update:
methods: {
checkPassword() {
this.blurred = true;
this.error = this.password !== this.passwordCheck;
},
getPasswordClass() {
if (!this.blurred) {
return '';
}
return this.error ? 'is-invalid' : 'is-valid'
},
...
}
I using Vue3.0 and also use Vee-validate to validate my form. But I don't know why it keep showing blank page just like in this picture
I already do what they said in the documentations, here's my code
<form class="wrap" id="signup-form col-lg-5" #submit.prevent="processForm">
<div class="row mb-5">
<router-link :to="{'name': 'Home'}">
<span class="iconify" data-icon="ion:return-up-back-outline" data-width="25" data-height="25"></span>
<button class="btn">Back</button>
</router-link>
</div>
<!-- full name -->
<div class="form-group row">
<label for="name">Full Name <span class="text-danger">*</span></label>
<ValidationProvider rules="positive|odd" v-slot="err">
<input type="text" class="form-control" v-model.trim="name">
<span>{{ err.errors[0] }}</span>
</ValidationProvider>
</div>
<!-- submit button -->
<div class="row d-flex align-items-center">
<button type="submit" class="btn btn-outline-dark col-sm-4">Submit</button>
<p style="cursor:pointer;" class="col-sm-7">
<router-link :to="{name:'Login'}">Has an account? Login</router-link>
</p>
</div>
</form>
And here's my script
<script>
import { ValidationProvider } from 'vee-validate';
import { extend } from 'vee-validate';
extend('odd', value => {
return value % 2 !== 0;
});
extend('positive', value => {
return value >= 0;
});
export default {
name: 'RegisterForm',
components: {
ValidationProvider
},
data: function(){
return{
name: '',
}
},
methods: {
processForm() {
this.$emit('form-submit',
{
'name': this.email,
'password': this.password,
})
}
}
}
</script>
What should I change from the code? By the way, Is Vee-Validator should be assigned in main.js?
Looks like you are using vee-validate v3.x, it isn't compatible with Vue 3
vee-validate v4 was released recently that supports Vue 3, but with a completely different API
https://vee-validate.logaretm.com/v4/
In my vue 2.5.17 app I have a select input and text input and I have a create a validation rule that only 1 of them musdt be filled :
<div class="form-row p-3">
<label for="existing_user_list_id" class="col-12 col-sm-4 col-form-label">Select already existing list</label>
<div class="col-12 col-sm-8">
<v-select
v-model="selection_existing_user_list_id"
data-vv-name="selection_existing_user_list_id"
:options="userListsByUserIdArray"
v-validate="''"
id="existing_user_list_id"
name="existing_user_list_id"
class="form-control editable_field"
placeholder="Select existing user list"
v-on:input="onChangeSelectionExistingUserListId($event);"
></v-select>
<span v-show="vueErrorsList.has('existing_user_list_id')" class="text-danger">{{ vueErrorsList.first('existing_user_list_id') }}</span>
</div>
</div>
<div class="form-row p-1 m-1 ml-4">
<strong>OR</strong>
</div>
<div class="form-row p-2`">
<label for="new_user_list_title" class="col-12 col-sm-4 col-form-label">Create a new list</label>
<div class="col-12 col-sm-8">
<input class="form-control" value="" id="new_user_list_title" v-model="new_user_list_title" #change="onChangeBewUserListTitle($event);">
<span v-show="vueErrorsList.has('title')" class="text-danger">{{ vueErrorsList.first('title') }}</span>
</div>
</div>
I found this :
https://baianat.github.io/vee-validate/guide/custom-rules.html#creating-a-custom-rule
But I am confused how to use it in my case. I try :
import { Validator } from 'vee-validate';
Validator.extend('new_user_list_title', {
getMessage: field => 'The ' + field + ' value is not a valid new_user_list_title.',
validate: value => false // for simplicity I try to raise error always
// validate: value => value.length == 0 && selection_existing_user_list_id == null
})
But my custom error is never triggered, even when I set always false,
Which is right way ?
Thanks!
After adding custom rule, you need to use it in component (in v-validate):
<input
class="form-control"
id="new_user_list_title"
v-model="new_user_list_title"
#change="onChangeBewUserListTitle($event);"
v-validate="'new_user_list_title'">