Skip to content

Instantly share code, notes, and snippets.

@timkinnane
Created June 24, 2015 13:59
Show Gist options
  • Save timkinnane/9dffd9ed956469ed5968 to your computer and use it in GitHub Desktop.
Save timkinnane/9dffd9ed956469ed5968 to your computer and use it in GitHub Desktop.
Email auto-suggest (by Stuart Taylor) http://codepen.io/stuarttayler/pen/NPdXrq
<div id="wrapper">
<header class="group">
<h1>Email auto-suggest</h1>
<p id="author" class="group">By Stuart Tayler</p>
<a href="https://twitter.com/share" class="twitter-share-button" data-via="stuarttayler1" data-count="none">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
</header>
<p>Email address</p>
<div id="placement">
<input autocomplete="off" type="email" id="email" />
<ul id="auto-list" style="display:none;" >
</ul>
</div>
$(document).ready(function () {
$("#email").autoEmail(["aol.com", "facebook.com", "gmail.com", "googlemail.com",
"google.com", "hotmail.com", "hotmail.co.uk", "mac.com", "me.com", "mail.com", "msn.com",
"live.com", "yahoo.com", "yahoo.co.uk"]);
});
(function ($) {
$.fn.autoEmail = function (domains) {
return this.each(function () {
var $this = $(this);
function addListeners() {
var $results = $("#auto-list > li");
$results.first().addClass("highlighted");
$results.css("cursor","pointer")
$results.click(function() {
$this.val($(this).text());
$this.focus();
$("#auto-list").hide();
});
$results.mouseenter(
function() {
$(this).addClass("highlighted");
$(this).siblings().removeClass("highlighted");
});
$( "#auto-list" ).show();
}
// check for autocomplete after each key
$this.keyup(function (e) {
if (e.keyCode == 40 || e.keyCode == 38) { // if user clicks down or up arrow
var $newHighlight;
if (e.keyCode == 40){ // down arrow
$newHighlight = $(".highlighted").next();
} else if (e.keyCode == 38) { // up arrow
// e.preventDefault(); // doesn't work cos a key up event
$newHighlight = $(".highlighted").prev();
}
$newHighlight.addClass("highlighted");
$newHighlight.siblings().removeClass("highlighted");
} else if (e.keyCode == 13) { // if user clicks enter
var $selected = $(".highlighted");
$this.val($selected.text());
$("#auto-list").hide();
} else {
var exactMatches = [];
var errorMatches = [];
$("#auto-list").empty();
$( "#auto-list" ).hide();
// get substring to try appending with autocomplete email
var emailsDirty = $(this).val().split("@");
if (emailsDirty.length < 2 || emailsDirty[0] == "") {
return;
}
var emailDomain = emailsDirty[1];//get the text after @
if (emailDomain.length === 0) {
exactMatches.push(domains[1],domains[2],domains[5],domains[6],domains[12]);
} else {
for (i = 0; i < domains.length; i++){
var testString = domains[i].substr(0, emailDomain.length);
if (emailDomain === testString) {
exactMatches.push(domains[i]);
} else if (getEditDistance(emailDomain,testString) < 2 && emailDomain.length > 1) {
errorMatches.push(domains[i]);
}
}
}
if (exactMatches.length > 0) {
for(i = 0; i < exactMatches.length; i++ ) {
// take first domain match for autocomplete
var subStr = exactMatches[i].substr(emailDomain.length, exactMatches[i].length);
// insert exact match into list
$( "#auto-list" ).append("<li>"+ $this.val() + "<b>" + subStr + "</b></li>");
}
addListeners();
} else if (errorMatches.length > 0) {
for(i = 0; i < errorMatches.length; i++ ) {
// take first domain match for autocomplete
var subStr = errorMatches[i].substr(emailDomain.length, errorMatches[i].length);
// insert error corrected match into list
$( "#auto-list" ).append("<li>"+ emailsDirty[0] + "@<b>" + errorMatches[i] + "</b></li>");
}
addListeners();
}
} // end of else statement
}); // end of keyup event
});
};
})(jQuery);
// Compute the edit distance between the two given strings
function getEditDistance(a, b) {
if(a.length === 0) return b.length;
if(b.length === 0) return a.length;
var matrix = [];
// increment along the first column of each row
var i;
for(i = 0; i <= b.length; i++){
matrix[i] = [i];
}
// increment each column in the first row
var j;
for(j = 0; j <= a.length; j++){
matrix[0][j] = j;
}
// Fill in the rest of the matrix
for(i = 1; i <= b.length; i++){
for(j = 1; j <= a.length; j++){
if(b.charAt(i-1) == a.charAt(j-1)){
matrix[i][j] = matrix[i-1][j-1];
} else {
matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
Math.min(matrix[i][j-1] + 1, // insertion
matrix[i-1][j] + 1)); // deletion
}
}
}
return matrix[b.length][a.length];
};
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
/*font: inherit;*/
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
* {
box-sizing: border-box;
}
.group:after {
content: "";
display: table;
clear: both;
}
#wrapper {
width: 90%;
max-width: 350px;
margin: 0 auto;
}
#wrapper, #email {
font-size: 16px;
line-height: 40px;
font-family: "franklin-gothic-urw";
color: #333333;
}
header {
margin-bottom: 40px;
border-bottom: 1px solid #D9D9D9;
}
h1 {
font-family: "franklin-gothic-urw";
font-weight: bold;
font-size: 28px;
line-height: 40px;
display: block;
margin-top: 20px;
}
#author {
font-size: 12px;
float: left;
color: #808080;
line-height: 40px;
}
.twitter-share-button {
margin-top: 10px;
float: right;
}
#email {
-webkit-appearance: none;
border: 1px solid #D9D9D9;
border-radius: 0;
box-shadow: inset 0px 2px 0px 0px rgba(0,0,0,0.05);
height: 40px;
padding: 0 10px;
background: white;
width: 100%;
}
#email:focus {
outline: none;
background: #EDF6FA;
}
#placement {
position: relative;
}
ul {
background: #FFFFFF;
border: 1px solid #D9D9D9;
box-shadow: 0px 2px 0px 0px rgba(0,0,0,0.05);
margin-top: -1px;
position: absolute;
top: 40px;
left: 0;
width: 100%;
}
li {
padding: 0 10px;
}
.highlighted {
background-color: #F0F0F0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment