FYI: Currently in sandbox, but soon to be a module
http://drupal.org/sandbox/alex-ter/1286062

Unlike this module (I think a better name for it is actually search API slider) -- it allows admin to create ranges. For example in a field price you can have factes saying:
Price
* 100 and below
* 100 - 1000
* 1000 and up

Comments

Anonymous’s picture

Category: task » feature

Unlike this module (I think a better name for it is actually search API slider)

We recently moved to Facet API, @see #1213360: Move to Facet API. Now the slider is just a widget for the ranges. It's easier to add another widget for your feature, easier than a new module.

Anonymous’s picture

Title: Similar module -- Search API range » Add widget for text range links (0-100,100-200,200 and up)

Changed title for this feature request.

amitaibu’s picture

Ok, I'll have to learn the code. Unless you have plans to do that :)

Anonymous’s picture

I can make a start, and then you can give suggestions.

amitaibu’s picture

Sounds good

jordiserra’s picture

I am very interested in that module/widget, do you know when it will be ready?? THANKS!

mrfelton’s picture

Going to put some time into this this week - has anyone already started work on porting Amitaibu's module to facet api? If so, can you make a patch for what you have so far?

Anonymous’s picture

Hi, if you want to work on this, easiest is to check out search_api_ranges module /plugins/facetapi/widget_links.inc
You can copy class SearchApiRangesWidgetUISlider and start from there. It should be relatively easy to do. All it needs is some grouping logic, either based on absolute min/max queries, or relative to the active filters (in which case you can re-use the _buildUISliderForm logic to get your min/max values).

You would add your widget in search_api_ranges_facetapi_widgets() and reference your own class.

mrfelton’s picture

Status: Active » Needs review
StatusFileSize
new16.85 KB

Started work on this this morning. Making good progress. Code is up in https://github.com/systemseed/search_api_ranges . Patch attached with my current progress. Unfortunately, because I'm working with Commerce price fields, I'm a little bit hindered by #1350528: Add support for Commerce module price fields. So I need that patch applied before I can get any thing at all, but as I mentioned in that other issue, all searches return no results - no no real way to test this code yet. But, what I have so far is:

- A new class SearchApiRangesWidgetLinks which extends FacetapiWidgetLinks
- An implementation of the Basic range mode a bit like in Amitaibu's module (it generates ranges for you - you just specify the step).
- This works to the point of generating and displaying the range links, with what looks like the correct query paramaters (no way to test yet).

What I'm having trouble with is:
- Calculating the count value for each option (could probably do this by running a count query for each range option, but feel inefficient)
- Doing anything with the Search API API - I an completely unfamiliar with these apis, and the documentation is pretty sparse.

Open to comments and suggestions..!

Anonymous’s picture

Great, will have a look at it myself soon.

- Calculating the count value:
To make this possible, would require you to index a prices as belonging to a certain group. So we'd need to set the grouping in advanced, then index each item and say "item with price 10,99 belongs to group 0-25". This makes the grouping less dynamic, but you'd have counts.

mrfelton’s picture

If you are going to look, use the code from git as there have been changes since the patch, and I can't be bothered regenerating the patch needlessly. After applying a fix for the issue described in #1344076: URL encoding issue in fields using relationships (I have only fixed in on this widget - I haven't touched the code for the slider widget), as well as adding code to detect if a facet is active or not, the filtering is working pretty well. It generates the ranges as per the configuration of the the widget, you can click on a range, the results are appropriately filtered, and the facet is marked as active. You can then click on the facet again to remove it, as with the standard text links widget.

There is something funky going on with the AND/OR modes though.

When in OR mode, after selecting one facet, the resultset is narrowed down - which causes the min/max valued to be recalculated, which means that the generated ranges only cover the items in the selected facedt - resulting in only one range displaying, which doesn't necessarily match the originally selected range!

In AND mode, it works better. You can add one facet, and then remove it. You can then add a different one, and then remove it. However, really, in AND mode, once you have selected one facet, all other options should be removed - since an item can not belong to more than one group.

To implement this properly, I think that as you say - we actually need to have the ranges predefined and properly indexed. Not sure how to go about doing that though. You said "So we'd need to set the grouping in advanced, then index each item"... Could you elaborate on that?

