I am using VueJS 3 and want to validate my step by step screen with single OR multiple input fields and want to check is he field valid or not and based on that I have to enable next button.
For validation I am using vee-validate plugin 4.7.3.
In my case I also do not want to use the form tag if possible. As my field is independent so no need to use form.
But as I search and read the comments of the package owner and mentioned that need to use Form so I used it but I just want to check the field validation as I have to show/hide the next button.
Component.vue
<template>
<Form :validateOnModelUpdate="true">
<Field name="mobile" as="input" :rules="mobileRules" v-model="mobile" />
</Form>
// Want to display button if the validation match
// Out side of the form
<button class="btn btn-default" v-if="IF_VALID" > Next </button>
</template>
<script>
import * as Yup from 'yup';
export default {
data(){
return {
mobile: '',
mobileRules: Yup.string().required().min(6)
}
}
}
</script>
If is there anyway to access the meta of the Field then may be that will be helped me.
Thanks.
I have tried to user UseField/useIsFieldValid but it shows me error that the
field with name mobile was not found
Also tried to use ref on the field but I can't able to access the meta of the Field
I have fixed it by using following code change:
For the field level validation need to code like this.
You can access field meta data in your component anywhere out of the Form
As per the owner comment if need to access this type of data out of the component need to achieve like this.
Owner Comment on Discussion
<template>
<div>
<form > <!-- This is simple HTML form -->
<input class="form-control" type="text" name="mobile" v-model="mobile" placeholder="000-0000-000">
<span class="text-danger" v-if="mobileErr">{{ mobileErr }}</span>
</form>
<button v-if="mobileMeta.valid"> Next </button>
</div>
</template>
<script>
import * as Yup from 'yup';
import { useField } from 'vee-validate';
export default {
setup(){
const mobileRules = Yup.string().required('Required').min(10, 'Must be 10 digits');
const { meta: mobileMeta, value: mobile, errorMessage: mobileErr} = useField('mobile', mobileRules);
return {
mobileMeta,
mobile,
mobileErr
}
},
data(){
return {
steps: '',
loading: false
}
},
created(){
},
methods:{
methodOne () {
// Some code to perform
},
methodTwo () {
// Some code to perform
}
}
}
</script>
Hopefully it will helps to others who want to perform step by step form and need to valid the field one by one.
Thanks.
Related
I am using a template based form in angular. I also use bootstrap (v4) and I wish to show some validation messages when the form was submitted.
This is my form:
<form [ngClass]="{'was-validated': wasValidated}">
<div class="form-group">
<label for="name">Name</label>
<input type="text" id="name" name="name" class="form-control" [(ngModel)]="category.name" #name="ngModel" required maxlength="100"/>
<div *ngIf="name.invalid" class="invalid-feedback">
<div *ngIf="name.errors.required">
Name is required.
</div>
</div>
</div>
<button type="submit" class="btn btn-success" (click)="save()">Save</button>
</form>
My component looks as follows:
category: Category;
wasValidated: boolean = false;
ngOnInit() {
this.reset();
}
save() {
this.wasValidated = true;
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
}
reset() {
this.wasValidated = false;
this.category = {} as Category;
}
This works, but I have a feeling it's overly complex and more like a workaround rather than the right way. What is the best way to accomplish this?
Note: the class was-validated must be present on the form element in order to show the div with class invalid-feedback. I'm using this: https://getbootstrap.com/docs/4.0/components/forms/#validation
Note 2: I have currently no mechanism yet to prevent form submission on error. I'd like to know a good solution for that as well!
With the answer from #Chellappan V I was able to construct the solution I wanted.
I have applied to following changes:
First added #form="ngForm" to the form tag in the template. Secondly I changed the ngClass expression to reference the submitted state of the form, rather than referring to a boolean which was set to true manually when form was submitted. Last but not least I pass the form in the submit method on the save button.
<form novalidate #form="ngForm" [ngClass]="{'was-validated': form.submitted}">
<!-- form controls -->
<button type="submit" class="btn btn-success" (click)="submit(form)">Save</button>
</form>
In the component I injected the template variable in the component with #ViewChild.
#ViewChild("form")
private form: NgForm;
The submit method now takes a form parameter of type NgForm which is used to check if the form was valid before sending a request to the backend:
submit(form: NgForm) {
if (form.valid) {
this.categoriesService.createCategory(this.category).subscribe(
() => {
this.notificationService.add(notifications.category_saved, {name: this.category.name});
this.reset();
},
() => this.notificationService.add(notifications.save_category_failed)
);
} else {
this.notificationService.add(notifications.validation_errors);
}
}
Finally the reset method resets the form and the model so it can be re-entered to submit a next instance:
reset() {
this.form.resetForm();
this.category = {} as NewCategoryDto;
}
I have an Angular 2 form with lots of required fields. Those have Validators.required assigned. I want to add an asterisk to these fields' labels.
<form [formGroup]="form">
<div class="form-group row">
<label class="col-sm-3 col-form-label">First Name -> Add asterisk here</label>
<div class="col-sm-9">
<input formControlName="firstName" type="text" class="form-control">
</div>
</div>
...
I have googled and read the docs, but can't find an implementation for this use case.
I know I can add the required attribute manually and work from there, but I would prefer to avoid as this seems redundant with the validator assignment.
Not sure, if its the best ng2-style solution, but what about this:
Let your FormComponent hold an array of required fields. In your template you can simply use something like:
<label for="firstName">
FirstName <span *ngIf="isFieldRequired('firstName')"> *</span>
</label>
You can create separate component for Label with asterisk, if you don't want to repeat the code through your template, for example:
#Component({
selector: 'my-label',
template: `<label for="{{id}}">{{label}} <span *ngIf="isFieldRequired(id)"> *</span></label>`
})
export class MyLabelComponent {
#Input() label: string;
#Input() id: string;
#Input() requires: [];
constructor() { }
isFieldRequired(id) {
return this.requires.indexOf(id) !== -1; // check if the array contains the value
}
}
In your Form Component, you just pass values to the my-label component, like:
<my-label [requires]="requiredFields" [label]="'Name'" [id]="'name'"></my-label>
Here is working plunker of this example: http://plnkr.co/edit/M66IFQGhhe82mNt3ekxw?p=preview
with the idea how to use the required definition together with more custom validators. See app.component.ts
I'm trying to render a form with data stored in the database. If I remove the form and wrap the PositionSingle input fields in a div the data renders correctly however I'm unable to make any changes. When I wrap the inputs in a form the component doesn't render.
I'm new to react with meteor so any assitance is appreciated.
Path: PositionSingle.jsx
render() {
return (
<form className="new-position" onSubmit={this.addPosition.bind(this)}>
<input
type="text"
ref="title"
placeholder="Position title"
defaultValue={this.props.position.title} />
<input
type="text"
ref="company"
placeholder="Company"
defaultValue={this.props.position.company} />
<button type="submit">Submit</button>
</form>
)
}
Path: PositionWrapper.jsx
render() {
return (
<div>
{this.positions().map( (position)=>{
return <PositionSingle key={position._id} position={position} />
})}
</div>
)
}
This is a very old question, so I don't know if you still have the same project, even, but I like to make sure there are no loose ends if I can. That error looks like what #ThaiTran said, that you don't have addPosition defined in PositionSingle. After you add that, that error should go away. Did that work?
Could you please share your experience and best practices when it comes to
ReactJS and Symfony2 used in common? How do you usually detect either user logged in or not inside React component ? Lets assume we need to show a "Delete" button or say hello to user in case he/she is logged in. What is your suggestions ? Store user's credential in global scope ?
const ExampleBox = React.createClass({
maybeSayHi: function () {
if (USER.IS_AUTHENTICATED_FULLY) {
return <div>Hi, user</div>;
}
},
render: function () {
return (
<div>
{this.maybeSayHi()}
<div>
Lorem
</div>
</div>
);
}
});
After some discussions I used following solution.
Inside my TWIG template I define few hidden element where I set all needed user's credentials such as user id and locale (language):
<input type="hidden" id="user_language" value="{{ app.request.getLocale() }}"/>
{% if is_granted('IS_AUTHENTICATED_REMEMBERED') %}
<input type="hidden" id="user_id" value="{{ app.user.id }}" />
{% endif %}
Then during React`s component initialization I grab values from these hidden fields into components as props.
var userId = document.getElementById("user_id").value;
var userLanguage = document.getElementById("user_language").value;
//We even can store it in the global variable
window.USER_DETAILS = {
user_id: userId,
user_language: userLanguage
};
ReactDOM.render(<Application user_id={userId} user_language={userLanguage } />, document.getElementById('application'));
I am using mizzao:autocomplete package in one of my search field in my application. Autocomplete is working fine and auto-suggestion is coming from my DB. As per given in the usage documentation this package using separate template for showing the suggestion list. Usually when someone select from given suggestion, the list will disappear and selected value appears in the textbox.
Now what i want is manually trigger some event in title template & do some extra stuff in autoComplete template when someone select some suggestion..
autoComplete.html
<template name="autoComplete">
<div class="col-md-4">
<h4>Auto Complete</h4>
{{> inputAutocomplete settings=settings id="jobTitle" class="form-control" name="title" placeholder="Job Title" autocomplete="off"}}
</div>
</template>
<template name="titles">
{{title}}
</template>
autoComplete.js
Template.autoComplete.helpers({
settings : function() {
return {
position: 'bottom',
limit: 10,
rules: [
{
collection: JobTitleCollection,
field: 'title',
matchAll: true,
template: Template.titles
}
]
};
}
});
You want to use the autocompleteselect event, as described in the docs.
Template.foo.events({
"autocompleteselect input": function(event, template, doc) {
console.log("selected ", doc);
}
});
(Disclaimer: I am mizzao.)