Created
May 23, 2017 12:49
-
-
Save kostyanet/d4f5f577c65068128624467eda47a891 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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