Anonymous’s picture

>> You said "So we'd need to set the grouping in advanced, then index each item"... Could you elaborate on that?

I mean, a user should pre-define the groups. For example "group by 10, 100 or 1000". If you choose 100, you get groups like 0-100, 100-200, 200-300 etc. Then you index values and say, "123,1" belongs to "100-200". If you want to change the grouping afterwards to 0-50, 50-100 then you have to re-index. But it gives you the benefits of being "real facets" with counts.

For example,
group: 0-100; index_value: 0; displayed as "$0 - $100"
group: 1-200; index_value: 1; displayed as "$100 - $200"

To do this during indexing, you need to implement a dynamic hook_entity_property_info_alter()

function hook_entity_property_info_alter(&$info) {
  $properties = &$info;

  foreach ($range_filter as $range) { // something like this

  $entity_type = $range->type; // determine the entity type, e.g. "node", or "comment" or "custom_entity"


  $properties[$entity_type]['properties'][$range->field_name] = array(
  	'type' => 'integer',
        'label' => t('Range group') . ': ' . $range->field_label,
        'query callback' => 'entity_metadata_table_query',
        'getter callback' => 'search_api_ranges_grouping_meta_get_properties',
  	'description' => t('A range group, e.g. 0-100, 100-200.'),
    );
  }
}

That function search_api_ranges_grouping_meta_get_properties() would do this

/**
 * Getter gallback for facet grouping by integer value
 *
 * @param object $entity Loadable entity object
 * @param array $options Settings options
 * @param string $name Property name
 * @param string $entity_type Entity type
 *
 * @return array of values
 */
function search_api_ranges_grouping_meta_get_properties($entity, array $options, $name, $entity_type) {
  $values = array();

  $group_size = get_grouping_configuration_for_field($name); // something like this,to get the grouping size, 10, 100, or 1000 etc.

  $value = floor($entity->$name - $group_size); // result: 0 for 0-100, 1 for 100-200, etc. depending on group_size
  
  return $value;
}

..well I don't know if this is the right approach, it's worth a try, see what happens. I could dive into this more in early January. Might need this for my own project anyway.

BeaPower’s picture

what is the status of this?

Anonymous’s picture

Status: Needs review » Active

I never got around to it. If anyone can post a patch for this, I will be happy to apply it.

mgriebe’s picture

+1 follow. Love to have this widget!

Island Usurper’s picture

Status: Active » Needs review
StatusFileSize
new18.94 KB

Hey, a widget class for range facets!

I've made them look according to my own preferences, but they work like you'd expect.

Anonymous’s picture

Status: Needs review » Fixed

Thank you so much. It works and looks good. I committed your patch as-is to dev-x.
http://drupalcode.org/project/search_api_ranges.git/commit/0b35e5a

Some suggestions for future improvement:
- keep showing active links
- automatic grouping basec on min/max values (e.g. show 10 links between min/max)

Anyway, it's good to go.

vegardjo’s picture

Very timely, thanks for working on this :)

However I have a support request: The simple range works beautifully, but I can't get the advanced range to work. What is the syntax for this? It says to refer to the readme, but it doesn't contain any info.

I have tried:

1500-1600
1601-1700

1500 - 1600
1601 - 1700

1500-1600, 1601-1700

1500 - 1600, 1601 - 1700

But no luck, all these gives me one link in the facet block that is 0-0

vegardjo’s picture

Status: Fixed » Needs work
StatusFileSize
new20.68 KB

Hi, after testing this for a few days I feel I have to reopen:

Simple range kind of works, but I just realized it doesn't have correct values. Have a look at the attached screenshot where it says all items are within the 2000000 - 3000000 range. To the right you se one value (which is that field) that is below that range..

Also, can not get advanced range to show at all. It says 0-0 whatever I put in, Which syntax are we supposed to use?

Anonymous’s picture

Status: Needs work » Closed (fixed)

Hi I opened new issues, because this thread was already committed to dev.x

See:
#1785428: Cannot get advanced range to work
#1785430: Simple range text links not showing correct values

vegardjo’s picture

Thanks, we made a patch that makes advanced ranges work here: #1785428: Cannot get advanced range to work