Skip to content

Instantly share code, notes, and snippets.

@whalesalad
Created October 11, 2010 18:19
Show Gist options
  • Select an option

  • Save whalesalad/620974 to your computer and use it in GitHub Desktop.

Select an option

Save whalesalad/620974 to your computer and use it in GitHub Desktop.
var SearchItem = function() {
var self = this,
args = arguments;
self.init.apply(self, args);
};
YY.SearchItem = SearchItem;
SearchItem.prototype = {
init: function(obj) {
var self = this;
// Loop the passed params, and make them that of the SearchItem object.
for (val in obj) {
this[val] = obj[val];
};
},
render: function() {
var self = this;
var content = Array(
'<span class="leftCap"></span>',
'<span class="name">'+self.n+'</span>',
'<span class="desc">'+self.d+'</span>',
'<span class="rightCap"></span>');
var li = $('<li/>').addClass('result'),
a = $('<a/>').attr('href', self.u).html(content.join(''));
a.appendTo(li);
li.bind('click', function(event) {
window.location = self.u;
});
self.button = a;
self.row = li;
return li;
},
select: function() {
var self = this;
self.row.addClass('selected');
},
unselect: function() {
var self = this;
self.row.removeClass('selected');
},
open: function() {
var self = this;
var iv = setInterval(function() {
if (self.row.hasClass('selected')) {
self.unselect();
} else {
self.select();
}
}, 80);
self.button.click();
}
};
var Searcher = function() {
var self = this,
args = arguments;
self.init.apply(self, args);
};
YY.Searcher = Searcher;
/*
Searcher class will manage the livesearch system.
Accepts as arguments:
- textbox, the box to use for searching the items
- items, the array of item objects to search
- field, the field of the item objects to match against
Each of the items in the list will be represented by a SearchItem object, which will contain the
values of the original item object, as well as all the methods necessary to manipulate it.
- things like, selecting an item, highlighting an item, showing an item, removing an item, blah
*/
Searcher.prototype = {
FADE_SPEED: 200,
NO_RESULTS: 'No results matched your search.',
init: function(textbox, items, field, container) {
// Bind to the textbox, and create some items.
var self = this;
self.textbox = $(textbox);
self.container = $(container);
self.results = $('#autoSearcherResults');
self.quick_items = $.map(items, function(item, i) {
return item[field]+'';
});
self.items = {};
for (var i=0; i < items.length; i++) {
var item = items[i],
key = item[field]+'';
self.items[key] = new SearchItem(item);
};
self.textbox.bind('keyup', function(event) {
var keycode = event.which,
input = $(this).val();
if (keycode in oc(40, 38, 13)) {
self.navigateEvent(keycode);
} else if (input.length && (input !== "")) {
self.searchEvent(input);
} else {
self.closeMenu();
}
});
self.textbox.bind('focus', function(event) {
var input = $(this).val();
if (input && (input !== "")) self.searchEvent(input);
});
self.textbox.bind('blur', function(event) {
self.closeMenu();
});
},
searchEvent: function(value) {
var self = this,
scores = [],
items = [];
$(self.quick_items).each(function(i) {
var score = this.score(value);
if (score > 0) { scores.push([score, i]); }
});
jQuery.each(scores.sort(function(a, b) { return b[0] - a[0]; }), function() {
items.push(self.quick_items[this[1]]);
});
self.setCurrentItems(items);
},
navigateEvent: function(keycode) {
var self = this;
switch (keycode) {
case 38: // Up Arrow
self.moveUp();
break;
case 40: // Down Arrow
self.moveDown();
break;
case 13: // Enter Key
self.openSelectedItem();
break;
default:
break;
}
},
// Deselect current item, and then select item above it (unless it's the first one)
moveUp: function() {
var self = this;
if (self.currently_selected === 0) { return; }
var current = self.current_items[self.currently_selected],
target = self.current_items[self.currently_selected-1];
current.unselect();
target.select();
self.currently_selected--;
},
// Deselect current item, and then select item below it (unless it's the last one)
moveDown: function() {
var self = this;
if (self.currently_selected == self.currently_selected.length-1) { return; }
var current = self.current_items[self.currently_selected],
target = self.current_items[self.currently_selected+1];
current.unselect();
target.select();
self.currently_selected++;
},
// Call the click event of the currently selected item
openSelectedItem: function() {
var self = this;
self.current_items[self.currently_selected].open();
self.closeMenu();
},
closeMenu: function() {
var self = this;
setTimeout(function() { self.container.fadeOut(self.FADE_SPEED); }, 400);
},
setCurrentItems: function(items) {
var self = this;
self.current_items = $.map(items, function(item, index) {
return self.items[item];
});
// Render the list with ze new itemz!
self.renderList();
},
renderList: function() {
var self = this;
self.results.empty();
self.rendered = $.map(self.current_items, function(item, index) {
return item.render();
});
if (self.rendered.length) {
$.each(self.rendered.splice(0, 10), function(index) {
self.results.append(this);
});
self.currently_selected = 0;
self.current_items[self.currently_selected].select();
} else {
self.results.append(self.showMessage(self.NO_RESULTS));
}
self.container.fadeIn(self.FADE_SPEED);
},
showMessage: function(message) {
var self = this;
return $('<li/>').addClass('message').text(message);
}
};
/*
** CREATE THE SEARCHER!
*/
// var searcher = new Searcher('#product_search', ARBESKO.products, 'm', '#autoSearcherContainer');
// window.searcher = searcher;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment