API Reference / Angular InstantSearch / ais-range-input
Signature
<ais-range-input
  attribute="string"

  // Optional parameters
  [min]="number"
  [max]="number"
  [precision]="number"
  currency="string"
  separator="string"
  submitLabel="string"
></ais-range-input>

About this widget # A

The ais-range-input allows a user to select a numeric range using a minimum and maximum input.

Requirements#

The attributes passed to the attributes prop must be declared as Attributes for faceting on the Algolia dashboard or configured as attributesForFaceting with the Algolia API.

Examples # A

1
<ais-range-input attribute="price"></ais-range-input>

Props # A

attribute #
type: string
Required

The name of the attribute in the record.

1
<ais-range-input attribute="price"></ais-range-input>
min #
type: number
Optional

The minimum value for the input. When not provided, the minimum value is automatically computed by Algolia from the data in the index.

1
2
3
4
<ais-range-input
  // ...
  [min]="10"
></ais-range-input>
max #
type: number
Optional

The maximum value for the input. When not provided, the maximum value is automatically computed by Algolia from the data in the index.

1
2
3
4
<ais-range-input
  // ...
  [max]="500"
></ais-range-input>
precision #
type: number
default: 2
Optional

The number of digits after the decimal point to use.

1
2
3
4
<ais-range-input
  // ...
  [precision]="0"
></ais-range-input>
currency #
type: string
default: $
Optional

Label for the currency sign.

1
2
3
4
<ais-range-input
  // ...
  currency="€"
></ais-range-input>
separator #
type: string
default: to
Optional

Label for the separator between the inputs.

1
2
3
4
<ais-range-input
  // ...
  separator="→"
></ais-range-input>
submitLabel #
type: string
default: Go
Optional

Label of the submit button.

1
2
3
4
<ais-range-input
  // ...
  submitLabel="Ok"
></ais-range-input>

HTML output# A

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div class="ais-RangeInput">
  <form class="ais-RangeInput-form">
    <label class="ais-RangeInput-label">
      <input
        class="ais-RangeInput-input ais-RangeInput-input--min"
        type="number"
        placeholder=""
        step="1"
      />
    </label>
    <span class="ais-RangeInput-separator">to</span>
    <label class="ais-RangeInput-label">
      <input
        class="ais-RangeInput-input ais-RangeInput-input--max"
        type="number"
        placeholder=""
        step="1"
      />
    </label>
    <button class="ais-RangeInput-submit" type="submit">Go</button>
  </form>
</div>

Customize the UI with connectRange# A

If you want to create your own UI of the ais-range-input widget, you can combine the connectRange connector with the TypedBaseWidget class.

This connector is also used to build other widgets: RangeSlider

1. Extend the TypedBaseWidget class#

First of all, you will need to write some boilerplate code to initialize correctly the TypedBaseWidget class. This happens in the constructor() of your class extending the TypedBaseWidget class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';

@Component({
  selector: 'app-range-input',
  template: '<p>It works!</p>'
})
export class RangeInput extends TypedBaseWidget {
  constructor(
    @Inject(forwardRef(() => NgAisIndex))
    @Optional()
    public parentIndex: NgAisIndex,
    @Inject(forwardRef(() => NgAisInstantSearch))
    public instantSearchInstance: NgAisInstantSearch
  ) {
    super('RangeInput');
  }
}

There are a couple of things happening in this boilerplate:

  • create a RangeInput class extending TypedBaseWidget
  • reference the <ais-instantsearch> parent component instance on the RangeInput widget class
  • set app-range-input as a selector, so we can use our component as <app-range-input></app-range-input>

2. Connect your custom widget#

The TypedBaseWidget class has a method called createWidget() which takes two arguments: the connector to use and an object of options (instance options) for this connector. We call this method at ngOnInit. This component now implements OnInit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';

import connectRange, {
  RangeWidgetDescription,
  RangeConnectorParams
} from 'instantsearch.js/es/connectors/range/connectRange';

@Component({
  selector: 'app-range-input',
  template: '<p>It works!</p>'
})
export class RangeInput extends TypedBaseWidget<RangeWidgetDescription, RangeConnectorParams> {
  public state: RangeWidgetDescription['renderState']; // Rendering options
  constructor(
    @Inject(forwardRef(() => NgAisIndex))
    @Optional()
    public parentIndex: NgAisIndex,
    @Inject(forwardRef(() => NgAisInstantSearch))
    public instantSearchInstance: NgAisInstantSearch
  ) {
    super('RangeInput');
  }
  ngOnInit() {
    this.createWidget(connectRange, {
      // instance options
      attribute: 'price',
    });
    super.ngOnInit();
  }
}

3. Render from the state#

Your component instance has access to a this.state property which holds the rendering options of the widget.

public state: RangeWidgetDescription['renderState'];
// {
//   start: number[];
//   range: object;
//   refine: Function;
//   widgetParams: object;
// }
1
2
3
4
5
6
7
<div *ngIf="state.range">
  from
  <input type="number" #min [value]="state.start[0]" min="state.range.min" max="state.range.max" />
  to
  <input type="number" #max [value]="state.start[1]" min="state.range.min" max="state.range.max" />
  <button (click)="state.refine([min.value, max.value])">Go</button>
</div>

Rendering options #

start #
type: number[]

The current value for the refinement, with start[0] as the minimum value and start[1] as the maximum value.

range #
type: object

The current available value for the range.

refine #
type: function

Sets a range to filter the results on. Both values are optional, and default to the higher and lower bounds. You can use undefined to remove a previously set bound or to set an infinite bound.

widgetParams #
type: object

All original widget options forwarded to the render function.

Instance options #

attribute #
type: string
Required

The name of the attribute in the record.

min #
type: number
Optional

The minimum value for the input. When not provided, the minimum value is automatically computed by Algolia from the data in the index.

max #
type: number
Optional

The maximum value for the input. When not provided, the maximum value is automatically computed by Algolia from the data in the index.

precision #
type: number
default: 0
Optional

The number of digits after the decimal point to use.

Full example#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';

import connectRange, {
  RangeWidgetDescription,
  RangeConnectorParams
} from 'instantsearch.js/es/connectors/range/connectRange';

@Component({
  selector: 'app-range-input',
  template: `
<div *ngIf="state.range">
  from
  <input type="number" #min [value]="state.start[0]" min="state.range.min" max="state.range.max" />
  to
  <input type="number" #max [value]="state.start[1]" min="state.range.min" max="state.range.max" />
  <button (click)="state.refine([min.value, max.value])">Go</button>
</div>
`
})
export class RangeInput extends TypedBaseWidget<RangeWidgetDescription, RangeConnectorParams> {
  public state: RangeWidgetDescription['renderState']; // Rendering options
  constructor(
    @Inject(forwardRef(() => NgAisIndex))
    @Optional()
    public parentIndex: NgAisIndex,
    @Inject(forwardRef(() => NgAisInstantSearch))
    public instantSearchInstance: NgAisInstantSearch
  ) {
    super('RangeInput');
  }
  ngOnInit() {
    this.createWidget(connectRange, {
      // instance options
      attribute: 'price',
    });
    super.ngOnInit();
  }
}
Did you find this page helpful?