Browse Source

[search] Toggle facet order and type

Romain Rigaux 11 years ago
parent
commit
3f05860

+ 15 - 2
apps/search/src/search/models.py

@@ -466,6 +466,14 @@ def augment_solr_response2(response, collection, solr_query):
         pairs.append({'cat': cat, 'value': element, 'count': next(a), 'selected': element == selected_field})
       return pairs
 
+  def reversepairs(iterable):
+      pairs = []
+      a, b = itertools.tee(iterable)
+      for element in a:
+        pairs.insert(0, next(a))
+        pairs.insert(0, element)
+      return pairs
+
   fq = solr_query['fq']
 
   if response and response.get('facet_counts'):
@@ -477,12 +485,15 @@ def augment_solr_response2(response, collection, solr_query):
         for name in response['facet_counts']['facet_fields']: # todo get from the list
           selected_field = fq.get(name, '') # todo with multi filter
           collection_facet = get_facet_field(category, name, collection['facets'])
+          counts = pairwise2(name, selected_field, response['facet_counts']['facet_fields'][name])
+          if collection_facet['properties']['sort'] == 'asc':
+            counts.reverse()          
           facet = {
             'id': collection_facet['id'],
             'field': name,
             'type': category,
             'label': collection_facet['label'],
-            'counts': pairwise2(name, selected_field, response['facet_counts']['facet_fields'][name]),
+            'counts': counts,
             # add total result count?
           }
           normalized_facets.append(facet)
@@ -490,9 +501,11 @@ def augment_solr_response2(response, collection, solr_query):
           name = facet['field']
           collection_facet = get_facet_field(category, name, collection['facets'])
           counts = response['facet_counts']['facet_ranges'][name]['counts']
+          if collection_facet['properties']['sort'] == 'asc':
+            counts = reversepairs(counts) 
           if facet['widgetType'] == 'facet-widget':
             selected_field = fq.get(name, '') # todo with multi filter
-            counts = pairwise2(name, selected_field, counts)
+            counts = pairwise2(name, selected_field, counts)          
           facet = {
             'id': collection_facet['id'],
             'field': name,

+ 6 - 5
apps/search/src/search/templates/search2.mako

@@ -335,13 +335,14 @@ ${ commonheader(_('Search'), "search", user, "60px") | n,unicode }
       ${ _('Label') }: <input type="text" data-bind="value: label" />
       ${ _('Field') }: <input type="text" data-bind="value: field" />
       <br/>
-      ${ _('Range') }: <input type="checkbox" data-bind="checked: isRange" />
-      <a href="javascript: void(0)" class="btn"><i class="fa fa-sort-alpha-asc"></i></a>
-      <a href="javascript: void(0)" class="btn"><i class="fa fa-sort-numeric-asc"></i></a>
-      <a href="javascript: void(0)" class="btn"><i class="fa fa-sort-numeric-desc"></i></a>
+      <span>
+        <span data-bind="text: label" style="font-weight: bold"></span>
+        <a href="javascript: void(0)" class="btn btn-loading" data-bind="click: $root.collection.toggleFacet" data-loading-text="...">      
+          <i class="fa" data-bind="css: { 'fa-sort-alpha-asc': properties.sort() == 'desc' && type() != 'range', 'fa-sort-alpha-desc': properties.sort() == 'asc' && type() != 'range', 'fa-sort-numeric-desc': properties.sort() == 'desc' && type() == 'range', 'fa-sort-numeric-asc': properties.sort() == 'asc' && type() == 'range' }"></i>
+        </a>  
+      </span>
     </div>  
 
-    <div data-bind="text: label" style="font-weight: bold"></div>
     <div data-bind="foreach: counts">
       <div>
         <a href="script:void(0)">

+ 7 - 4
apps/search/src/search/views.py

@@ -484,7 +484,10 @@ def new_facet(request, collection_id):
     facet_label = request.POST['label']
     facet_field = request.POST['field']
     widget_type = request.POST['widget_type']
-    properties = {}
+    properties = {
+      'sort': 'desc',
+      'canRange': False,
+    }
     is_range = False
 
     try:
@@ -524,11 +527,12 @@ def new_facet(request, collection_id):
                 
     if is_range:
       facet_type = 'range'
-      properties = {
+      properties.update({
         'start': stats_min,
         'end': stats_max,
         'gap': gap,
-      }       
+        'canRange': True,
+      })       
 #    elif widget_type == 'hit-widget':
 #      facet_type = 'query'
 #    elif widget_type == 'histogram-widget':
@@ -547,7 +551,6 @@ def new_facet(request, collection_id):
       'field': facet_field,
       'type': facet_type,
       'widgetType': widget_type,
-      'isRange': is_range,
       'properties': properties
     }
     result['status'] = 0

+ 50 - 32
apps/search/static/js/search.ko.js

