Last active
October 27, 2020 14:10
-
-
Save joepuzzo/47a158632530d7726b19d4b60773e2b2 to your computer and use it in GitHub Desktop.
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
const getFormatter = (formatter, value) => { | |
// If mask is a string turn it into an array; | |
if (typeof formatter === 'string') { | |
return formatter.split('').map((char) => { | |
if (char === '#') { | |
return /\d/; | |
} | |
if (char === '*') { | |
return /[\w]/; | |
} | |
return char; | |
}); | |
} | |
// If mask is a function use it to genreate current mask | |
if(typeof formatter === 'function'){ | |
return formatter(value); | |
} | |
if(Array.isArray(formatter)){ | |
return formatter; | |
} | |
// Should never make it here throw | |
throw new Error('Formatter must be string, array, or function') | |
} | |
const matchingIndex = ( a, b ) => { | |
let i = 0; | |
let mi = -1; | |
let matching = true; | |
// a = "+1 " | |
// b = "+12" | |
while(matching && i < a.length ){ | |
if( a[i] == b[i] ){ | |
mi = i; | |
} else { | |
matching = false; | |
} | |
i = i +1; | |
} | |
return mi; | |
} | |
const format = ( value, frmtr ) => { | |
console.log('Formatting', value); | |
// Null check | |
if( !value ){ | |
return value; | |
} | |
// Generate formatter array | |
const formatter = getFormatter( frmtr, value ); | |
// Start to fill in the array | |
// Example: phone formatter | |
// formatter =['+', '1', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/] | |
// value examples: | |
// "1231231234 ----> +1 123-123-1234 | |
// "+" ----> + | |
// "+1" ----> +1 | |
// "+2" ----> +1 2 | |
// "1" ----> +1 1 | |
// "1234" ----> +1 123-4 | |
// "123a" ----> +1 123 | |
// Determine prefix length and suffix start | |
const prefixLength = formatter.findIndex( v => typeof v != 'string'); | |
const suffixStart = formatter.length - [...formatter].reverse().findIndex( v => typeof v != 'string'); | |
// Formatted value | |
let formatted = []; | |
// The characters from the current value | |
const chars = value.split(''); | |
// To track the value index during itteration | |
let vIndex = 0; | |
let start = 0; | |
// If the value matches part of the prefix take it out | |
// Example prefix = "+1 " value = ["+1 123-123-1234", "+12", "+2"] | |
const matchIndex = matchingIndex(formatter.slice(0, prefixLength), chars.slice(0, prefixLength)); | |
console.log('Matching index', matchIndex); | |
if( matchIndex > -1 ) { | |
//vIndex = prefixLength; | |
vIndex = matchIndex + 1; | |
formatted = formatted.concat(formatter.slice(0,matchIndex + 1)); | |
start = matchIndex + 1; | |
} | |
// Example prefix = "+1 " value=["1", "1234"] | |
if( matchIndex < 0 ){ | |
// Start past the prefix | |
formatted = formatted.concat(formatter.slice(0,prefixLength)); | |
start = prefixLength; | |
} | |
// console.log('start', start, formatted); | |
// console.log('PREFIX_LENGTHT', prefixLength); | |
// console.log('SUFIX_START', suffixStart); | |
// console.log('FORMATTER_LENGTH', formatter.length); | |
// To track if we have made it past the prefix | |
let pastPrefix = false; | |
// Fill in the stuff | |
for(let i = start; i < formatter.length; i++ ){ | |
// Get current formatter location matcher | |
const matcher = formatter[i]; | |
// We get past the prefix if matcher is not a string | |
if( !pastPrefix && typeof matcher != "string" ){ | |
pastPrefix = true; | |
} | |
// Chec to see if there is more value to look at | |
if( vIndex != chars.length ){ | |
// Get the current value character | |
const curChar = chars[vIndex]; | |
// If type is string normal compare otherwise regex compare | |
const match = typeof matcher === "string" ? matcher === curChar : matcher.test(curChar); | |
// If the current character of the value matches and matcher is a string | |
// "1" === "1" | |
if( match && typeof matcher === "string" ){ | |
formatted.push(matcher); | |
//if( pastPrefix ){ | |
vIndex = vIndex + 1; | |
//} | |
} | |
// If the current character does not match and matcher is a stirng | |
// "1" != "+" | |
else if( !match && typeof matcher === "string"){ | |
// Special check for 123a ---> dont want "+1 123-" | |
// Special check for 1234 ---> DO want "+1 123-4" | |
if( vIndex != chars.length) formatted.push(matcher); | |
} | |
// If the current character matches and the matcher is not a string | |
// /\d/.test("2") | |
else if( match && typeof matcher != "string" ) { | |
formatted.push(curChar); | |
vIndex = vIndex + 1; | |
} | |
// If the current character does NOT match and the matecer is regex | |
// /\d/.test("a") | |
else if( !match && typeof matcher != "string" ){ | |
// Throw out this value | |
vIndex = vIndex + 1; | |
i = i - 1; | |
} | |
} else { | |
// If mattcher is a string and we are at suffix keep going | |
if( typeof matcher === "string" && i >= suffixStart ){ | |
formatted.push(matcher); | |
} else { | |
// Otherwise we want to break out | |
break; | |
} | |
} | |
} | |
return formatted.join(""); | |
} | |
const fmtr = ['+', '1', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]; | |
// undefiend ----> undefined | |
console.log( format(undefined, fmtr) ); | |
console.log('\n'); | |
// "1231231234 ----> +1 123-123-1234 | |
console.log( format("1231231234", fmtr) ); | |
console.log('\n'); | |
// "+" ----> + | |
console.log( format("+", fmtr) ); | |
console.log('\n'); | |
// "+1" ----> +1 | |
console.log( format("+1", fmtr) ); | |
console.log('\n'); | |
// "+11" ----> +1 1 | |
console.log( format("+11", fmtr) ); | |
console.log('\n'); | |
// "+2" ----> +1 2 | |
console.log( format("+2", fmtr) ); | |
console.log('\n'); | |
// "1" ----> +1 1 | |
console.log( format("1", fmtr) ); | |
console.log('\n'); | |
// "1234" ----> +1 123-4 | |
console.log( format("1234", fmtr) ); | |
console.log('\n'); | |
// "+1 123-456" ----> +1 123-456 | |
console.log( format("+1 123-456", fmtr) ); | |
console.log('\n'); | |
// "+1 123-456-" ----> +1 123-456- | |
console.log( format("+1 123-456-", fmtr) ); | |
console.log('\n'); | |
// "123-456-" ----> +1 123-456- | |
console.log( format("123-456-", fmtr) ); | |
console.log('\n'); | |
// "123a" ----> +1 123 | |
console.log( format("123a", fmtr) ); | |
console.log('\n'); | |
// "123a456B78" ----> +1 123-456-78 | |
console.log( format("123a456b78", fmtr) ); | |
console.log('\n'); | |
// "123abc456B78" ----> +1 123-456-78 | |
console.log( format("123abc456b78", fmtr) ); | |
console.log('\n'); | |
// "+1 123-a" ----> +1 123- | |
console.log( format("+1 123-a", fmtr) ); | |
console.log('\n'); | |
// "123-a" ----> +1 123- | |
console.log( format("123-a", fmtr) ); | |
console.log('\n'); | |
// "1234567812345678" ----> "1234-5678-1234-5678" | |
console.log( format("1234567812345678", "####-####-####-####") ); | |
console.log('\n'); | |
// "3000" ----> "$3,000.00&" | |
console.log( format("3000", "$#,###.00&") ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment