admin管理员组文章数量:1294329
I am trying to check the email validity (when the user start typing onkeyup), then if the email is valid I push it into an array of unique emails; however, I stop pushing to the array once it reaches a certain number, in my case it's 3.
<textarea (ngModelChange)="onKeyUp($event)"></textarea>
onKeyUp(ev) {
let finalEmailList = []
this.finalEmailList = [];
this.numberOfUsers = 3;
let emails = ev.replace(' ', '').split(/,| /);
emails.forEach(email => {
if (this.validateEmail(email)) {
//If the email has a valid format, the push it to the array
finalEmailList.push(email);
//it's a lodash function to clean the array an keep only unique emails in the array
this.finalEmailList = _.uniq(finalEmailList);
if (this.finalEmailList.length <= this.numberOfUsers) {
this.numberOfUsers -= this.finalEmailList.length;
}
}
})
}
//returns true if the email has a valid format
validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\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,}))$/;
return re.test(email);
}
The issue:
I believe it's a wrong way to do it as on each and every letter printed from the keyboard everything runs again and again, resetting variables, running for loops, etc...
Also the value returned for this.numberOfUsers is not correct.
I am trying to check the email validity (when the user start typing onkeyup), then if the email is valid I push it into an array of unique emails; however, I stop pushing to the array once it reaches a certain number, in my case it's 3.
<textarea (ngModelChange)="onKeyUp($event)"></textarea>
onKeyUp(ev) {
let finalEmailList = []
this.finalEmailList = [];
this.numberOfUsers = 3;
let emails = ev.replace(' ', '').split(/,| /);
emails.forEach(email => {
if (this.validateEmail(email)) {
//If the email has a valid format, the push it to the array
finalEmailList.push(email);
//it's a lodash function to clean the array an keep only unique emails in the array
this.finalEmailList = _.uniq(finalEmailList);
if (this.finalEmailList.length <= this.numberOfUsers) {
this.numberOfUsers -= this.finalEmailList.length;
}
}
})
}
//returns true if the email has a valid format
validateEmail(email) {
var re = /^(([^<>()\[\]\\.,;:\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,}))$/;
return re.test(email);
}
The issue:
I believe it's a wrong way to do it as on each and every letter printed from the keyboard everything runs again and again, resetting variables, running for loops, etc...
Also the value returned for this.numberOfUsers is not correct.
Share edited May 19, 2018 at 14:12 Folky.H asked May 16, 2018 at 23:02 Folky.HFolky.H 1,2044 gold badges16 silver badges40 bronze badges 5-
let emails = ev.replace(' ', '').split(/,| /);
you call.replace
on the$event
– Karen Grigoryan Commented May 19, 2018 at 14:23 - Create a custom ponent, subscribe on blur, validate email only once and emit the event to the subscriber. or Use pattern html5 attribute – Drag13 Commented May 19, 2018 at 14:24
-
let email = ev.value.replace(' ', '').split(/,| /);
– Ritwick Dey Commented May 19, 2018 at 15:10 - Your code runs every time someone releases a key, si youll want to find a way go gather the keys and run the loop once the user is done. Regarding the number od users issue, I dont know what you are trying to achieve there, do you want to equalize the amount of users and emails in list? – Jusmpty Commented May 20, 2018 at 8:05
- You should use a directive which will simply deny the wrong input, so you will get always correct email in Input. however user can copy and paste the wrong email. That you can check against the regex. The same regex you can use in your directive. – Deepender Sharma Commented Dec 30, 2019 at 12:38
4 Answers
Reset to default 1If you want the email address to be plete before validating, validating onBlur as others have suggested may be your best course of action. Another option is to continue listening for onKeyUp, but only trigger validation if the key is a specific trigger key.
Example:
onKeyUp(event) {
if ([13, 188].includes(event.keyCode)) {
validateEmails()
}
}
In this example, 13 and 188 are the key codes for Enter and ma, respectively.
If you want to apply a check on different entries, the simplest solution would be to have one input per email. Not sure it'll fit your need as you haven't say whether you want to stick with a textarea or not but here's my idea:
Create a form containing a formArray
with all the required emails.
this.emailsForm = this.fb.group({
emails: this.fb.array(this.getEmailsFormGroup())
});
Here's how to create the formArray
:
getEmailsFormGroup() {
const emailsForms: FormGroup[] = [];
for (let i=0; i<this.nbEmails; i++) {
emailsForms.push(this.fb.group({
email: ['', [emailValidator()], []]
}));
}
return emailsForms;
}
Here we're taking advantage of the validators array and calling a custom validator emailValidator
, which is defined like that:
const emailRegex = /^(([^<>()\[\]\\.,;:\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,}))$/;
export function emailValidator(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
return emailRegex.test(control.value) ?
null :
{ 'not-email-like': { value: control.value } };
};
}
Full ponent code (TS):
@Component({
selector: 'app-emails',
templateUrl: './emails.ponent.html',
styleUrls: ['./emails.ponent.css']
})
export class EmailsComponent implements OnInit {
nbEmails = 3;
emailsForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.emailsForm = this.fb.group({
emails: this.fb.array(this.getEmailsFormGroup())
});
}
getEmailsFormGroup() {
const emailsForms: FormGroup[] = [];
for (let i = 0; i < this.nbEmails; i++) {
emailsForms.push(this.fb.group({
email: ['email-' + i, [emailValidator()], []]
}));
}
return emailsForms;
}
}
HTML:
Please enter the {{ nbEmails }} required email{{ nbEmails > 1 ? 's' : '' }}
<form [formGroup]="emailsForm">
<div formArrayName="emails">
<div *ngFor="let email of emailsForm.controls['emails'].controls; let i=index" [formGroupName]="i">
<input
type="text"
formControlName="email"
>
</div>
</div>
</form>
<hr>
<div>
VALID? {{ emailsForm.valid }}
</div>
<hr>
<div>
<pre>
{{ emailsForm.value | json }}
</pre>
</div>
Here's a working version on Stackblitz:
https://stackblitz./edit/angular-lxltri?file=src%2Fapp%2Femails%2Femails.ponent.ts
Notice that you have access to the property valid
of the form so you know when the X emails are in a valid state.
What I understand is, you have a textarea, where user can enter multiple emailIds. You want to validate each and add into an array.
First, you should not subscribe to ngModelChange, instead subscribe to blur event. Which means only when user moves out of the field, you split the input value based on ma separator and validate each.
Second, you can also separate the input value based on /n i.e. line change. using this .split(/\r?\n/)
This way you don't have to clean array, loop through input field value every time user enters something.
I rather have a single input and a add button. Take the email input and run the logic on click event of add button.That will make sure code runs only when needed and provides user with a better UX. Something like git has done with user profiles Reference UI
本文标签: AngularJavascriptreturn the correct number onKeyUpStack Overflow
版权声明:本文标题:AngularJavascript - return the correct number onKeyUp - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741591131a2387133.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论