> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ais-range-input

> Lets users enter a numeric range for refining search results.

<div className="not-prose algolia-flavor-switcher">
  <div className="afs-dropdown">
    <div className="afs-trigger" role="button" tabIndex="0" aria-haspopup="listbox">
      <span className="afs-current">Vue</span>

      <svg className="afs-chevron lucide lucide-chevron-down" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="m6 9 6 6 6-6" />
      </svg>
    </div>

    <ul className="afs-menu" role="listbox">
      <li role="option" aria-selected="false"><a className="afs-option" href="/doc/api-reference/widgets/range-input/js"><span className="afs-option-name">JavaScript</span><span className="afs-option-lib">InstantSearch.js</span></a></li>
      <li role="option" aria-selected="false"><a className="afs-option" href="/doc/api-reference/widgets/range-input/react"><span className="afs-option-name">React</span><span className="afs-option-lib">React InstantSearch</span></a></li>
      <li role="option" aria-selected="true"><a className="afs-option is-current" href="/doc/api-reference/widgets/range-input/vue"><span className="afs-option-name">Vue</span><span className="afs-option-lib">Vue InstantSearch</span></a></li>
    </ul>
  </div>
</div>

```vue Signature theme={"system"}
<ais-range-input
  attribute="string"
  // Optional parameters
  :min="number"
  :max="number"
  :precision="number"
  :class-names="object"
/>
```

## Import

