diff --git a/packages/algoliasearch-helper/src/SearchParameters/index.js b/packages/algoliasearch-helper/src/SearchParameters/index.js index cff47af3a7..33ca84a5c1 100644 --- a/packages/algoliasearch-helper/src/SearchParameters/index.js +++ b/packages/algoliasearch-helper/src/SearchParameters/index.js @@ -365,9 +365,16 @@ SearchParameters.prototype = { * @return {SearchParameters} */ addFacetRefinement : function addFacetRefinement( facet, value ) { + if( this.isRefined( facet, value ) ) { + return this; + } + return this.mutateMe( function( m ) { m.page = 0; - m.facetsRefinements[ facet ] = value; + if( !m.facetsRefinements[ facet ] ) { + m.facetsRefinements[ facet ] = []; + } + m.facetsRefinements[ facet ].push( value ); } ); }, /** @@ -403,15 +410,29 @@ SearchParameters.prototype = { } ); }, /** - * Remove a refinement set on facet. + * Remove a refinement set on facet. If a value is provided, it will clear the + * refinement for the given value, otherwise it will clear all the refinement + * values for the facetted attribute. * @method * @param {string} facet + * @param {string} value * @return {SearchParameters} */ - removeFacetRefinement : function removeFacetRefinement( facet ) { + removeFacetRefinement : function removeFacetRefinement( facet, value ) { return this.mutateMe( function( m ) { m.page = 0; - m._clearFacetRefinements( facet ); + if( value ) { + var idx = m.facetsRefinements[ facet ].indexOf( value ); + if( idx > -1 ) { + m.facetsRefinements[ facet ].splice( idx, 1 ); + if( m.facetsRefinements[ facet ].length === 0 ) { + delete m.facetsRefinements[ facet ]; + } + } + } + else { + m._clearFacetRefinements( facet ); + } } ); }, /** @@ -519,7 +540,7 @@ SearchParameters.prototype = { */ toggleFacetRefinement : function toggleFacetRefinement( facet, value ) { if( this.isFacetRefined( facet, value ) ) { - return this.removeFacetRefinement( facet ); + return this.removeFacetRefinement( facet, value ); } else { return this.addFacetRefinement( facet, value ); @@ -563,7 +584,8 @@ SearchParameters.prototype = { * @return {boolean} */ isFacetRefined : function isFacetRefined( facet, value ) { - return this.facetsRefinements[ facet ] === value; + return this.facetsRefinements[ facet ] && + this.facetsRefinements[ facet ].indexOf( value ) !== -1; }, /** * Returns true if the couple (facet, value) is excluded diff --git a/packages/algoliasearch-helper/src/algoliasearch.helper.js b/packages/algoliasearch-helper/src/algoliasearch.helper.js index cb7ac94d7f..aac13635f6 100644 --- a/packages/algoliasearch-helper/src/algoliasearch.helper.js +++ b/packages/algoliasearch-helper/src/algoliasearch.helper.js @@ -438,8 +438,10 @@ AlgoliaSearchHelper.prototype._hasDisjunctiveRefinements = function( facet ) { AlgoliaSearchHelper.prototype._getFacetFilters = function( facet ) { var facetFilters = []; - forEach( this.state.facetsRefinements, function( facetValue, facetName ) { - facetFilters.push( facetName + ":" + facetValue ); + forEach( this.state.facetsRefinements, function( facetValues, facetName ) { + forEach( facetValues, function( facetValue ) { + facetFilters.push( facetName + ":" + facetValue ); + } ); } ); forEach( this.state.facetsExcludes, function( facetValues, facetName ) { diff --git a/packages/algoliasearch-helper/test/spec/SearchParameters.getRefinedDisjunctiveFacets.js b/packages/algoliasearch-helper/test/spec/SearchParameters.getRefinedDisjunctiveFacets.js index 8702504dbd..dd1eb0658f 100644 --- a/packages/algoliasearch-helper/test/spec/SearchParameters.getRefinedDisjunctiveFacets.js +++ b/packages/algoliasearch-helper/test/spec/SearchParameters.getRefinedDisjunctiveFacets.js @@ -1,5 +1,4 @@ "use strict"; - var test = require( "tape" ); //var _ = require( "lodash" ); var SearchParameters = require( "../../src/SearchParameters" ); diff --git a/packages/algoliasearch-helper/test/spec/helper.clears.js b/packages/algoliasearch-helper/test/spec/helper.clears.js index 707272451b..c00685d79a 100644 --- a/packages/algoliasearch-helper/test/spec/helper.clears.js +++ b/packages/algoliasearch-helper/test/spec/helper.clears.js @@ -1,5 +1,4 @@ "use strict"; - var test = require( "tape" ), algoliasearchHelper = require( "../../index" ), isUndefined = require( "lodash/lang/isUndefined" ); @@ -25,7 +24,7 @@ var init = function init() { test( "Check that the state objects match how we test them", function( t ) { var helper = init(); - t.deepEqual( helper.state.facetsRefinements, { "facet1" : "0", "facet2" : "0" } ); + t.deepEqual( helper.state.facetsRefinements, { "facet1" : [ "0" ], "facet2" : [ "0" ] } ); t.deepEqual( helper.state.disjunctiveFacetsRefinements, { "disjunctiveFacet1" : [ "0" ], "disjunctiveFacet2" : [ "0" ] } ); t.deepEqual( helper.state.facetsExcludes, { "excluded1" : [ "0" ], "excluded2" : [ "0" ] } ); t.deepEqual( helper.state.numericRefinements, { "numeric1" : { ">=" : "0", "<" : "10" }, "numeric2" : { ">=" : 0, "<" : 10 } } ); @@ -37,7 +36,7 @@ test( "Clear with a name should work on every type and not remove others than ta var helper = init(); helper.clearRefinements( "facet1" ); - t.deepEqual( helper.state.facetsRefinements, { "facet2" : "0" } ); + t.deepEqual( helper.state.facetsRefinements, { "facet2" : [ "0" ] } ); helper.clearRefinements( "disjunctiveFacet1" ); t.deepEqual( helper.state.disjunctiveFacetsRefinements, { "disjunctiveFacet2" : [ "0" ] } ); @@ -57,7 +56,7 @@ test( "Clearing the same field from multiple elements should remove it everywher helper.addNumericRefinement( "facet1", ">=", "10" ).toggleExclude( "facet1", "value" ); - t.equal( helper.state.facetsRefinements.facet1, "0" ); + t.deepEqual( helper.state.facetsRefinements.facet1, [ "0" ] ); t.deepEqual( helper.state.numericRefinements.facet1, { ">=" : "10" } ); t.deepEqual( helper.state.facetsExcludes.facet1, [ "value" ] ); @@ -72,7 +71,7 @@ test( "Clearing the same field from multiple elements should remove it everywher test( "Clearing twice the same attribute should be not problem", function( t ) { var helper = init(); - t.equal( helper.state.facetsRefinements.facet1, "0" ); + t.deepEqual( helper.state.facetsRefinements.facet1, [ "0" ] ); helper.clearRefinements( "facet1" ); t.assert( isUndefined( helper.state.facetsRefinements.facet1 ) ); t.doesNotThrow( function() { diff --git a/packages/algoliasearch-helper/test/spec/helper.constructor.js b/packages/algoliasearch-helper/test/spec/helper.constructor.js index c8b94ae258..73069eccbb 100644 --- a/packages/algoliasearch-helper/test/spec/helper.constructor.js +++ b/packages/algoliasearch-helper/test/spec/helper.constructor.js @@ -1,3 +1,4 @@ +"use strict"; var test = require("tape"); var _ = require( "lodash" ); var sinon = require("sinon"); diff --git a/packages/algoliasearch-helper/test/spec/refinements.js b/packages/algoliasearch-helper/test/spec/refinements.js index aaf845438f..f15288508a 100644 --- a/packages/algoliasearch-helper/test/spec/refinements.js +++ b/packages/algoliasearch-helper/test/spec/refinements.js @@ -29,10 +29,9 @@ test( "Adding refinments should add an entry to the refinments attribute", funct var facetValue = "42"; t.ok( _.isEmpty( helper.state.facetsRefinements ), "should be empty at first" ); - helper.addRefine( facetName, "42" ); - t.ok( _.size( helper.state.facetsRefinements ) === 1 && - helper.state.facetsRefinements.facet1 === facetValue, - "when adding a refinment, should have one" ); + helper.addRefine( facetName, facetValue ); + t.ok( _.size( helper.state.facetsRefinements ) === 1, "when adding a refinment, should have one" ); + t.deepEqual( helper.state.facetsRefinements.facet1, [ facetValue ] ); helper.addRefine( facetName, facetValue ); t.ok( _.size( helper.state.facetsRefinements ) === 1, "when adding the same, should still be one" ); helper.removeRefine( facetName, facetValue ); diff --git a/packages/algoliasearch-helper/test/spec/search.js b/packages/algoliasearch-helper/test/spec/search.js index 6c65a5e83b..9231125ffd 100644 --- a/packages/algoliasearch-helper/test/spec/search.js +++ b/packages/algoliasearch-helper/test/spec/search.js @@ -1,5 +1,4 @@ "use strict"; - var test = require("tape"); var sinon = require("sinon"); var algoliaSearch = require( "algoliasearch" );