Skip to content

Instantly share code, notes, and snippets.

@kostyanet
Created May 23, 2017 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kostyanet/d4f5f577c65068128624467eda47a891 to your computer and use it in GitHub Desktop.
Save kostyanet/d4f5f577c65068128624467eda47a891 to your computer and use it in GitHub Desktop.
import { Component, ElementRef } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators, AbstractControl, ValidatorFn } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription';
import {DOMElement} from '../interfaces/misc.interface';
import {UserService} from '../services/user.service';
import AppValues from '../misc/app.values';
/*** Custom validators ***/
// name: ^[a-zA-Z]+(([\'\,\.\- ][a-zA-Z ])?[a-zA-Z]*)*$
const namePattern = /^[a-zA-ZàáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçšžÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßnjƊŽ∂ð ,.'-]+$/u;
const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/;
const emailPattern = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/i;
const phonePattern = /^(\(?\+?[0-9]*\)?)?[0-9_\- \(\)]*$/;
const cityPattern = /^[a-zA-Z]+[\. - ']?(?:[\s-][a-zA-Z0-9]+)*$/;
const statePattern = /^(?:(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY]))$/;
const codePattern = /^[a-zA-Z\d][a-zA-Z\d\- ]*[a-zA-Z\d]$/;
const charsAntiPattern = /[!@$%^&*_<>\{\}'"`+±§~]+/;
function antiPatternMatcher(antiPattern: RegExp): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} => {
return control.value.match(antiPattern) ? {pattern: true} : null;
};
}
function duplicatePassword(input: FormControl) {
const inp = (input.root as any);
if (!inp || !inp.controls) return null;
const exactMatch = inp.controls.password.value === input.value;
return exactMatch ? null : { mismatchedPassword: true };
}
@Component({
selector: 'signup',
templateUrl: 'app/components/signup.component.html'
})
export default class SignupComponent {
formErrors = {
'firstName': '',
'lastName': '',
'login': '',
'password': '',
'password2': '',
'email': '',
'phone': '',
'address': '',
'city': '',
'state': '',
'code': '',
'country': '',
'ppFirstName': '',
'ppLastName': '',
'ppEmail': '',
};
validationMessages = {
'firstName': {
'required': 'First Name is required.',
'pattern': 'Shouldn\'t contain digits and special characters'
},
'lastName': {
'required': 'First Name is required.',
'pattern': 'Shouldn\'t contain digits and special characters'
},
'login': {
'required': 'Login is required.',
'pattern': 'Shouldn\'t contain special characters',
'used': 'This login is already used'
},
'password': {
'required': 'Password is required.',
'pattern': '8 characters min: upper+lowercase and digit(s)'
},
'password2': {
'required': 'Password confirmation is required.',
'pattern': '8 characters min: upper+lowercase and digit(s)',
'match': 'Passwords mismatch!'
},
'email': {
'required': 'Email is required.',
'pattern': 'Wrong email pattern!',
'used': 'This email is already used'
},
'phone': {
'required': 'Phone is required.',
'pattern': 'Wrong phone pattern!'
},
'address': {
'required': 'Address is required.',
'pattern': 'Wrong address pattern!'
},
'city': {
'required': 'City is required.',
'pattern': 'Wrong city pattern!'
},
'state': {
'required': 'State is required.',
'pattern': 'Wrong state pattern!'
},
'code': {
'required': 'Code is required.',
'pattern': 'Wrong code pattern!'
},
'country': {
'required': 'Country is required.',
'pattern': 'Please, choose your country'
},
'ppFirstName': {
'required': 'PayPal first name is required.',
'pattern': 'Shouldn\'t contain digits and special characters'
},
'ppLastName': {
'required': 'PayPal last name is required.',
'pattern': 'Shouldn\'t contain digits and special characters'
},
'ppEmail': {
'required': 'PayPal account email is required.',
'pattern': 'Wrong email pattern!'
},
};
signupForm: FormGroup;
countryErr: boolean = false;
countries = AppValues.countries;
warningMsg: string;
busy: boolean;
private userType: string = 'shopper';
private countrySelect: any;
private elem: DOMElement;
private signupSubscription: Subscription;
constructor(
private fb: FormBuilder,
private elementRef: ElementRef,
private userService: UserService
) {
this.elem = elementRef.nativeElement;
this.userService = userService;
}
ngOnInit() {
this.buildForm();
}
ngAfterViewInit() {
this.countrySelect = this.elem.querySelector('.input__select');
let o1 = this.countrySelect.querySelectorAll('option')[0];
o1.disabled = true;
}
buildForm(): void {
this.signupForm = this.fb.group({
'firstName': [
'', [Validators.required, Validators.pattern(namePattern)]
],
'lastName': [
'', [Validators.required, Validators.pattern(namePattern)]
],
'login': [
'', [Validators.required, antiPatternMatcher(charsAntiPattern)]
],
'password': [
'', [Validators.required, Validators.pattern(passwordPattern)]
],
'password2': [
'', [Validators.required, Validators.pattern(passwordPattern), duplicatePassword]
],
'email': [
'', [Validators.required, Validators.pattern(emailPattern)]
],
'phone': [
'', [Validators.required, Validators.pattern(phonePattern)]
],
'address': [
'', [Validators.required, antiPatternMatcher(charsAntiPattern)]
],
'city': [
'', [Validators.required, Validators.pattern(cityPattern)]
],
'state': [
'', [Validators.pattern(statePattern)]
],
'code': [
'', [Validators.required, Validators.pattern(codePattern)]
],
// country validation declined to work. reason unknown
// Performed custom, see `onCountryChange()`
'country': [
'', // [Validators.required]
],
'ppFirstName': [
'', [Validators.required, Validators.pattern(namePattern)]
],
'ppLastName': [
'', [Validators.required, Validators.pattern(namePattern)]
],
'ppEmail': [
'', [Validators.required, Validators.pattern(emailPattern)]
],
});
this.signupForm.valueChanges
.subscribe(data => this.onValueChanged(data));
this.onValueChanged(); // (re)set validation messages now
}
onCountryChange(e: Event) {
let c = this.signupForm.value.country;
this.countrySelect.classList.remove('error');
this.countryErr = false;
this.formErrors.country = '';
if (c === '') {
this.countryErr = true;
this.formErrors.country = 'Country required!';
this.countrySelect.classList.add('error');
}
}
onValueChanged(data?: any) {
if (!this.signupForm) { return; }
this.warningMsg = '';
const form = this.signupForm;
for (const field in this.formErrors) {
if (field === 'country') continue;
// clear previous error message (if any)
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
} // eofn
onSubmit(event: Event) {
this.busy = true;
let x = this.signupForm.value;
const userDump = {
latitude: 0,
longitude: 0,
accessLevel: 1,
};
if (this.countryErr) {
this.toggleWarning('country');
} else if (this.signupForm.invalid) {
this.toggleWarning('other');
} else {
this.toggleWarning();
let user = Object.assign({
login: x.login,
password: x.password,
firstName: x.firstName,
lastName: x.lastName,
email: x.email,
title: this.userType,
paypal_email: x.ppEmail,
addresses: [
{
firstName: x.ppFirstName,
lastName: x.ppLastName,
address: x.address,
city: x.city,
postCode: x.code,
country: x.country,
isPrimary: true,
state: x.state,
phone: x.phone
}
]
}, userDump);
console.log(user);
// timeout for manual test purpose
// setTimeout(() => {
this.signupSubscription = this.userService
.signup(user)
.subscribe(
(response) => {
this.busy = false;
console.log(response);
}, (err: any) => {
console.error(err);
this.busy = false;
this.toggleWarning(err.status);
});
// }, 1200);
} // end if
event.preventDefault();
return false;
}
toggleWarning(key?: string | number) {
this.onCountryChange(null);
switch (key) {
case 'country':
this.warningMsg = 'Please select your country.';
break;
case 501:
case 'login':
this.warningMsg = 'This LOGIN is already occupied. Please choose another one.';
this.formErrors.login = this.warningMsg;
break;
case 503:
case 'email':
this.warningMsg = 'This EMAIL is already used. Please choose another one.';
this.formErrors.email = this.warningMsg;
break;
case 'other':
this.warningMsg = 'Please check all the fields for completeness or typos.';
break;
default:
this.warningMsg = '';
break;
}
}
setUserType(event: string) {
this.userType = event;
// for testing purpose. left here
// this.signupForm.setValue({
// address: '8, Lyubaya str.',
// city: 'Kharkov',
// code: '61000',
// country: 'Ukraine',
// email: 'my@mail.com',
// firstName: 'Kostya',
// lastName: 'Net',
// login: 'KOSTYA',
// password: 'Password1',
// password2: 'Password1',
// phone: '+380669977555',
// ppEmail: 'my1@mail.com',
// ppFirstName: 'Kostyan',
// ppLastName: 'Netro',
// state: 'TX'
// });
}
ngOnDestroy() {
this.signupSubscription && this.signupSubscription.unsubscribe();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment