I'm building conditional form with vue and stuck on how conditionally validate input field based on the previous users choice. I'll appreciate any help.
in the form I have dropdown menu with payment choices (terminal, payconiq, cash etc).
Second input field is the link user need to add. If user choose terminal, he should add to link input an IP Address. If not - url address.
I receive a paymentId from options with #click, send it to the store and get it from the store with computed property.
The problem is that my vuelidate does not read the condition
const typefromStore = computed(() => paymentStore.paymentType) // here I get typeId from store
const validations = {
description: { required },
type: { required },
link: {
required,
type: typefromStore.value === 1? ipAddress : url // always checks for url and give an error if I need to input IP address
},
}
I read documentation, but I didn't find how to check second input field based on the value of the previous. Only cases when previous field is invalid. But data from dropdown list is always valid.
I need to use the value of 'type' somehow to check conditionally value of link.
Found the solution. May be will help someone. Needed to put validation in computed. No store needed
let newMethod = reactive({
instanceId: 1,
description: '',
type: -1,
link: '',
active: true,
})
const rules = computed(() => {
const localRules = {
description: { required },
type: { required },
link: {},
}
if (newMethod.type === 1) {
localRules.link = {
ipAddress,
}
}
else {
localRules.link = {
url,
}
}
return localRules
})
const v$ = useVuelidate(rules, newMethod, { $autoDirty: true })
Related
I'm new to VueJS. I'm creating signup and login page and users are supposed to send the email and password to the back-end (I'm using Django) to check if the data is valid. I'd like to show error messages on form if one of them are not valid.
I saw some documentation about validation and seems like I have to write a bunch of validation code. Now I'm wondering if there's an easy way to do it.
I'd like to validate them based on the server side's validators.
Login.vue
export default {
data() {
return {
form: {
email: '',
password: '',
}
}
},
methods: {
onSubmit(event) {
event.preventDefault()
// validate the inputs here and shows error messages if they are not valid
const path = `http://127.0.0.1:8000/users/login/`
axios.post(path, this.form).then((resp) => {
location.href = '/'
})
.catch((err) => {
console.log(err)
})
}
}
}
Can anyone give me tips?
Yes, Here is the code you can follow.
In data make a reg object like this.
data(){
return{
email:null,
reg: /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,24}))$/
}
},
add then in your submit method
if(this.email == null || this.email == '')
{
this.errorEmail = "Please Enter Email";
}
else if(!this.reg.test(this.email))
{
this.errorEmail = "Please Enter Correct Email";
}
I am new the Angular but I am trying to understand How can we use Reactive Form and FormGroups array while we use the Service Observable.
My form is very simple, It has list of Articles, where you can select one of them and can edit the detail. It also has feature to add new article.
So, starting of the page itself, It has list of articles in left side and reactive blank form on other side.
Now, this form also contain some of the checkbox which provides the tags for an article.
Now, when I load the page, everything is coming as expected. Articles are coming and reactive form is also loading along with all the tags (un-checked)
When I click any of the article to make that editable, I am getting an error
"Must supply a value for form control at index: 0."
I tried to change the code little but but with that the new error started coming
"Must supply a value for form control with name: 'articleId'"
So, overall I am not getting what is fundamental issue. Seems like I am missing to give a name to the formgroup but not sure how to supply.
// Global Variables: Called from the constructor.
articleDetailForm: FormGroup;
tagFormArray: FormArray = new FormArray([]);
// While this.loadArticle(this.selectedArticleId); called on change event
private loadArticle(selectedArticleID: string) {
this.articleService.getArticle(selectedArticleID)
.subscribe(
(data: ArticleViewModel) => {
const _a = new ArticleViewModel(data);
debugger;
this.articleDetailForm.setValue({
articleBasicDetail: this.setBasicDetailForSelectedArticle(_a),
articleTagDetail: this.setTagDetailForSelectedArticle(_a.ArticleTagViewModels)
})
},
(err) => {
console.log(err);
});
}
private setBasicDetailForSelectedArticle(articleVM: ArticleViewModel) {
return new FormGroup({
articleId: new FormControl(articleVM.articleTitle, ),
articleTitle: new FormControl(articleVM.articleTitle),
articleContent: new FormControl(articleVM.articleContent)
});
}
private setTagDetailForSelectedArticle(articleTagsVM: ArticleTagViewModel[]) {
// want to loop through variable and checked only those tags which are available for this article
return new FormGroup({
tagId: new FormControl(111),
tagName: new FormControl("111"),
isChecked: new FormControl(true)
});
}
private createArticleDetailForm() {
let articleId = 'Dummy ID';
let articleTitle = 'Dummy Title';
let articleContent = 'Dummy Content';
this.articleDetailForm = this.formBuilder.group({
articleBasicDetail: this.formBuilder.group({
articleId: [{ value: articleId, disabled: true }, Validators.required],
articleTitle: [articleTitle, Validators.required],
articleContent: [articleContent, Validators.required],
}),
articleTagDetail: this.tagFormArray
});
}
ERROR Error: Must supply a value for form control with name: 'articleId'.
ERROR Error: "Must supply a value for form control at index: 0."
I have a sails app working with just a simple index and simple create (insert) to a mongo db. When I enter correctly typed data hard coded to be the type stated in the model, I get an error.
url insert err = [Error (E_VALIDATION) 1 attribute is invalid] Invalid attributes sent to urls:
• status
• Value should be a number (instead of "0", which is a string)
This is a very small, new project so not a lot of settings have been changed from default.
Since I have console.log in the create, I can see exactly what I' sending to the urls.create:
{ url: 'http://www.dina.com',
status: 0,
statusDate: '2016-11-19T19:46:10.804Z' }
I'm not doing anything to enforce type and it looks like I'm obeying type. Why am I getting error?
The model looks like:
// urls.js
module.exports = {
attributes: {
url : { type: 'string' },
status: { type: 'number'},
statusDate: {type: 'date'}
}
};
My config/models.js has schema set to false:
// config/models.js
module.exports.models = {
connection: 'DigitalOceanMongodbServer',
migrate: 'safe',
schema: false
};
My controller creates a new object with hard-coded status and statusDate of the correct type:
// urlsController.js
create: function (req, res) {
let url = req.body.url;
if(!url) return res.json({failure: 'empty url'});
let isValid = sails.validurl.isUri(url);
if(!isValid) return res.json({failure: 'url is not valid'});
let newObj = {
url: url,
status: 0, <---- obviously a number
statusDate: new Date().toISOString() <---obviously a date
}
console.log(newObj);
urls.create(newObj).exec(function createCB(err,created){
if (err){
return res.negotiate(err);
} else {
return res.ok(created);
}
});
}
Specify "integer" instead of "number" in the type of your model. I did not find "number" in the docs.
See: http://sailsjs.org/documentation/concepts/models-and-orm/attributes
I am trying to implement a custom validator for a paper-input. In this particular case, the control should accept positive numbers. However, not only only will the control only accept positive numbers, it will also run some other custom validation logic to determine if the entry falls within a constantly changing (dynamic & calculated) upper and lower limit. Ideally, the paper-input control's error-message text will also change depending on what part of the custom validator check failed.
In the past, I was able to implement this sort of thing with the gold-email-input element. In that case, the control checks for an entry that matches a regular expression for email addresses (i.e. implements a type-check). It also calls a backend api to see if the email address entered (as it is being typed), already exists in a database. If it exists in the database, the control fails validation and updates the control's validation error-message with a custom message. If it does not exist, it passes validation. As you might have imagined by this description, this was for a user registration UI element whereby the provided email should not already exist in the current list of user accounts. Here is an excerpt of that working code below for your reference:
<gold-email-input id="userEmail" label="Email" required auto-validate value="{{userEmail}}" error-message$="{{_getEmailErrorMsg(0)}}" invalid="{{_emailInvalid}}" validator="_validateEmail"></gold-email-input>
<iron-signals on-iron-signal-email-used="_accountFound" on-iron-signal-email-available="_accountNotFound"></iron-signals>
<script>
var emailErrors = ["Provide a valid email address", "Address already used"];
// Register the polymer element
Polymer({
properties: {
userEmail: {type: String, value: null},
validated: {type: Boolean, notify: true}, //overall validity state of entire element
_emailInvalid: {type: Boolean, value: true, observer: "_validityChanged"}, // validity state of email input itself
},
ready: function() {
// Called before attached
this.$.userEmail.validate = this._validateEmail.bind(this);
},
_accountFound: function() {
// Listener function intended to fire when the user email address/account was found
console.log(this.nodeName + " accountFound listener called\n");
this.$.userEmail.errorMessage = this._getEmailErrorMsg(1);
this._emailInvalid = true;
},
_accountNotFound: function() {
// Listener function intended to fire when the user email address/account was not found
console.log(this.nodeName + " accountNotFound listener called\n");
this.$.userEmail.errorMessage = this._getEmailErrorMsg(0);
this._emailInvalid = false;
},
_checkAccountExistance: function() {
if (this.userEmail !== undefined && this.userEmail != null) {
this.$.user.checkEmailAvailability(this.userEmail);
} else {
this._emailInvalid = true;
}
},
_getEmailErrorMsg: function(code) {
if (code !== undefined && code != null) {
return emailErrors[code];
} else {
return "";
}
},
_validateEmail: function() {
// Custom validator function for email input (also checks if email has already been associated to any user accounts)
console.log(this.nodeName + " validateEmail validator called\n");
// Check if proper email address format (W3C Spec Regex used)
var validEntry = /^[a-zA-Z0-9.!#$%&�*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(this.userEmail);
if (validEntry) {
this._emailInvalid = false;
this._checkAccountExistance();
} else {
this._emailInvalid = true;
}
}
_validityChanged: function(newVal, oldVal) {
// set the containing/parent element's overall validity state
this.validated = (!this._nameInvalid && !this._pwInvalid && !this._phoneInvalid && !this._emailInvalid && !this._countryInvalid && !this._regionInvalid && !this._cityInvalid);
},
});
</script>
Now, if I try to implement a similar approach with the paper-input component, it does not work. The custom validator function does not get called at any point. Is there something inherently different with paper-input compared to gold-email-input? Should it not treat validation the same way?
<paper-input id="xpos" label="Horizontal Position" required auto-validate value="{{XPos}}" error-message="Provide the x position" invalid="{{_xInvalid}}" validator="_validatePosition"></paper-input>
<script>
// Register the polymer element
Polymer({
properties: {
xPos: {type: Number},
validated: {type: Boolean, notify: true}, //overall validity state of entire element
_xInvalid: {type: Boolean, value: true, observer: "_validityChanged"}, // validity state of xpos input itself
},
ready: function() {
// Called before attached
this.$.xpos.validate = this._validatePosition.bind(this);
},
_validatePosition: function() {
console.log(this.nodeName + " validatePosition validator called\n");
// perform some validation code here like the gold-email-input example above
}
});
</script>
I'm using mongoose and trying to set a custom validation that tells the property shall be required (ie. not empty) if another property value is set to something. I'm using the code below:
thing: {
type: String,
validate: [
function validator(val) {
return this.type === 'other' && val === '';
}, '{PATH} is required'
]}
If I save a model with {"type":"other", "thing":""} it fails correctly.
If I save a model with {"type":"other", "thing": undefined} or {"type":"other", "thing": null} or {"type":"other"} the validate function is never executed, and "invalid" data is written to the DB.
As of mongoose 3.9.1, you can pass a function to the required parameter in the schema definition. That resolves this problem.
See also the conversation at mongoose: https://github.com/Automattic/mongoose/issues/941
For whatever reason, the Mongoose designers decided that custom validations should not be considered if the value for a field is null, making conditional required validations inconvenient. The easiest way I found to get around this was to use a highly unique default value that I consider to be "like null".
var LIKE_NULL = '13d2aeca-54e8-4d37-9127-6459331ed76d';
var conditionalRequire = {
validator: function (value) {
return this.type === 'other' && val === LIKE_NULL;
},
msg: 'Some message',
};
var Model = mongoose.Schema({
type: { type: String },
someField: { type: String, default: LIKE_NULL, validate: conditionalRequire },
});
// Under no condition should the "like null" value actually get persisted
Model.pre("save", function (next) {
if (this.someField == LIKE_NULL) this.someField = null;
next()
});
A complete hack, but it has worked for me so far.
Try adding this validation to the type attribute, then adjust your validation accordingly. E.g.:
function validator(val) {
val === 'other' && this.thing === '';
}
thing: {
type: String,
required: function()[{
return this.type === 'other';
}, 'YOUR CUSTOM ERROR MSG HERE']
}