# Slider

{% hint style="info" %}
Availability of the functionality depends on the license and may not be available in all deployments.
{% endhint %}

A component that allows you to select numeric values using a slider.

![](https://content.gitbook.com/content/2CssJT0zIo4SJQLbSZ6l/blobs/UQI2VkKvY5L8AgnSm0Fl/14s_files/image2025-5-16_10-39-8.png)

✅ **When to use:**

* When you want to allow entering any precise amount in a text field (e.g. a loan amount of 5200 PLN), regardless of the slider step (e.g. 500 PLN).
* When you need to visually limit the selection range without changing the visible scale – the properties `minBlockValue` and `maxBlockValue` allow dynamic slider locking (e.g. based on the customer's creditworthiness, the form limits the range to 5000 PLN, even though the maximum amount offered by the bank is 10,000 PLN).

:x: **When not to use:**

* When the process does not allow intermediate values (e.g. the application accepts only specific values, such as the number of installments). **Use**: [Step Slider](https://docs.eximee.com/documentation/documentation-en/budowanie-aplikacji/interfejs-uzytkownika/formularze/biblioteka-komponentow-bazowych/3-wartosci-i-skale/step-slider).

## Component properties

| **Eximee Designer property**                                                                 | Attribute name in the Source | **Description**                                                                                                                                                                                                                                                                       |
| -------------------------------------------------------------------------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **The increment by which the value can be set on the slider** (section **Basic properties**) | step                         | Value increment, i.e. the step by which the value can be set on the slider (default value 100).                                                                                                                                                                                       |
| **Slider starting value** (section **Basic properties**)                                     | startValue                   | Slider starting value (default is empty). It can be supplied from a service.                                                                                                                                                                                                          |
| **Minimum displayed slider value** (section **Basic properties**)                            | minValue[^1]                 | Minimum slider value (default value 0). It can be supplied from a service.                                                                                                                                                                                                            |
| **Maximum displayed slider value** (section **Basic properties**)                            | maxValue[^1]                 | Maximum slider value (default value 1000). It can be supplied from a service.                                                                                                                                                                                                         |
| **Minimum possible value** (section **Basic properties**)                                    | minBlockValue[^1]            | The minimum beyond which the value cannot be selected (default value 0). It can be supplied from a service.                                                                                                                                                                           |
| **Maximum possible value** (section **Basic properties**)                                    | maxBlockValue[^1]            | The maximum beyond which the value cannot be selected (default value 1000). It can be supplied from a service.                                                                                                                                                                        |
| **Suggested value** (section **Basic properties**)                                           | suggestedValue               | Suggested value (e.g. in the case of a revolving credit limit, the limit amount suggested by the bank). It can be supplied from a service. Availability of this functionality depends on the license and may not be available in all deployments.                                     |
| **Suffix of the minimum and maximum slider value label** (section **Other**)                 | legendSuffix                 | Value appended to the label of the slider's minimum and maximum value. It can be supplied from a service. Availability of this functionality depends on the license and may not be available in all deployments.                                                                      |
| **Predicted slider value on hover over the axis** (section **Other**)                        | showPredictionTooltip        | Shows the predicted slider value when hovering over the slider axis (default value "true"). Availability of this functionality depends on the license and may not be available in all deployments.                                                                                    |
| **Display of the value indicated by the slider in a tooltip** (section **Other**)            | showTooltip                  | Shows the value indicated by the slider (default value "true"). Availability of this functionality depends on the license and may not be available in all deployments.                                                                                                                |
| **Formatter of the value displayed in the text field**                                       | textInputFormatter           | Formatter of the value displayed in the slider's text field. Availability of this functionality depends on the license and may not be available in all deployments.                                                                                                                   |
| **Text field suffix**                                                                        | textInputSuffix              | Value appended to the end of the slider's text field. It can be supplied from a service. Availability of this functionality depends on the license and may not be available in all deployments.                                                                                       |
| **Description displayed after clicking the text field**                                      | descriptionPopupText         | Description displayed after clicking the slider's text field. Functionality available in the mobile and native channels.                                                                                                                                                              |
| **Minimum value exceeded message**                                                           | minValueSuggest              | Text displayed below the slider's text field after exceeding the minimum value. Availability of this functionality depends on the license and may not be available in all deployments.                                                                                                |
| **Maximum value exceeded message**                                                           | maxValueSuggest              | Text displayed below the slider's text field after exceeding the maximum value. Availability of this functionality depends on the license and may not be available in all deployments.                                                                                                |
| **Synchronization of the slider state and the value entered in the text field**              | separatedSliderValue         | Controls synchronization of the slider state and the value entered in the input. When separatedSliderValue=true, the minBlockValue and maxBlockValue values are not respected. Availability of this functionality depends on the license and may not be available in all deployments. |

{% hint style="warning" %}
IMPORTANT — on the Slider, by default the maxValue and maxBlockValue values should match, unless they are intentionally different (then the Slider value will be limited to min (maxBlockValue, maxValue), so the upper limit will be the smaller of these values). Similarly for the minValue and minBlockValue values.

In the Slider component (in properties) it is not possible to set the starting/minimum/maximum value to a type other than integer.
{% endhint %}

> More information about component properties: [Common component properties](https://docs.eximee.com/documentation/documentation-en/budowanie-aplikacji/interfejs-uzytkownika/formularze/praca-z-komponentami-bazowymi/wspolne-wlasciwosci-komponentow)

## Writing the slider value to the Text Field (TextField) and vice versa

If the Slider value is to be written to the Text Field component, this component must listen to the Slider, and the value will be written either by indicating the slider in the **Data source from another field** text component, or a special service will be set for the Text Field (e.g. *EchoService*).

Also, the Slider value can be set based on the number entered in the Text Field component. To do this, the Slider should listen to the TextField and indicate this text field in the Slider property's **Data source from another field** .

### Slider with sample properties

![Figure 1. Example appearance of the component in the application](https://content.gitbook.com/content/2CssJT0zIo4SJQLbSZ6l/blobs/Ne5vZpyuT1T0Oa4xtcAR/14s_files/image2025-5-16_10-43-44.png)

### Specific appearance of the Slider

{% hint style="info" %}
Availability of the functionality depends on the license and may not be available in all deployments.
{% endhint %}

In some skins, the text field is already integrated with the slider.

![Figure 2. Example appearance of the Slider with a text field](https://content.gitbook.com/content/2CssJT0zIo4SJQLbSZ6l/blobs/5Czmt061WYddAQzGcAlc/14s_files/image2025-5-16_10-44-29.png)

![Figure 3. Example appearance of the Slider with parameters provided in text fields](https://content.gitbook.com/content/2CssJT0zIo4SJQLbSZ6l/blobs/XXaLQPx9gGo3SRtYVCnr/14s_files/image2025-5-16_10-46-11.png)

## Component state information

Information about the current value of a given component property, which can then be used in the application, e.g. to feed another field with the value of that property, can be obtained using the structure COMPONENT\_ID$PROPERTY\_NAME

The following property can be retrieved for the slider:

| Key             | Description                                                                                                       |
| --------------- | ----------------------------------------------------------------------------------------------------------------- |
| **sliderValue** | The value marked on the slider. When separatedSliderValue is set to true, it may differ from the component value. |

{% hint style="info" %}
Example: supply **Data source from another field** via GesSlider1$sliderValue
{% endhint %}

## Sample validator for the Slider

The validator displays a hint for the Slider in specific situations.

When attaching the validator below, as the parameter *insuranceComponentId* enter the id of the component related to insurance (e.g. a checkbox controlling enabling/disabling insurance) and as *sliderId* provide the id of the Slider whose amounts we want to control. If the mentioned components are not embedded directly on the application, provide the full embedding path, i.e. the id of the composite component containing these components and every parent composite component.

<details>

<summary>Sample validator code</summary>

{% code title="DevDemoSliderHintValidator.java" %}

```java
package pl.slider.demo.hint;

import lombok.extern.slf4j.Slf4j;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pl.consdata.eximee.validation.api.exceptions.ValidatorException;
import pl.consdata.eximee.validation.api.model.*;
import pl.consdata.eximee.validation.api.validator.AbstractExtendedValidator;

import java.math.BigDecimal;

import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.apache.commons.lang3.StringUtils.*;

@Slf4j
@Component
@Service(AbstractExtendedValidator.class)
public class DevDemoSliderHintValidator extends AbstractExtendedValidator {
    static final String GREATER_THAN_MAX = "DevDemoSliderHintValidator.greaterThanMax";
    static final String LESS_THAN_MIN = "DevDemoSliderHintValidator.lessThanMin";
    static final String LESS_THAN_MIN_BUTTON_LABEL = "DevDemoSliderHintValidator.lessThanMin.buttonLabel";
    static final String GREATER_THAN_MAX_BUTTON_LABEL = "DevDemoSliderHintValidator.greaterThanMax.buttonLabel";
    static final String GREATER_THAN_INSURANCE_TRESHOLD_CHANGE_AMOUNT = "DevDemoSliderHintValidator.greaterThanInsuranceTreshold.changeAmount";
    static final String GREATER_THAN_INSURANCE_TRESHOLD_WITHOUT_INSURANCE = "DevDemoSliderHintValidator.greaterThanInsuranceTreshold.withoutInsurance";
    static final String INSURANCE_AMOUNT_THRESHOLD = "insuranceAmountThreshold";
    static final String MAX_AMOUNT = "maxAmount";
    static final String MIN_AMOUNT = "minAmount";
    static final String SLIDER_INPUT = "sliderInput";
    static final String INSURANCE_CURRENT_VALUE = "insuranceCurrentValue";
    static final String INSURANCE_COMPONENT_ID = "insuranceComponentId";
    static final String INSURANCE_UNCHECKED_VALUE = "insuranceUncheckedValue";
    static final String GREATER_THAN_INSURANCE_TRESHOLD = "DevDemoSliderHintValidator.greaterThanInsuranceTreshold";
    static final String SLIDER_ID = "sliderId";

    private static final Logger LOGGER = LoggerFactory.getLogger(DevDemoSliderHintValidator.class);

    public DevDemoSliderHintValidator() {
        this.name = "DevDemoSliderHintValidator";
        this.version = "1.0";
        this.description = "Validator returning a validation message in the form of a hint for the slider.";
        this.fields.put(SLIDER_INPUT, "Value from the slider");
        this.fields.put(SLIDER_ID, "Identifier of the validated slider");
        this.fields.put(INSURANCE_AMOUNT_THRESHOLD, "Threshold for the amount with insurance");
        this.fields.put(MAX_AMOUNT, "Maximum value in the slider");
        this.fields.put(MIN_AMOUNT, "Minimum value in the slider");
        this.fields.put(INSURANCE_CURRENT_VALUE, "Current insurance value");
        this.fields.put(INSURANCE_COMPONENT_ID, "Insurance component identifier");
        this.fields.put(INSURANCE_UNCHECKED_VALUE, "Value of unchecked insurance");

        this.possibleErrors.put(LESS_THAN_MIN, "The minimum loan amount is <strong>{0} PLN</strong>");
        this.possibleErrors.put(GREATER_THAN_MAX, "For a loan higher than <strong>{0} PLN</strong> net, we need to ask you a few additional questions.");
        this.possibleErrors.put(GREATER_THAN_INSURANCE_TRESHOLD, "If you want a loan with insurance higher than <strong>{0} PLN</strong> net, visit any Bank branch.");
        this.possibleErrors.put(LESS_THAN_MIN_BUTTON_LABEL, "I understand >");
        this.possibleErrors.put(GREATER_THAN_MAX_BUTTON_LABEL, "Yes, I want to apply for {1} PLN");
        this.possibleErrors.put(GREATER_THAN_INSURANCE_TRESHOLD_CHANGE_AMOUNT, "I am reducing the amount");
        this.possibleErrors.put(GREATER_THAN_INSURANCE_TRESHOLD_WITHOUT_INSURANCE, "Without insurance");
    }

    @Override
    public ValidatorOutput validate(ValidatorInput validatorInput) {
        LOGGER.info(">> Validator called with params: {}", validatorInput);
        ValidatorOutput result = new ValidatorOutput();

        if (isValueGreaterThanMax(validatorInput)) {
            result.setErrors(singletonList(valueGreaterThanMaxMessage(validatorInput)));
        } else if (isValueLessThanMin(validatorInput)) {
            result.setErrors(singletonList(valueLessThanMinMessage(validatorInput)));
        } else if (isValueGreaterThanInsuranceTresholdAndInsuranceIsChecked(validatorInput)) {
            result.setErrors(singletonList(valueGreaterThanInsuranceTresholdAndInsuranceIsCheckedMessage(validatorInput)));
        }

        LOGGER.info("<< Output: {}", result);
        return result;
    }

    private boolean isValueGreaterThanMax(final ValidatorInput input) {
        return asBigDecimal(input.getFirstValue(SLIDER_INPUT)).compareTo(asBigDecimal(input.getFirstValue(MAX_AMOUNT))) > 0;
    }

    private ValidationMessage valueGreaterThanMaxMessage(final ValidatorInput input) {
        final ValidationMessage message = new ValidationMessage(GREATER_THAN_MAX, asList(input.getFirstValue(MAX_AMOUNT), input.getFirstValue(SLIDER_INPUT)));
        message.setType(ValidationMessage.TYPE_HINT);
        message.setActions(singletonList(ValidationAction
                .builder()
                .actionData("https://www.xxxxxxx.pl")
                .actionType(ValidationActionType.REDIRECT)
                .actionName(GREATER_THAN_MAX)
                .content(GREATER_THAN_MAX_BUTTON_LABEL)
                .build()));
        return message;
    }

    private boolean isValueLessThanMin(final ValidatorInput input) {
        return asBigDecimal(input.getFirstValue(SLIDER_INPUT)).compareTo(asBigDecimal(input.getFirstValue(MIN_AMOUNT))) < 0;
    }

    private ValidationMessage valueLessThanMinMessage(final ValidatorInput input) {
        final ValidationMessage message = new ValidationMessage(LESS_THAN_MIN, singletonList(input.getFirstValue(MIN_AMOUNT)));
        message.setType(ValidationMessage.TYPE_HINT);
        message.setActions(singletonList(ValidationAction
                .builder()
                .actionData(input.getFirstValue(MIN_AMOUNT))
                .actionType(ValidationActionType.CHANGE_VALUE)
                .changeComponentId(input.getFirstValue(SLIDER_ID))
                .actionName(LESS_THAN_MIN)
                .content(LESS_THAN_MIN_BUTTON_LABEL)
                .build()));
        return message;
    }

    private boolean isValueGreaterThanInsuranceTresholdAndInsuranceIsChecked(final ValidatorInput input) {
        return !equalsIgnoreCase(input.getFirstValue(INSURANCE_CURRENT_VALUE), input.getFirstValue(INSURANCE_UNCHECKED_VALUE))
                && asBigDecimal(input.getFirstValue(SLIDER_INPUT)).compareTo(asBigDecimal(input.getFirstValue(INSURANCE_AMOUNT_THRESHOLD))) > 0;
    }

    private ValidationMessage valueGreaterThanInsuranceTresholdAndInsuranceIsCheckedMessage(final ValidatorInput input) {
        final ValidationMessage message = new ValidationMessage(GREATER_THAN_INSURANCE_TRESHOLD, singletonList(input.getFirstValue(INSURANCE_AMOUNT_THRESHOLD)));
        message.setType(ValidationMessage.TYPE_HINT);
        message.setActions(asList(ValidationAction
                .builder()
                .actionData(input.getFirstValue(INSURANCE_AMOUNT_THRESHOLD))
                .actionType(ValidationActionType.CHANGE_VALUE)
                .changeComponentId(input.getFirstValue(SLIDER_ID))
                .actionName(GREATER_THAN_INSURANCE_TRESHOLD_CHANGE_AMOUNT)
                .content(GREATER_THAN_INSURANCE_TRESHOLD_CHANGE_AMOUNT)
                .build(), ValidationAction
                .builder()
                .actionData(input.getFirstValue(INSURANCE_UNCHECKED_VALUE))
                .actionType(ValidationActionType.CHANGE_VALUE)
                .changeComponentId(input.getFirstValue(INSURANCE_COMPONENT_ID))
                .actionName(GREATER_THAN_INSURANCE_TRESHOLD_WITHOUT_INSURANCE)
                .content(GREATER_THAN_INSURANCE_TRESHOLD_WITHOUT_INSURANCE)
                .build()));
        return message;
    }

    private BigDecimal asBigDecimal(final String str) {
        final String digits = removePattern(str, "[^0-9-]");
        return isNotEmpty(digits) ? new BigDecimal(digits) : BigDecimal.ZERO;
    }
}
```

{% endcode %}

</details>

{% hint style="info" %}
Demo application: demoSlider

Demo application in selected deployments: demoSliderValidationHint
{% endhint %}

{% hint style="info" %}
♿WCAG: [WCAG best practices for low-code dev](https://docs.eximee.com/documentation/documentation-en/budowanie-aplikacji/proces-biznesowy/tworzenie-procesu-biznesowego-w-bpmn-2.0/dobre-praktyki)
{% endhint %}

[^1]: The Slider value will be limited to min (maxBlockValue, maxValue), so the upper limit will be the smaller of these values.
