I currently have a validation function to verify if the password and confirm password match. This seems to work just fine if I do not add updateOn blur, However when I add the blur it doesn't hit the match function which causes validation to not work. Not sure what I am doing wrong ?
Here is the function to check for matching passwords
```import { FormGroup } from '#angular/forms';
// custom validator to check that two fields match
export function MustMatch(controlName: string, matchingControlName: string) {
return (formGroup: FormGroup) => {
const control = formGroup.controls[controlName];
const matchingControl = formGroup.controls[matchingControlName];
if (matchingControl.errors && !matchingControl.errors.mustMatch) {
// return if another validator has already found an error on the matchingControl
return;
}
// set error on matchingControl if validation fails
if (control.value !== matchingControl.value) {
matchingControl.setErrors({ mustMatch: true });
} else {
matchingControl.setErrors(null);
}
};
}
```
Here is the HTML
``` <div class="card-block">
<p class="text-success" *ngIf="success">Your password has successfully been updated, you can now <a [routerLink]="['/login']">login</a> with your new password.</p>
<p class="text-danger" *ngIf="( resetPasswordForm.invalid && submitted)">Please complete all
required fields.</p>
<p class="text-danger" *ngIf="resetPasswordForm.controls['confirmPassword'].errors && resetPasswordForm.controls['confirmPassword'].errors.mustMatch">Passwords must match.</p>
<ng-container *ngIf="!success">
<p class="text-danger" *ngFor="let err of errorMessages">{{ err }}</p>
</ng-container>
<div class="form-group" [ngClass]="{'has-danger' :submitted && resetPasswordForm.controls.password.errors}">
<label class="form-control-label" for="password">New Password</label>
<input id="password" type="password" class="form-control" name="password" formControlName="password"
[ngClass]="{ 'is-invalid': submitted && resetPasswordForm.controls.password.errors}" required>
</div>
<div class="form-group" [ngClass]="{'has-danger' :submitted && resetPasswordForm.controls.confirmPassword.errors}">
<label class="form-control-label" for="confirmPassword">Confirm Password</label>
<input id="confirmPassword" type="password" class="form-control" name="confirmPassword" formControlName="confirmPassword"
[ngClass]="{ 'is-invalid': (submitted && resetPasswordForm.controls.confirmPassword.errors) ||
resetPasswordForm.controls['confirmPassword'].errors && resetPasswordForm.controls['confirmPassword'].error.mustMatch}" required>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary" >Reset Password</button>
<small class="text-muted"> <a [routerLink]="['/login']">Back to Login</a></small>
</div>
</form>
</section>```
Here is the component code
``` private createForm() {
this.resetPasswordForm = this.fb.group({
password: ['', Validators.required],
confirmPassword: ['', Validators.required]
}, {
validator: MustMatch('password', 'confirmPassword'), updateOn: 'blur' // verify that passwords match
});
}```
I would expect to see the error message "Passwords must match." after the user moves off the confirm password input box if they do not match. If they do match never seeing the error message
Seems that the code above does work, Not sure why I things were not working correctly but after many changes and reverting back it seems to now work
Related
I am getting this error "Access to XMLHttpRequest at 'http://localhost/api/auth/register' from origin 'http://127.0.0.1:8000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."
<template>
<div class="container mt-2">
<form autocomplete="off" #submit.prevent="register" method="post">
<div class="form-group" v-bind:class="{ 'has-error': has_error && errors.email }">
<label for="email">E-mail</label>
<input type="email" id="email" class="form-control bg-light border-0 small" placeholder="user#example.com" v-model="email">
<span class="help-block" v-if="has_error && errors.email">{{ errors.email }}</span>
</div>
<div class="form-group" v-bind:class="{ 'has-error': has_error && errors.password }">
<label for="password">Password</label>
<input type="password" id="password" class="form-control bg-light border-0 small" v-model="password">
<span class="help-block" v-if="has_error && errors.password">{{ errors.password }}</span>
</div>
<div class="form-group" v-bind:class="{ 'has-error': has_error && errors.password }">
<label for="password_confirmation">Conform Password</label>
<input type="password" id="password_confirmation" class="form-control bg-light border-0 small" v-model="password_confirmation">
</div>
<div class="alert alert-danger" v-if="has_error && !success">
<p v-if="error == 'registration_validation_error'">Validation error</p>
<p v-else>Please fill all the fields to get registered</p>
</div>
<input type="hidden" name="_token" :value="csrf">
<div class="text-center pb-3">
<button type="submit" class="btn btn-success btn-sm" style="background-color:#00A7F5;border:none;">Register</button>
</div>
</form>
</div>
</template>
<script>
export default {
data() {
return {
email: '',
password: '',
password_confirmation: '',
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
has_error: false,
error: '',
errors: {},
success: false
}
},
methods: {
register() {
var app = this
this.$auth.register({
data: {
email: app.email,
password: app.password,
password_confirmation: app.password_confirmation
},
success: function () {
app.success = true
},
error: function (res) {
app.has_error = true
app.error = res.response.error
app.errors = res.response.errors || {}
}
})
}
}
}
</script>
if fails, response from controller
$a = Validator::make($request->all(), [
'email' => 'required|email|unique:users',
'password' => 'required|min:6|confirmed',
]);
if ($a->fails())
{
return response()->json([
'status' => 'error',
'errors' => $a->errors()
], 422);
}
if everything ok then
return response()->json(['status' => 'success'], 200);
Please let me know whats wrong with this and is there any better way to handle error. Please share link then, i am not able to handle error correctly.
All helps are appreciated.
CORS policy checks strictly on domain plus port. So make both the same will be the solution.
You need to add CORS Service Provider to your project, like this: https://github.com/barryvdh/laravel-cors
I have an error when i try to show an error in the DOM when validating validators & async validators
My error:
ERROR TypeError: Cannot read property 'required' of null at
Object.eval [as updateDirectives]
In component html:
<div class="form-group">
<label for="email">email</label>
<input
type="text"
id="email"
formControlName="email"
class="form-control">
<div *ngIf="!signupForm.get('userData.email').valid && signupForm.get('userData.email').touched ">
<span class="help-block"
*ngIf="signupForm.get('userData.email').errors['required'] && signupForm.get('userData.email').touched">Email
is required
</span>
<span class="help-block"
*ngIf="signupForm.get('userData.email').errors['email'] && signupForm.get('userData.email').touched">Email
is not valid
</span>
</div>
In component.ts :
ngOnInit() {
this.signupForm = new FormGroup({
'userData': new FormGroup({
'username': new FormControl(null, [Validators.required, this.forbiddenNames.bind(this)]),
'email': new FormControl(null, [Validators.required, Validators.email], this.forbiddenEmails),
}),
'gender': new FormControl('male'),
'hobbies': new FormArray([])
});
}
Note: when i remove the async validator, (this.forbiddenEmails) from the form control async validator, it works:
'email': new FormControl(null, [Validators.required, Validators.email], this.forbiddenEmails)
(Works when i have only validators without async validators
i get no error, but i want to show the error for the async validator as well .)
I fixed this by using "hasError('errorName')":
<div class="form-group">
<label for="email">email</label>
<input
type="text"
id="email"
formControlName="email"
class="form-control">
<div *ngIf="!signupForm.get('userData.email').valid && signupForm.get('userData.email').touched ">
<span class="help-block"
*ngIf="signupForm.get('userData.email').hasError('required') && signupForm.get('userData.email').touched">Email
is required
</span>
<span class="help-block"
*ngIf="signupForm.get('userData.email').hasError['email'] && signupForm.get('userData.email').touched">Email
is not valid
</span>
Email
is not valid
The contoller shows output error1 it does not shoe even row(),and does not give any error in developer tool. it get the file from ajax users_controller but does not work & issue is contant.
This is the form:
<form class="form-signin" >
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="name" class="sr-only">Username</label>
<input type="text" id="name" class="form-control" placeholder="Username" autofocus><br/>
<label for="Password" class="sr-only">Password</label>
<input type="text" id="password" class="form-control" placeholder="Password">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Login</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
<span class="error"></span>
</form>
These are the scripts:
<script>
$(document).ready(function(){
$('form').on('submit',function(){
var username = $('#name').val();
var password = $('#password').val();
$.ajax({
type:'post',
url:'users_controller/login_check',
data: {
username:'username',
password:'password'
},
success:function(result)
{
if(result !== 'error')
{
window.location.href=result;
}
else
{
$('.error').html('');
$('.error').html('<p class="alert alert-danger">Invalid username or password</p>');
$('.error').show();
}
}
});
return false;
});
});
This is controller file:
public function login_check()
{
$username = $this->input->post('username',TRUE);
$password = $this->input->post('password',TRUE);
$this->load->model('users_model');
//$row = $this->load->users_model('getUsers');
$row = $this->users_model->getUsers($username,$password);
if($row)
{
if($this->username === $username && $this->password === $password)
{
$this->session->set_userdata('user_id',$row->user_id);
$this->session->set_userdata('user_name',$row->username);
echo base_url('users_controller');
}
else
{
echo "error";
}
}
else{
echo "error1";
print_r($row);
}
}
The contoller shows output error1 it does not shoe even row(),and does not give any error in developer tool.
I haven't been in FE solutions for a while. As a part of my FE education, I would like to create a simple VUE2 SPA app on ASP.NET Core BE using SPAServices/SPATempaltes. In general, I consider this as a great piece of technology, but I came to one problem. How to conduct client side validation. Some time ago I was using jquery validation that was integrated with ASP.NET MVC services. Can someone give me a point (maybe not the exact solution, but the places where to look for) how this can be done nowadays?
Regards
Client side Validation in VueJs or any front framework happens using HTML5 and Javascript. Like you did in Jquery all these frameworks exposes different events to subscribe and you can validate user inputs etc.
I found this post to be really helpful in doing your own validation for Vue (using vee-validation).
https://stu.ratcliffe.io/2017/7/23/integrating-vuejs-with-aspnet-core-mvc
Now it isn't using Vue as a SPA, but this is one that talks about validation. He also has a post on utilizing Vue and ASP.NET Core in a SPA here:
https://stu.ratcliffe.io/2017/07/20/vuejs-serverside-rendering-with-aspnet-core
Here is some of the validation code from the first post (in case of link rot):
(function (Vue, VeeValidate) {
if (document.querySelector('#contact')) {
Vue.use(VeeValidate);
var app = new Vue({
el: "#contact",
data: {
name: '',
email: '',
message: '',
errorMessage: ''
},
methods: {
send: function () {
this.$validator.validateAll().then(result => {
if (result) {
this.reset();
alert('Form submitted!');
} else {
this.errorMessage = 'Please fix all validation errors.'
}
});
},
reset: function () {
this.name = '';
this.email = '';
this.message = '';
this.errorMessage = '';
this.$validator.clean();
}
}
});
}
})(Vue, VeeValidate);
View
#{
ViewData["Title"] = "Contact";
}
<h2>#ViewData["Title"].</h2>
<div id="contact">
<form v-on:submit.prevent="send">
<div v-if="errorMessage.length" class="alert alert-danger">
{{ errorMessage }}
</div>
<div :class="{ 'form-group': true, 'has-error': errors.has('name'), 'has-success': name.length && !errors.has('name') }">
<label for="name">Name</label>
<input autofocus v-model="name" v-validate="'required|min:5'" class="form-control" name="name" type="text" />
<span v-show="errors.has('name')" class="text-danger">{{ errors.first('name') }}</span>
</div>
<div :class="{ 'form-group': true, 'has-danger': errors.has('email'), 'has-success': email.length && !errors.has('email') }">
<label for="email">E-mail</label>
<input v-model="email" v-validate="'required|email'" class="form-control" name="email" type="text" />
<span v-show="errors.has('email')" class="text-danger">{{ errors.first('email') }}</span>
</div>
<div :class="{ 'form-group': true, 'has-danger': errors.has('message'), 'has-success': message.length && !errors.has('message') }">
<label for="message">Message</label>
<textarea v-model="message" v-validate="'required|min:5'" class="form-control" name="message"></textarea>
<span v-show="errors.has('message')" class="text-danger">{{ errors.first('message') }}</span>
</div>
<input type="submit" value="Save" class="btn btn-primary" />
</form>
</div>
The project can be found at:
https://github.com/sturatcliffe/VueDotnetMVC
I am using vee-validate to validate the register form and i have made the code as follows,
<form #submit.prevent="signUp()">
<div class="form-group" :class="{'has-error': errors.has('register.mobile_number') }" >
<input v-model="register.mobile_number" v-validate="register.mobile_number" data-vv-rules="required" required class="form-control" type="number" placeholder="Mobile Number">
</div>
<div class="form-group" :class="{'has-error': errors.has('register.email') }" >
<input v-model="register.email" v-validate="register.email" class="form-control" type="email" data-vv-rules="required|email" placeholder="Email">
</div>
<div class="form-group" :class="{'has-error': errors.has('register.password') }" >
<input v-model="register.password" v-validate="register.password" name="password" data-vv-rules="required" class="form-control" type="password" placeholder="Password">
</div>
<div class="form-group" :class="{'has-error': errors.has('register.confirm_password') }" >
<input v-model="register.confirm_password" v-validate="register.confirm_password" name="confirm_password" data-vv-as="password" data-vv-rules="required|confirmed:password" class="form-control" type="password" placeholder="Confirm Password">
</div>
<div class="modal-footer btn-center">
<button type="submit" class="btn btn-default">Sign Up</button>
</div>
</form>
And the script was:
export default {
data() {
return {
register: {
mobile_number: '',
email: '',
password: '',
confirm_password: '',
},
}
},
methods: {
signUp() {
this.$validator.validateAll().then((result) => {
});
axios.post(config.apiDomain+'/Home',this.register).then(response=>{
});
}
},
}
And also imported vee-validate in main.js as,
import VeeValidate from 'vee-validate';
Vue.use(VeeValidate);
But if we enter anything inside the input box, it is throwing error as
Uncaught Error: [vee-validate] No such validator '12312321' exists.
Whatever thing i enter inside any of the input box, it is showing the same error. Kindly help me to resolve this issue.
I had a similar error in VeeValidate 3, and the problem is that I forgot to include the rules in the import statement and then extend them like this:
import { required, email, integer, between } from 'vee-validate/dist/rules';
extend('required', required);
extend('email', email);
extend('integer', integer);
extend('between', between);
In case someone else does the same mistake.
The code is incorrectly specifying the validation rules. For example here:
<input v-model="register.mobile_number" v-validate="register.mobile_number" data-vv-rules="required" class="form-control" type="number" placeholder="Mobile Number">
The code is saying that the validation rule should be whatever is in register.mobile_number because of this: v-validate="register.mobile_number".
Instead, you should specify the name(s) of the validation rules to use.
<input v-model="register.mobile_number" v-validate="'required'" class="form-control" type="number" name="Mobile Number" placeholder="Mobile Number">
Note that I added name="Mobile Number" because either name or data-vv-name is required, and I removed data-vv-rules because it is deprecated.
All of this is covered directly in the basic example in the documentation.