@@ -238,22 +238,19 @@ var Collection = function (vm, collection) {
 
   self.addFacet = function (facet_json) {
     $.post("/search/template/" + self.id + "/new_facet", {
-    	"collection": ko.mapping.toJSON(self),
+      "collection": ko.mapping.toJSON(self),
         "id": facet_json.widget_id,
         "label": facet_json.name,
         "field": facet_json.name,
         "widget_type": facet_json.widgetType
       }, function (data) {
         if (data.status == 0) {
-	      var facet = ko.mapping.fromJS(data.facet);
-	      facet.field.subscribe(function () {
-	        vm.search();
-	      });
-	      facet.isRange.subscribe(function () {
-	        vm.search();
-	      });	    
-	      self.facets.push(facet);
-	      vm.search();
+        var facet = ko.mapping.fromJS(data.facet);
+        facet.field.subscribe(function () {
+          vm.search();
+        });      
+        self.facets.push(facet);
+        vm.search();
         } else {
           $(document).trigger("error", data.message);
         }
@@ -261,7 +258,7 @@ var Collection = function (vm, collection) {
   };
 
   self.removeFacet = function (widget_id) {
-    $.each(self.facets(), function (index, facet) {	
+    $.each(self.facets(), function (index, facet) {  
       if (facet.id() == widget_id()) {
         self.facets.remove(facet); 
         return false;
@@ -285,7 +282,7 @@ var Collection = function (vm, collection) {
     $.each(self.template.fieldsAttributes(), function (index, field) {
       var position = self.template.fieldsSelected.indexOf(field.name());
       if (position != -1) {
-    	_fields[position] = field;
+      _fields[position] = field;
       }      
     });
     return _fields;
@@ -305,15 +302,34 @@ var Collection = function (vm, collection) {
   }
 
   self.toggleSortColumnGridLayout = function (template_field) {
-	 if (! template_field.sort.direction()) {
-	   template_field.sort.direction('desc');
-	 } else if (template_field.sort.direction() == 'desc') {
-	   template_field.sort.direction('asc');
-	 } else {
-	   template_field.sort.direction(null); 
-	 }
-
-	 vm.search();
+   if (! template_field.sort.direction()) {
+     template_field.sort.direction('desc');
+   } else if (template_field.sort.direction() == 'desc') {
+     template_field.sort.direction('asc');
+   } else {
+     template_field.sort.direction(null); 
+   }
+
+   vm.search();
+  };
+  
+  self.toggleFacet = function (facet_field, event) {	
+    if (facet_field.properties.canRange()) {
+	   if (facet_field.type() == 'field' && facet_field.properties.sort() == 'desc') {
+		 facet_field.type('range');
+	   } else if (facet_field.type() == 'range' && facet_field.properties.sort() == 'desc') {
+	     facet_field.type('field'); 
+       }
+    }
+   
+    if (facet_field.properties.sort() == 'desc') {
+      facet_field.properties.sort('asc');
+    } else {
+      facet_field.properties.sort('desc');
+    }   
+   
+    $(event.target).button('loading');
+    vm.search();
   };
 };
 
@@ -331,16 +347,16 @@ var SearchViewModel = function (collection_json, query_json) {
   self.norm_facets = ko.computed(function () {
     return self.response().normalized_facets;
   });
-  self.getFacetFromQuery = function (facet_id) {	
+  self.getFacetFromQuery = function (facet_id) {  
     var _facet = null;
     if (self.norm_facets() !== undefined) {
-	  $.each(self.norm_facets(), function (index, norm_facet) {  
-	    if (norm_facet.id == facet_id()) {
-	      _facet = norm_facet;
-	    }      
-	  });
+      $.each(self.norm_facets(), function (index, norm_facet) {  
+        if (norm_facet.id == facet_id()) {
+          _facet = norm_facet;
+        }      
+      });
     }
-    return _facet;	  
+    return _facet;    
   };
 
   self.previewColumns = ko.observable("");
@@ -363,10 +379,10 @@ var SearchViewModel = function (collection_json, query_json) {
   self.draggablePie = ko.observable(new Widget(12, UUID(), "Pie Chart", "pie-widget"));
 
   self.init = function () {
-	//self.collection.addDynamicFields();
+  //self.collection.addDynamicFields();
 
-	self.isEditing(true);
-	self.search();	
+  self.isEditing(true);
+  self.search();  
   }
 
   self.search = function () {
@@ -411,6 +427,8 @@ var SearchViewModel = function (collection_json, query_json) {
       }
     }).fail(function (xhr, textStatus, errorThrown) {
       $(document).trigger("error", xhr.responseText);
+    }).always(function () {
+      $('.btn-loading').button('reset');
     });
   };
   
@@ -425,7 +443,7 @@ var SearchViewModel = function (collection_json, query_json) {
       layout: ko.mapping.toJSON(self.columns)
     },function (data) {
       if (data.status == 0) {
-    	self.collection.id = data.id;
+        self.collection.id = data.id;
         $(document).trigger("info", data.message);
       }
       else {