Skip to content

Commit

Permalink
facets renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
Leandro Oniszczuk committed Aug 12, 2011
1 parent 5ea3424 commit 8d17ec2
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 85 deletions.
29 changes: 29 additions & 0 deletions facets.html
@@ -0,0 +1,29 @@
<html>
<head>
<!-- Dependencies -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script type="text/javascript" src="querybuilder.js"></script>
<script type="text/javascript" src="jquery.indextank.ize.js"></script>
<script type="text/javascript" src="jquery.indextank.ajaxsearch.js"></script>
<script type="text/javascript" src="jquery.indextank.facetsrenderer.js"></script>

<link type="text/css" rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/south-street/jquery-ui.css" media="all" />

<script>
$(document).ready(function(){
$("#myform").indextank_Ize(YOUR_PUBLIC_API_URL, YOUR_INDEX_NAME);
$("#facets").indextank_FacetsRenderer();
$("#query").indextank_AjaxSearch( {listeners: $("#facets")});
});
</script>
</head>

<body>
<h3>Type, hit enter and see facets rendered by jquery.indextank.facetsrenderer.js</h3>
<form id="myform" action="ignored.html">
<input id="query" type="text"/>
</form>
<div id="facets"></div>
</body>
</html>
188 changes: 103 additions & 85 deletions jquery.indextank.facetsrenderer.js
Expand Up @@ -18,103 +18,121 @@
base.init = function(){
base.options = $.extend({},$.Indextank.FacetsRenderer.defaultOptions, options);


base.$el.bind( "Indextank.AjaxSearch.success", function (event, data) {
base.$el.show();
base.$el.html("");

var stats = base.options.format(data);
stats.appendTo(base.$el);
var queriedFacets = data.query.categoryFilters || {};

var $selectedFacetsContainer = $("<ul/>").attr("id", "indextank-selected-facets");
var $availableFacetsContainer = $("<div/>").attr("id", "indextank-available-facets");

$.each( data.facets, function (catName, values){
if (catName in queriedFacets) {
var $selectedFacet = base.renderSelectedFacet(queriedFacets, catName, data);
$selectedFacetsContainer.append($selectedFacet);
} else {
var $availableFacet = base.renderAvailableFacet(queriedFacets, catName, values, data);
$availableFacetsContainer.append($availableFacet);
}
});

var $facetsContent = $("<div/>").append($selectedFacetsContainer, $availableFacetsContainer);
var $facetsTitle = $("<h3/>").text("Filters");

base.$el.append($facetsTitle, $facetsContent);

});
};


// Run initializer
base.init();
};

