Skip to content

Instantly share code, notes, and snippets.

@theotherdy
Last active July 23, 2018 13:38
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 theotherdy/255bbff2015a8f32ce95b86e175f6842 to your computer and use it in GitHub Desktop.
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/
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