Soundex Calculator
by Kyle Mitofsky
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="steps">
<div class="empty"></div>
<div class="step">Step 1:</div>
<div class="step">Step 2:</div>
<div class="step">Step 3:</div>
<div class="step">Step 4:</div>
</div>
<div class="soundex" data-bind="template: { name: 'soundex', data: word1 }"> </div>
<div class="soundex" data-bind="template: { name: 'soundex', data: word2 }"> </div>
<div class="steps-desc">
<div class="empty"></div>
<div class="step">Drop vowels and H & Y</div>
<div class="step">Replace letters with numbers</div>
<div class="step">Remove redundant numbers</div>
<div class="step">Trim/Pad to 4 digits</div>
</div>
<script type="text/html" id="soundex">
<input class="input" data-bind='value: text, valueUpdate: "input"' />
<div class="step" data-bind="template: { name: 'characters', data: step1Result }"> </div>
<div class="step" data-bind="template: { name: 'characters', data: step2Result }"> </div>
<div class="step" data-bind="template: { name: 'characters', data: step3Result }"> </div>
<div class="step" data-bind="template: { name: 'characters', data: step4Result }"> </div>
</script>
<script type="text/html" id="characters">
<span class="chars" data-bind="foreach: $data.chars, css: { 'final' : $data.step === 4 }" >
<span class="char" data-bind="text: $data !== '' ? $data : ' ', css: { 'match' : $root.diff()[$index()] } "></span>
</span>
</script>
<hr class="clear">
<code class="results">
<span class="keyword" >SELECT</span>
<span class="function" >SOUNDEX</span><span class="operator">(</span><span class="string" >'<span data-bind="text: word1.text"></span>'</span><span class="operator">)</span><br>
<span class="keyword" >SELECT</span>
<span class="function" >SOUNDEX</span><span class="operator">(</span><span class="string" >'<span data-bind="text: word2.text"></span>'</span><span class="operator">)</span><br>
...
CSS
@font-face {
font-family: 'Smiler';
src: url('//2ttf.com/webfont/EoVxytkhYOw/webfont.ttf') format('truetype');
}
/* sample using the font */
body{
font-family: 'Smiler';
}
@media (max-width: 660px) {
.steps-desc {
display: none;
}
}
.steps, .steps-desc, .soundex, .results {
margin: 10px;
float: left;
}
.clear {
clear:both;
}
.empty {
height: 30px;
}
.input {
font-size: 16px;
width: 120px;
}
.step {
height: 30px;
}
.steps-desc {
color: #1f1f1f;
font-size: 14px;
}
.chars .char {
font-family: consolas, monospace;
display:inline-block;
width:15px;
margin: 0 1.5px;
text-align: center;
vertical-align: bottom;
font-size:20px;
border-bottom: solid 1.5px black;
border-radius:3px;
}
.chars.final .char {
border-bottom-width: 3px;
border-radius: 4px;
border-bottom-color: #ec2222;
}
.chars.final .char.match {
border-bottom-color: #2bd22b;
}
.chars .char:first-child {
font-weight: bold;
color: #002cc6;
}
.chars:not(.final) .char:first-child:after,
.chars.final .char:nth-of-type(4):after {
content: ' ';
position: relative;
left: 6px;
top: 2px;
border: 1px solid #5b5b5b;
}
code {
font-family: consolas, monospace;
}
code .keyword { color: #0000FF }
code .function { color: #FF00FF }
code .string { color: #FF0000 }
code .operator { color: #988080 }
code .comment { color: #008000 }
JavaScript
if (!Array.prototype.filter){
Array.prototype.filter = function(func, thisArg) {
'use strict';
if ( ! ((typeof func === 'Function' || typeof func === 'function') && this) )
throw new TypeError();
var len = this.length >>> 0,
res = new Array(len), // preallocate array
t = this, c = 0, i = -1;
if (thisArg === undefined){
while (++i !== len){
// checks to see if the key was set
if (i in this){
if (func(t[i], i, t)){
res[c++] = t[i];
}
}
}
}
else{
while (++i !== len){
// checks to see if the key was set
if (i in this){
if (func.call(thisArg, t[i], i, t)){
res[c++] = t[i];
}
}
}
}
res.length = c; // shrink down array to proper size
return res;
};
}
var ViewModel = function(seedWord1, seedWord2) {
var self = this;
var dict = {
A: '', E: '', I: '', O: '', U: '', H: '', W: '',
B: 1, F: 1, P: 1, V: 1,
C: 2, G: 2, J: 2, K: 2, Q: 2, S: 2, X: 2, Z: 2,
D: 3, T: 3,
L: 4,
M: 5, N: 5,
R: 6
};
var createWord = function(text) {
var word = {}
// track input
word.text = ko.observable(text);
// basics
word.upper = ko.computed(function() { return word.text().toUpperCase().split(''); }, self);
word.first = ko.computed(function() { return word.upper().slice(0,1); }, self);
word.chars = ko.computed(function() { return word.upper().slice(1); }, self);
// step pieces
word.step1 = ko.computed(function() {
return word.chars().map(function (el, i) {
return el.replace(/[AEIOUYHW]/gi,'');
})
}, self);
word.step2 = ko.computed(function() {
return word.chars().map(function (el, i) {
return ( dict[el] );
});
...