$.Indextank.FacetsRenderer.defaultOptions = {
format: function (data) {
base.renderSelectedFacet = function(queriedFacets, categoryName, data) {
// Render selected facet as a <li/> and return it
$item = $("<li/>");

var queriedFacets = data.query.categoryFilters || {};

var r = $("<div/>");




$.each( data.facets, function (catName, values){
$cat = $("<div/>").addClass("facets-container").addClass("ui-widget-content").text(catName);
$list = $("<ul/>");
$cat.append($list);
r.append($cat);


// find out if we should collapse facets, or not
sorted = []
$extraFacets = $();
$.each(values, function( ignored, count) { sorted.push(count);});

if (sorted.length > 4 ) {
$more = $("<div/>").addClass("more");
$btn = $("<span/>").text("more " + catName + " options").button().data("mymore",$more);

$extraFacets = $("<ul/>");
$more.append($extraFacets);

$btn.click(function(event) {
// need to call parents here, as 'button' messes up objects.
$(event.target).parents().data("mymore").dialog("open");
} );

$selectedCategory = $("<span/>").append(
$("<a/>").attr("href","#")
.append($("<span/>").text(categoryName + " - " + queriedFacets[categoryName]))
.click(function(){
// ensure query data has something on it
var query = data.query.clone();
query.withoutCategories([categoryName]);
// start over!
query.withStart(0);
data.searcher.trigger("Indextank.AjaxSearch.runQuery", [query]);
})
);

$item.append($selectedCategory);

return $item;
}

$cat.append($btn);
$cat.append($more);
sorted = sorted.sort( function(a,b) { return b-a;});

$more.dialog({autoOpen:false});
base.renderAvailableFacet = function(queriedFacets, categoryName, categoryValues, data) {
// Render available facet as a <dl> (definition list) and return it

$facetContainer = $("<div/>");
$availableFacet = $("<dl/>");
$facetContainer.append($availableFacet);
$availableFacet.append($("<dt/>").text(categoryName));

// find out if we should collapse facets, or not
var sorted = [];
var categoriesCount = 0;
$.each(categoryValues, function( categoryValue, count) { categoriesCount += 1; sorted.push([categoryValue, count])});
sorted.sort(function(a,b){return b[1]-a[1];});
$extraValues = $();

if (categoriesCount > base.options.showableFacets) {
$more = $("<div/>").addClass("indextank-more-facets").hide();
$btn = $("<a/>").attr("href", "#").text("more " + categoryName + " options");

$extraValues = $("<dl/>");
$more.append($extraValues);

$btn.click(function(event) {
// need to call parents here, as 'button' messes up objects.
$(event.target).parents().children(".indextank-more-facets").toggle();
} );

$facetContainer.append($btn);
$facetContainer.append($more);
}

// for this category, render all the controls
$.each(sorted, function (idx, categoryCount) {
var categoryValue = categoryCount[0];
var count = categoryCount[1];
var dd = $("<dd/>").append(
$("<a/>")
.attr("href", "#")
.text(categoryValue + " (" + count + ")")
.click(function(){
// ensure query data has something on it
var query = data.query.clone();
filter = {};
filter[categoryName] = categoryValue;
query.withCategoryFilters(filter);
// start over!
query.withStart(0);
data.searcher.trigger("Indextank.AjaxSearch.runQuery", [query]);
})
);

if (idx < base.options.showableFacets) {
$availableFacet.append(dd);
} else {
$extraValues.append(dd);
}

threshold = sorted.length > 4 ? sorted[4] : 0;

// for this category, render all the controls
$.each(values, function (catValue, count) {
var li = $("<li/>").text(catValue + " (" + count + ")");
if (queriedFacets[catName] == catValue) {
li.addClass("ui-selected");
}


li.data("Indextank.FacetsRenderer.catValue", catValue);
li.data("Indextank.FacetsRenderer.catName", catName);
li.data("Indextank.FacetsRenderer.searcher", data.searcher);

if (count >= threshold ) {
$list.append(li);
} else {
$extraFacets.append(li);
}
});
});
return $facetContainer;
}

// Run initializer
base.init();
};

$("li", $list).add( $("li", $extraFacets)).selectable( {
stop: function(event, ui) {

// ensure query data has something on it
var query = data.query.clone();
filter = {};
filter[catName] = $(this).data("Indextank.FacetsRenderer.catValue");
query.withCategoryFilters(filter);
// start over!
query.withStart(0);
data.searcher.trigger("Indextank.AjaxSearch.runQuery", [query]);

}

} );
});
return r;
}
$.Indextank.FacetsRenderer.defaultOptions = {
showableFacets: 4,
};

$.fn.indextank_FacetsRenderer = function(options){
Expand Down
12 changes: 12 additions & 0 deletions querybuilder.js
Expand Up @@ -82,6 +82,18 @@ Query.prototype.withCategoryFilters = function (categoryFilters) {
return this;
};

Query.prototype.withoutCategories = function (categories) {
if (this.categoryFilters == null) {
this.categoryFilters = {};
} else {
for (idx in categories) {
delete this.categoryFilters[categories[idx]];
}
}

return this;
};

Query.prototype.withQueryVariables = function (queryVariables) {
if (this.queryVariables == null) {
this.queryVariables = {};
Expand Down

0 comments on commit 8d17ec2

Please sign in to comment.