<Tabs>
  <Tab title="Component">
    To ensure optimal bundle sizes,
    see [Optimize build size](/doc/guides/building-search-ui/going-further/improve-performance/vue#optimize-build-size).

    ```js Vue icon=code theme={"system"}
    import { AisRangeInput } from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    export default {
      components: {
        AisRangeInput
      },
      // ...
    };
    ```
  </Tab>

  <Tab title="Plugin">
    This imports all widgets, even the ones you don't use.
    For more information, see [Get started with Vue InstantSearch](/doc/guides/building-search-ui/getting-started/vue).

    ```js JavaScript icon="code" theme={"system"}
    import Vue from "vue";
    import InstantSearch from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    Vue.use(InstantSearch);
    ```
  </Tab>
</Tabs>

<Card title="See this widget in action" icon="monitor-play" href="https://instantsearchjs.netlify.app/stories/vue/?selectedKind=ais-range-input" horizontal>
  Preview this widget and its behavior.
</Card>

## About this widget

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

### Requirements

The [`attribute`](#param-attribute) provided to the widget must be in attributes for faceting,
either on the [dashboard](/doc/guides/managing-results/refine-results/faceting/how-to/declaring-attributes-for-faceting-with-dashboard) or using the [`attributesForFaceting`](/doc/api-reference/api-parameters/attributesForFaceting) parameter with the API.

The values of the attribute must be numbers, not strings.

## Examples

```vue Vue icon=code theme={"system"}
<ais-range-input attribute="price" />
```

## Props

<ParamField body="attribute" type="string" required>
  The name of the attribute in the record.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input attribute="price" />
  ```
</ParamField>

<ParamField body="min" type="number">
  The minimum value for the input.
  When not provided, the minimum value is automatically computed by Algolia from the data in the index.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input
    [...]
    :min="10"
  />
  ```
</ParamField>

<ParamField body="max" type="number">
  The maximum value for the input.
  When not provided, the maximum value is automatically computed by Algolia from the data in the index.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input
    [...]
    :max="500"
  />
  ```
</ParamField>

<ParamField body="precision" type="number" default={0}>
  The number of digits after the decimal point to use.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input
    [...]
    :precision="2"
  />
  ```
</ParamField>

<ParamField body="class-names" type="object" default="{}">
  The [CSS classes you can override](/doc/guides/building-search-ui/widgets/customize-an-existing-widget/vue#style-your-widgets):

  * `ais-RangeInput`. The root of the widget.
  * `ais-RangeInput--noRefinement`. The root of the widget without refinement.
  * `ais-RangeInput-form`. The form wrapper around the inputs and the submit button.
  * `ais-RangeInput-separator`. The separator between the min and the max.
  * `ais-RangeInput-button`. The button that triggers the submission of the form.
  * `ais-RangeInput-label`. The enclosing label of an input.
  * `ais-RangeInput-input`. The inputs.
  * `ais-RangeInput-input--min`. The input for the minimum value.
  * `ais-RangeInput-input--max`. The input for the maximum value.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input
    [...]
    :class-names="{
      'ais-RangeInput': 'MyCustomRangeInput',
      'ais-RangeInput-form': 'MyCustomRangeInputForm',
      // ...
    }"
  />
  ```
</ParamField>

## Customize the UI

<ParamField body="default">
  The slot to override the complete DOM output of the widget.

  When you implement this slot,
  none of the other slots will change the output,
  as the default slot surrounds them.

  **Scope**

  * `currentRefinement: { min: number, max: number }`. A value that contains the currently applied refinement.
  * `range: { min: number, max: number }`. A value that contains the minimum and maximum available value.
  * `canRefine: boolean`. Whether the refinement can be applied.
  * `refine: ({ min: number, max: number }) => void`. A function to select the refinement.
  * `sendEvent: (eventType: 'click', facetValue: string) => void`. The function to send `click` events.

    * The `view` event is automatically sent when the facets are rendered.
    * The `click` event is automatically sent when `refine` is called.

    To learn more, see the [`insights`](/doc/api-reference/widgets/insights/vue) middleware.

  ```vue Vue icon=code theme={"system"}
  <template>
    <!-- ... -->
    <ais-range-input attribute="price">
      <template
        v-slot="{ currentRefinement, range, canRefine, refine, sendEvent }"
      >
        <input
          type="number"
          :min="range.min"
          :max="range.max"
          :placeholder="range.min"
          :disabled="!canRefine"
          :value="formatMinValue(currentRefinement.min, range.min)"
          @input="
            refine({
              min: $event.currentTarget.value,
              max: formatMaxValue(currentRefinement.max, range.max),
            })
          "
        />
        →
        <input
          type="number"
          :min="range.min"
          :max="range.max"
          :placeholder="range.max"
          :disabled="!canRefine"
          :value="formatMaxValue(currentRefinement.max, range.max)"
          @input="
            refine({
              min: formatMinValue(currentRefinement.min, range.min),
              max: $event.currentTarget.value,
            })
          "
        />
      </template>
    </ais-range-input>
  </template>

  <script>
  export default {
    methods: {
      formatMinValue(minValue, minRange) {
        return minValue !== null && minValue !== minRange ? minValue : "";
      },
      formatMaxValue(maxValue, maxRange) {
        return maxValue !== null && maxValue !== maxRange ? maxValue : "";
      },
    },
  };
  </script>
  ```
</ParamField>

<ParamField body="minLabel">
  The slot to override the DOM output for the label of the minimum value.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input attribute="price">
    <template v-slot:minLabel>Minimum:</template>
  </ais-range-input>
  ```
</ParamField>

<ParamField body="maxLabel">
  The slot to override the DOM output for the label of the maximum value.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input attribute="price">
    <template v-slot:maxLabel>Maximum:</template>
  </ais-range-input>
  ```
</ParamField>

<ParamField body="submitLabel">
  The slot to override the DOM output for the label of the submit button.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input attribute="price">
    <template v-slot:submitLabel>Submit</template>
  </ais-range-input>
  ```
</ParamField>

<ParamField body="separator">
  The slot to override the DOM output for the separator beteween the inputs.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input attribute="price">
    <template v-slot:separator>→</template>
  </ais-range-input>
  ```
</ParamField>

## HTML output

```html HTML icon=code-xml theme={"system"}
<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>
```
