filterJSON expects an array of items in the JSON result whereas Flickr provides an single parent object in the result which contains an array of items inside the 'items' property of that parent object.
This is an inherent limitation in filterJSON that you cannot fix without modifying the plugin itself as follows:
24a27
> itemsLocation: null,
39a43,49
> if (options.itemsLocation && $.isArray(options.itemsLocation)) {
> // extract the items from the object hierarchy
> $.each(options.itemsLocation, function () {
> r = r[this];
> });
> }
>
You can then specify an array of property names (e.g. itemsLocation: ['items']
for the Flickr result) to extract the items that you want filterJSON to work with.
Working Demo
http://jsbin.com/enudu3 (editable via http://jsbin.com/enudu3)
Full Source
https://gist.github.com/290420
/*
* filterJSON v.9.1 - http://www.jeffrey-way.com
* Last Updated: January 29, 2009
* When you attach a JSON file, it will parse it with getJSON, and then allow you to filter through and display the items on the page according to
* a specified limit, delay, transition, etc.
* Developed by Jeffrey Way
* http://jeffrey-way.com/filterjson-a-jquery-plugin/
* [email protected]
* Modified by Brian Peiris
* http://twitter.com/brianpeiris
*/
(function($) {
$.fn.filterJson = function(options) {
var defaults = {
anchorWrap : '<p>',
complete : null,
data : null,
delay : 500,
limit : 5,
index : 0,
transition : 'fade',
itemsLocation: null,
nextId : 'next',
nextText : 'More',
prevId : 'prev',
prevText : 'Last'
},
options = $.extend(defaults, options);
this.each(function() {
var $this = $(this);
$.getJSON(options.data, function(r) {
if (options.itemsLocation && $.isArray(options.itemsLocation)) {
// extract the items from the object hierarchy
$.each(options.itemsLocation, function () {
r = r[this];
});
}
// add the NEXT button
$this
.after(options.anchorWrap)
.next()
.append('<a></a>')
.children()
.attr('href', '#')
.attr('id', options.nextId)
.text(options.nextText);
// Get first set of items
options.index = getItems(r);
// when the user clicks the NEXT button
$('a#' + options.nextId).live('click', function() {
// If a previous button doesn't exist, create it!
if($('a#' + options.prevId).length == 0) {
$this
.after(options.anchorWrap)
.next().append('<a></a>')
.children()
.attr('href', '#')
.attr('id', options.prevId)
.text(options.prevText);
}
// If the user chose the "slide" transition, slideUp...otherwise fadeOut.
if(options.transition === 'slide') $this.slideUp(options.delay, emptyAndContinue);
else $this.fadeOut(options.delay, emptyAndContinue);
// remove the current items and get the next set, passing in the json file - represented by "r"
function emptyAndContinue() {
$this.empty();
options.index = getItems(r);
}
return false;
}); // end nextId click
// When the previous button is clicked, add the NEXT button if one doesn't exist.
$('a#' + options.prevId).live('click', function() {
if($('a#' + options.nextId).length == 0) {
$this
.after(options.anchorWrap)
.next().append('<a>')
.children()
.attr('href', '#')
.attr('id', options.nextId)
.text(options.nextText);
}
// If the user chose the "slide" transition, slide up...oitherwise fadeOut
if(options.transition === 'slide') $this.slideUp(options.delay, emptyAndContinue);
else $this.fadeOut(options.delay, emptyAndContinue);
// remove the current items and get the next set, passing in the json file - represented by "r"
function emptyAndContinue() {
$this.empty();
options.index = getPreviousItems(r);
}
return false;
});
return this;
}); // end getJSON
// Acccepts the parsed JSON file as a parameter "r", and then gets the next set of items.
function getItems(r) {
var i = options.index, // the current index, or offset.
dataLength = r.length; // total # objects in the JSON file.
(function append() {
if(i === dataLength) {$('a#' + options.nextId).remove(); return; } // if the index is equal to total # of items in JSON file, remove the "next" link and exit.
if(i >= options.limit + options.index) return; // if index is gte to the current index + the limit, return because reached the max.
options.complete(i, r); // call userdefined "complete" function, which appends necessary html to the page.
// If the user chose the "slide" transition, slide up...oitherwise fadeOut
if(options.transition === 'slide') $this.slideDown(options.delay);
else $this.fadeIn(options.delay);
i++;
append(); // Rinse and repeat until i equals the limit
})();
// Increase INDEX by current offset to allow for the next grouping.
return options.index + options.limit;
} /// end getItems
// Used when the PREVIOUS BUTTON is clicked.
function getPreviousItems(r) {
// Need to reduce the current options.index back to what it would have been on the previous page. A bit confusing...
var i = options.index - options.limit * 2;
(function append() { // if the user has chosen to delay the appearance of each new image...
if(i === 0) $('a#' + options.prevId).remove(); // If i = 0, we don't need a previous button.
if(i >= options.index - options.limit) return;
options.complete(i, r); // call userdefined "complete" function, which appends necessary html to the page.
if(options.transition === 'slide') $this.slideDown(options.delay);
else $this.fadeIn(options.delay);
i++;
append(); // Rinse and repeat until i equals the specified options.limit.
})();
// REDUCE index by the limit, because "PREVIOUS BUTTON" was clicked
return options.index - options.limit;
} /// end getPreviousItems
}); // end this.each
}; // end plugin. Go eat some cake.
})(jQuery);