Skip to content

Instantly share code, notes, and snippets.

@vinniefranco
Created April 17, 2011 03:47
Show Gist options
  • Save vinniefranco/923736 to your computer and use it in GitHub Desktop.
Save vinniefranco/923736 to your computer and use it in GitHub Desktop.
SPA.extend("SearchableList", (function($) {
var my = {},
options = {
url: "/",
clearCallback: function() {},
clickCallback: function() {},
list: {},
guid: null,
itemTemplate: "",
name: "List"
},
query = null,
current_page = 1,
loader = null,
full_set = false,
clear_link = $("#clear-search").click(function(event) {
$(this).hide();
query = null; $.cookie("SLISTquery", null); search_field[0].reset();
options.list.html(""); my.getItems();
event.preventDefault();
}),
search_field = $("#list-search").submit(function(event) {
var form = $(this).serializeArray();
if (form[1].value === "") { return false; }
query = form[1].value; clear_link.show();
// Store the query for later use
$.cookie("SLISTquery", query);
// Set page 1, and get items.
current_page = 1; my.getItems();
event.preventDefault();
}),
pager = $(".inline-page").live("click", function(event) {
// Get the page we want to load.
current_page = this.href.match(/\#(\d+)/)[1];
$.cookie("SLISTpage", current_page);
my.getItems(); event.preventDefault();
});
function buildNotFound() {
options.list.empty();
options.meta.html("<p class='not-found'>No Results Found</p>");
}
function buildListItems(data, appending, callback) {
var items = ( _.isArray(data.items) )? data.items : [data.items],
total = items.length,
meta_data = data.meta,
list = options.list,
meta = options.meta,
content = (current_page === 1 && appending)? list.html("") : list;
if ( total > 0 ) {
_.each(items, function(item_data) {
var item = $("<li>", { "class": "list-item", "id": "list-item-"+item_data.item_id})
.html(_.template(options.itemTemplate, item_data))
.click(function(event) {
$.cookie("SLISTactive-list", this.id);
$(this).addClass('active').siblings().removeClass('active');
options.clickCallback(item_data);
event.preventDefault();
});
// Prepend or append list item.
(appending)? content.append(item) : content.prepend(item);
});
}
content.disableSelection();
if (appending) { meta.empty().html(meta_data); }
// Fire any callbacks
callback&&callback();
}
function getCache() {
query = $.cookie("SLISTquery");
current_page = $.cookie("SLISTpage");
// This was a refresh and we are not on page 1
// We'll need the full set from getItems
if (current_page > 1) { full_set = true; }
}
function setCache() {
if (query) { $.cookie('query', query); };
$.cookie('page', current_page);
}
function clearCache() {
$.cookie("SLISTquery", null); query = null;
$.cookie("SLISTpage", 1); current_page = 1;
}
my.getItems = function() {
// Build the data query
var d = {};
loader = loader || $("<div id='scroll-loader'/>").appendTo(options.list.parents(".ui-viewpane-outer"));
// Stack query into request data
if ( query !== null ) { d["query"] = query; }
d["page"] = current_page || 1;
// Let the backend know we need a full set returned
if (full_set) {
// false after this request
d["fullset"] = full_set;
full_set = false;
}
/*
TODO Put this in a utils class, it's not DRY.
*/
$.ajax({
url: options.url, data: d,
beforeSend: function() { loader.show(); },
complete: function() { loader.hide(); },
success: function(data) {
if (data.list.items) { buildListItems(data.list, true); }
else { buildNotFound(); return; }
setActiveItem();
}
});
setCache();
};
function clearActiveItem() {
$(".list-item").removeClass("active");
}
function setActiveItem() {
if (options.guid && options.guid[0]) {
clearActiveItem();
$("#list-item-"+options.guid[0]).addClass("active");
}
}
// Used for adding in new list items
my.prependItem = function(item) {
// Add the new post
buildListItems({items:[item]}, false, function() {
$("#list-item-"+item.item_id).effect("highlight", 500, function() {
$(this).effect("highlight", 500);
});
});
};
my.updateItem = function(item) {
var list_item = $("#list-item-"+item.item_id);
list_item
.html(_.template(options.itemTemplate, item))
.effect("highlight", 500);
};
my.deleteItem = function(item_id) {
clearCache();
$("#list-item-"+item_id).fadeOut(200, function() {
$(this).fadeOut();
});
};
my.setup = function(setup_opts) {
var frag = Dispatcher.getFragment(),
list_path = $.cookie("SLISTpath");
options.guid = frag.match(/(\d+)/);
_.each(setup_opts, function(method,key) {
options[key] = method;
});
// New section clear any cache and reset section.
if (list_path !== location.pathname) { clearCache(); $.cookie("SLISTpath", location.pathname); }
// Otherwise load cache
else { getCache(); }
// Refresh from a search show clear_link
if ( search_field.find("#search").val() ) { clear_link.show(); }
my.getItems();
$(window).bind("hashchange", function() {
var frag = Dispatcher.getFragment();
options.guid = frag.match(/(\d+)/);
if (frag === "/") {
document.title = options.name+"s - ground(ctrl)";
clearActiveItem(); options.clearCallback();
} else if (frag === "/new") {
document.title = "New "+options.name+" - ground(ctrl)";
}
if ( options.guid ) { setActiveItem(); }
});
};
return my;
})(jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment