Last active
July 23, 2018 13:38
-
-
Save theotherdy/255bbff2015a8f32ce95b86e175f6842 to your computer and use it in GitHub Desktop.
Angular validator for 16 digit code which uniquely identifies an ORDCID id. See: https://learntech.imsu.ox.ac.uk/blog/angular-reactive-form-custom-validator-for-orcid/
This file contains hidden or 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 { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'; | |
/* | |
* Validator for 16 digit code which uniquely identifies an ORDCID id | |
* Digit 16 is a chceksum for digits 1-15 - this validator checks that | |
* Note: use other validators to check for valid Url which contains | |
* https://orcid.org | |
*/ | |
export function isORCIDValidator(control: AbstractControl): {[key: string]: any} | null { | |
if (control.value) { // don't check null values | |
// split url up on / | |
const urlParts: string[] = control.value.split('/'); | |
// get last digit | |
const lastDigit = urlParts[urlParts.length - 1].slice(-1); | |
// let's get numbers from last part (removing any hyphens, etc) | |
const orcidDigits = urlParts[urlParts.length - 1].replace(/\D/g, ''); | |
// strip last digit | |
const baseDigits = orcidDigits.slice(0, -1); | |
// get check digit - 0-9 or X | |
const generatedCheckDigit = generateCheckDigit(baseDigits).toString(); | |
if (generatedCheckDigit !== lastDigit) { | |
return {'isORCID': {value: control.value}}; //return error | |
} | |
} | |
return null; //no errors | |
} | |
/** | |
* Generates check digit as per ISO 7064 11,2. | |
* https://support.orcid.org/knowledgebase/articles/116780-structure-of-the-orcid-identifier | |
*/ | |
function generateCheckDigit(baseDigits: string) { | |
let total = 0; | |
for (let i = 0; i < baseDigits.length; i++) { | |
const digit = parseInt(baseDigits.charAt(i), 10); // base 10 | |
total = (total + digit) * 2; | |
} | |
const remainder: number = total % 11; | |
const result: number = (12 - remainder) % 11; | |
return result === 10 ? 'X' : result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment