Field not required but if user entered a value it must be meeting some rules (vuetify rules) - vuejs2

I am trying to enter a validation for a field that accept url, the field not required but if user entered a value it must meet url regex.
so I tried the following code
<v-text-field height="34px" v-model="website" single-line outline placeholder="http://" :rules="urlRules"></v-text-field>
this attribute :rules="urlRules" refer to a bulk of rules that I give in my vue object
urlRules: [
v => !!v || 'required',
v => /[-a-zA-Z0-9#:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9#:%_\+.~#?&//=]*)?/gi.test(v) || 'Please enter a correct URL to your website'
],
I want to change the validation in the rule object to make it not required but if user entered a url it must be correct

This is how I manage to validate non required fields with Vuetify:
urlRules: [
(v) => ( !v || YOUR_REGEX.test(v) ) || 'Please enter a correct URL to your website'
],
Check the !v. I am validating first, that if nothing is passed, will trigger a true value, this means, will not be required. But if something is passed, will check your regex or whatever expression you want to place.
There are other options, like an if else inside the rules, but i prefer this (prettier).

You can do it like below
urlRules: [
v => (v && v.length > 0 && !YOUR_REGEXP.test(v)) ? 'Please enter a correct URL to your website' : true
],

I solved this by maintaining separate validation functions as follows:
export const emailFormat = v =>
/^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(v) ||
"E-mail must be valid";
export const emptyEmailFormat = v => {
if (v && v.length > 0) {
return /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(v) ||
"E-mail must be valid";
} else {
return true
}
}
emailRules = {
isRequired: this.question.mandatory ? required : true,
emailFormat: this.question.mandatory ? emailFormat : emptyEmailFormat
};

I got this idea after posting this question
I used a regex that accept an empty value with the pattern I want
here is what I used
urlRules: [
v => /^$|[-a-zA-Z0-9#:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9#:%_\+.~#?&//=]*)?/gi.test(v) || 'Please enter a correct URL to your website'
],
so if there is a better answer share it with me plz

Related

Show different message on Password validation in Vuetify?

I have passowrd rule like this
passwordRule(value){
const pattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!##\$%\^&\*])(?=.{8,})/;
return (
pattern.test(value) ||
"Min. 8 characters with at least one capital letter, a number and a special character."
);
}
which I am using currently in
<v-text-field
autocomplete="current-password"
:value="userPassword"
label="Enter password"
:append-icon="value ? 'mdi-eye' : 'mdi-eye-off'"
:type="value ? 'password' : 'text'"
:rules="[passwordRule]"
></v-text-field>
as it currently shows "Min. 8 characters with at least one capital letter, a number and a special character." as error message,
How can I achieve like if password doesn't have capital letter it should display only message like "Atleast 1 capital letter". and if password doesn't have a number it should display "a number is required"
Please guide me how can I achieve that?
Your current rule assumes that the password must contain only latin uppercase letters.
If it's OK, use uppercaseEn rule from code below. Otherwise it should be better to use uppercase rule.
<v-text-field
v-model="password"
:rules="[rules.uppercaseEn, rules.special, rules.number, rules.length]"
label="Password"
></v-text-field>
...
data () {
return {
password: '',
rules: {
uppercase: value => {
//For non-latin letters also
return (value && value.toLowerCase() !== value) || 'At least 1 uppercase letter'
},
uppercaseEn: value => {
//For latin letters only
return /[A-Z]/.test(value) || 'At least 1 uppercase letter (A-Z only)'
},
number: value => {
return /\d/.test(value) || 'At least 1 number'
},
special: value => {
return /[!##\$%\^&\*]/.test(value) || 'At least 1 special symbol'
},
length: value => {
return (value && value.length >= 8) || 'Min password length: 8 symbols'
}
},
}
}
Test this at CodePen.

Rules should return a string or boolean, received 'object' instead when using more then one rule

I'm trying to validate a vuetify v-text-field. I have two rules, one for required field and the other for validating thar user only enters positive numbers. But it doesn't work, I get this error:
[Vuetify] Rules should return a string or boolean, received 'object' instead.
This is how I define the rules in vue file:
rules: {
select: [(v) => !!v || "Item is required"],
emailRules: [
v => !!v || 'E-mail is required',
v => /.+#.+\..+/.test(v) || 'E-mail must be valid',
],
phoneRules: [
v => /(\+1)?\s?\(?\d{3}\)?-?\s?\d{3}-\d{4}/.test(v) || 'Phone Number must be valid',
v => v.length <= 15 || 'Phone Number must be valid'
],
numberRules: [
v => /\d+\.?\d*/.test(v) || 'You have to enter a number',
v => v>0 || 'You have to enter a positive number'
]
},
this is the view:
<v-text-field
v-if="loggedUser.role_id == 1"
v-model="editedItem.commission"
label="Commission (%) *"
required
:rules="[rules.select, rules.numberRules]"
></v-text-field>
If I use them separately, they work fine, but if I put them both, neither of them works.
You should concatenate the rules using the spread operator to get an array of rules:
:rules="[...rules.select, ...rules.numberRules]"

Error in vue-simple-suggest when item is selected

In my vue/cli 4 / Bootstrap 4.3 app I make suggestion component(using vue-simple-suggest)
with some additive parameters and returning data I need to get slug
field of selected row and to redirect to other page
based on this slug. Search works ok for me, but when Item in selection list is selected
I see in browsers console one more request to database with whole selected item object and that
raise error.
I make:
<vue-simple-suggest
id="search_string"
v-model="search_string"
display-attribute="name"
value-attribute="slug"
:list="simpleSuggestionList"
autocomplete=off
mode="select"
#select="taskSuggestionSelected()"
></vue-simple-suggest>
and js code:
simpleSuggestionList() {
let filters={
search_string : this.search_string, // search
only_free : ( this.cbx_only_free ? 1 : 0), // additive parameters
price_min : this.tasksPriceRange[0],
price_max : this.tasksPriceRange[1],
selectedCategories : this.getSelectedCategories
}
console.log('filters::')
console.log(filters)
return axios.post(this.apiUrl + '/tasks-search', filters, this.credentialsConfig)
.then(({data}) => {
return data.tasks
})
.catch(error => {
console.error(error)
this.showPopupMessage('Tasks search', error.response.data.message, 'warn')
})
// return this.retArray
},
taskSuggestionSelected() {
console.log('\'taskSuggestionSelected par1 ::\'+par1 +" search_string::"+this.search_string::')
return false
}
1) Why error and how not to trigger request to server when item is selected and
2) how can I save/ pass slug of selected item into taskSuggestionSelected method as I need to make redirection?
"vue": "^2.6.10",
"vue-simple-suggest": "^1.10.1",
Thanks!

Using Vuelidate, how to generate error if what the user inputs already exists in db?

I'm creating a form using Vue JS, more specifically the Vuetify framework.
I've already created a way to show an error when an item doesn't exist, however how can I make it so that it also shows an error if what the user enters already exists in the database?
data: () => ({
aRule: [
v => !! v || 'Please provide project type',
],
}),
My form component looks like this:
<v-text-field
:rules="aRule"
label="Project Type"
v-model="choice.data"
>
</v-text-field>
Please note that 'choice.data' represents the data column in the database
The rule should be like this
emailRules = [
v: => !!v || "email address is required",
v: => /.+#.+\..+/.test(v) || "Please input a valid email",
v: => (v && this.doesUserExist != true) || "Email already exists.",
];
initialize doesUserExist = null;
set this.doesUserExist = true; , when server response user already exist.

How to create correct rule for validating zero via vee-validate

"vee-validate": "^2.2.11",
"vue": "^2.5.16",
I need a simple rule, the rule should be that the input must be required,numeric and greater than 0.
So in this case, if I input 0 it validates correctly(return false), but if I input something like this 0.0 vv returns true. Even if I remove is_not:0, the result still the same.
<sui-input
type="text"
v-validate="'required|decimal|is_not:0'"
name="cellSize"
v-model="cellSize">
You could also create a custom rule, like follows.
created() {
this.$validator.extend(
'greaterThanZero',{
getMessage: field => field + ' needs to be > zero.',
validate: (value) => {
// value must be > zero
if (value > 0 ) return true;
return false;
}
});
},
then call the code on your field instance.
v-validate="'required|decimal|greaterThanZero'"
more on custom rules here:
https://vee-validate.logaretm.com/v2/guide/custom-rules.html#creating-a-custom-rule
or you could also use this following style (if you were going to add more than one rule for example). Here the code would be inserted in the area where you do your imports, i.e. directly after the script tag.
import { Validator } from 'vee-validate';
Validator.extend(
'greaterThanZero',
(value) => {
// value must be > zero
if (value > 0 ) return true;
return false;
}
);
let instance = new Validator({ greaterThanZeroField: 'greaterThanZero' });
you can now add a second rule to the style directly above using the following code:
instance.extend('greaterThan1Million', {
getMessage: field => field +' needs to be > 1,000,000',
validate: value => (value > 1000000 ? true : false)
});
instance.attach({
name: 'greaterThan1MillionField',
rules: 'greaterThan1Million'
});
again that second rule could be called as follows:
v-validate="'required|decimal|greaterThan1Million'"
I found this solution(to leave everything greater than 0)
<sui-input
type="text"
v-validate="{ required: true, regex: /^(?=.*[1-9])\d+(\.\d+)?$/ }"
name="cellSize"
v-model="cellSize">
</sui-input>
Did you try to use a regex to exclude 0 ?
Example:
<input v-validate="{ required: true, regex: /[1-9]*/ }">