SFDC Lookup
by Dan Shahin
HTML
<script src="https://code.jquery.com/jquery-2.2.0.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<div class="container">
<i class="fa fa-search fa-lg search-icon"></i>
<label for="testInput" class="typeahead">super lookup</label>
<input id="testInput" class="typeahead" type="text" />
<pre id="debug"></pre>
</div>
<script id="item-template" type="text/x-handlebars-template">
<li id={{id}}>
<i class="fa fa-{{icon}}"></i>
<span class="data">{{name}}</span>
<br/>
Type: {{type}} <br/>
Icon: {{icon}}
</li>
</script>
CSS
div.container {
font-family: arial;
}
label.typeahead{
display: block;
}
input.typeahead{
width: 400px;
height: 30px;
font-size: 24px;
background-color : white;
}
i.search-icon{
position:absolute;
top:35px;
left:380px;
color:gray;
}
i.search-icon.success{
color:lightgreen;
}
i.search-icon.fail{
color:red;
}
ul.typeahead{
position: absolute;
top : 47px;
left : 8px;
padding : 0px;
width: 406px;
}
ul.typeahead>li{
border : 1px solid lightgray;
padding: 2px;
background-color: white;
font-size: 24px;
}
ul.typeahead>li.template{
display:none;
}
ul.typeahead>li.selectable:hover{
background-color: lightyellow;
cursor: pointer;
}
ul.typeahead>li.selectable.focused{
background-color: lightyellow;
cursor: pointer;
}
JavaScript
(function($) {
$.fn.lookup = function(options) {
// Plugin defaults – added as a property on our plugin function.
$.fn.lookup.defaults = {
placeholder: "typeahead...",
//jsr method
remoteAction: '',
data: [],
skipFields: ['id'],
minMatchLength: 1,
debug: false,
//default template
templateSource : '<li id={{id}}>{{name}}</li>'
};
var opts = $.extend({}, $.fn.lookup.defaults, options);
var $input = $(this), //the original plain text input
$parent = $input.parent(),
selectedIndex = -1,
optionMap = {},
templateSource,
template;
if(opts.templateId){
templateSource = $("#"+options.templateId).html();
}else{
templateSource = opts.templateSource;
}
template = Handlebars.compile(templateSource);
$clone = $input.clone();// the new typeahead input
$clone.removeAttr('id')
.attr({
'placeholder': opts.placeholder
})
.insertAfter($input.hide());
var html = '<ul class="typeahead"></ul>';
$(html).insertAfter($clone);
var size = opts.data.length;
var selectedIndex = 0;
$('i.search-')
$.each( opts.data, function( index, obj ){
optionMap[obj.id] =obj;
var newLi = template(obj);
var $newLi = $('ul.typeahead>li').first().clone()
.removeClass('template')
.attr('id',obj.id) //set id of li to object id
.hide();
$newLi.children('span.data').html(obj.name);
$('ul.typeahead').append(newLi);
});
$('ul.typeahead>li').hide();
$clone.keyup(function(event){
hideAllOptions();
var $lookup = $(this),
query = $lookup.val(),
key = event.keyCode;
if(query === ''){
$('ul.typeahead>li').hide();
reset();
return;
}
debug(query,event);
//up arrow
if(key === 38 ){
...