Created
June 17, 2009 18:20
-
-
Save silentmatt/131402 to your computer and use it in GitHub Desktop.
JavaScript class to represent and format names
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
var Name = (function() { | |
function Name(prefix, first, middle, last, suffix, called) { | |
this.prefix = prefix || ""; | |
this.first = first || ""; | |
this.middle = middle || ""; | |
this.last = last || ""; | |
this.suffix = suffix || ""; | |
this.called = called || ""; | |
} | |
function capitalize(s) { | |
return s.charAt(0).toUpperCase() + s.substring(1); | |
} | |
function addSetter(cls, name, fn) { | |
cls.prototype["set" + capitalize(name)] = fn || function(value) { | |
this[name] = value; | |
return this; | |
}; | |
// Define a JS setter if it's supported and needed | |
if (fn && cls.prototype.__defineGetter__) { | |
cls.prototype.__defineGetter__(name, fn); | |
} | |
} | |
function addGetter(cls, name, fn) { | |
cls.prototype["get" + capitalize(name)] = fn; | |
if (cls.prototype.__defineGetter__) { | |
cls.prototype.__defineGetter__(name, fn); | |
} | |
} | |
// Chainable setters | |
addSetter(Name, "prefix"); | |
addSetter(Name, "prefix"); | |
addSetter(Name, "first"); | |
addSetter(Name, "middle"); | |
addSetter(Name, "last"); | |
addSetter(Name, "suffix"); | |
addSetter(Name, "called"); | |
// Common name formats | |
addGetter(Name, "fullName", function() { | |
return this.toString("PFMLS"); | |
}); | |
addGetter(Name, "lastFirst", function() { | |
return this.toString("L,F"); | |
//return (this.last + ", " + this.first).replace(/(^, )|(, $)/, ""); | |
}); | |
addGetter(Name, "lastFirstMiddle", function() { | |
return this.toString("L,FM"); | |
}); | |
addGetter(Name, "firstLast", function() { | |
return this.toString("FL"); | |
}); | |
addGetter(Name, "firstMiddleLast", function() { | |
return this.toString("FML"); | |
}); | |
addGetter(Name, "informal", function() { | |
return this.toString("CL"); | |
}); | |
// Initials | |
addGetter(Name, "firstInitial", function() { | |
return (this.first || "").substring(0, 1); | |
}); | |
addGetter(Name, "middleInitial", function() { | |
return (this.middle || "").substring(0, 1); | |
}); | |
addGetter(Name, "lastInitial", function() { | |
return (this.last || "").substring(0, 1); | |
}); | |
addGetter(Name, "monogram", function() { | |
return this.getFirstInitial() + this.getMiddleInitial() + this.getLastInitial(); | |
}); | |
// Names match if all the common parts match | |
Name.prototype.matches = function(other) { | |
if (this.prefix && other.prefix) { | |
if (this.prefix != other.prefix) { | |
return false; | |
} | |
} | |
if (this.first && other.first) { | |
if (this.first != other.first) { | |
return false; | |
} | |
} | |
if (this.middle && other.middle) { | |
if (this.middle != other.middle) { | |
return false; | |
} | |
} | |
if (this.last && other.last) { | |
if (this.last != other.last) { | |
return false; | |
} | |
} | |
if (this.suffix && other.suffix) { | |
if (this.suffix != other.suffix) { | |
return false; | |
} | |
} | |
return true; | |
} | |
// Spaces are automatically inserted between parts where it (hopefully) makes sense | |
// Leading and trailing spaces and commas, as well as empty quotes, braces, etc. are stripped. | |
// Multiple spaces are squeezed into a single space. | |
// | |
// Default format is "PFMLS" - the same as getFullName() | |
// | |
// Format characters: | |
// P - Prefix | |
// N - Nickname (called) | |
// C - Called By (called or first) | |
// F,f - First / first initial | |
// M,m - Middle / middle initial | |
// L,l - Last / last initial | |
// S - Suffix | |
// (,[,{," - Literal (no implied space after) | |
// ),],} - Literal | |
// .,comma - Literal (skipped if the last part was missing) | |
// space - Force a space (useful after an end quote) | |
Name.prototype.toString = function(fmt) { | |
fmt = fmt || "PFMLS"; | |
var parts = []; | |
var sep = ""; | |
var hadLast = false; | |
function pushPart(value) { | |
hadLast = false; | |
if (value) { | |
parts.push(sep + value); | |
sep = " "; | |
hadLast = true; | |
} | |
} | |
for (var i = 0; i < fmt.length; i++) { | |
var c = fmt.charAt(i); | |
switch (c) { | |
case ',': | |
case '.': | |
if (hadLast) { | |
parts.push(c); | |
sep = " "; | |
} | |
break; | |
case ' ': | |
parts.push(" "); | |
sep = ""; | |
break; | |
case 'P': | |
pushPart(this.prefix); | |
break; | |
case 'N': | |
pushPart(this.called); | |
break; | |
case 'C': | |
pushPart(this.called || this.first); | |
break; | |
case 'F': | |
pushPart(this.first); | |
break; | |
case 'f': | |
pushPart(this.getFirstInitial()); | |
break; | |
case 'M': | |
pushPart(this.middle); | |
break; | |
case 'm': | |
pushPart(this.getMiddleInitial()); | |
break; | |
case 'L': | |
pushPart(this.last); | |
break; | |
case 'l': | |
pushPart(this.getLastInitial()); | |
break; | |
case 'S': | |
pushPart(this.suffix); | |
break; | |
case '"': | |
parts.push('"'); | |
sep = ""; | |
break; | |
case '{': | |
case '[': | |
case '(': | |
parts.push(sep + c); | |
sep = ""; | |
break; | |
case '}': | |
case ']': | |
case ')': | |
parts.push(c); | |
sep = " "; | |
break; | |
default: | |
throw new Error("Invalid format character: '" + c + "'"); | |
} | |
} | |
return parts.join("").replace(/(^[, ]+)|([, ]+$)|(\(\))|("")|(\[\])|({})/g, "").replace(/ +/g, " "); | |
} | |
Name.test = function() { | |
function expect(actual, expected) { | |
if (expected !== actual) { | |
print("Expected <" + expected + "> but got <" + actual + ">"); | |
return false; | |
} | |
return true; | |
} | |
var me = new Name(); | |
me.setFirst("Matthew").setLast("Crumley").setCalled("M@"); | |
expect(me.first, "Matthew"); | |
expect(me.last, "Crumley"); | |
expect(me.middle, ""); | |
expect(me.firstInitial, "M"); | |
expect(me.lastInitial, "C"); | |
expect(me.monogram, "MC"); | |
expect(me.toString(), "Matthew Crumley"); | |
expect(me.toString('F "N" L'), 'Matthew "M@" Crumley'); | |
expect(me.toString('L,F'), 'Crumley, Matthew'); | |
me.called = ""; | |
expect(me.toString('L,N'), 'Crumley'); | |
expect(me.toString('L,C'), 'Crumley, Matthew'); | |
} | |
return Name; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment