0

I am using the "vue-slider" component to sort products based on their price. The problem I am facing is that, eventhough the data is correctly loaded and send to the "vue-slider" implementation. The tooltips (the dragable dots) on the slider appear both at the end of the slider. I would like to have the first tooltip at the beginning of the slider and the second one at the end. The getMin and getMax are read via string interpolation {{getMin}} and {{getMax}} both of these show the right values, 1 and 800 (dollars). This makes me wonder why both tooltips are still at the end of the slider.

I display the slider data in the front-end using the following code:

                <price-slider
                  code="price"
                  id="reloadDiv"
                  :priceRange="[
                    { from: minPrice },
                    { to: maxPrice   },
                  ]"
                  @change="$emitPriceSlider($event)"
                />
              </div>

The logic behind this slider is based of the component. The code I use for this is as follows:

<template>
  <div class="price-slider-container">
    
    {{ getMin }} {{ getMax }}
    <no-ssr placeholder="loading..." placeholader-tag="span">
      <vue-slider
        ref="priceSlider"
        v-model="value"
        v-bind="priceSliderOptions"
        :clickable="false"
        :min="getMin"
        :max="getMax"
        :tooltip-formatter="tooltipContent"
        @drag-end="setPrice"
      />
    </no-ssr>
  </div>
</template>

<script>
import NoSSR from "vue-no-ssr";
import isEqual from "lodash-es/isEqual";
import { products } from "config";

const PriceSliderComponents = {};

if (process.browser) {
  let VueSlider = require("vue-slider-component");
  PriceSliderComponents["vue-slider"] = VueSlider;
}
PriceSliderComponents["no-ssr"] = NoSSR;

export default {
  name: "PriceSlider",
  props: {
    content: {
      type: null,
      default: "",
    },
    id: {
      type: null,
      required: true,
    },
    code: {
      type: null,
      required: true,
    },
    priceRange: {
      type: Array,
      required: true,
    },
    context: {
      type: null,
      default: "",
    },
  },
  beforeMount() {
    this.$bus.$on("reset-filters", this.resetPriceSlider);
    this.$bus.$on("reset-price-slider", this.resetPriceSlider);
  },
  beforeDestroy() {
    this.$bus.$off("reset-filters", this.resetPriceSlider);
    this.$bus.$off("reset-price-slider", this.resetPriceSlider);
  },
  mounted() {
    const routeQueryData =
      this.$store.state.route[products.routerFiltersSource];
    if (routeQueryData.hasOwnProperty("price")) {
      const routePriceRange = routeQueryData["price"].split("-");
      if (!isEqual(this.value, routePriceRange)) {
        this.value = routePriceRange;
      }
    }
  },
  data() {
    return {
      active: false,
      remove: false,
      value: this.priceRange,
      currencySign: this.$store.state.config.i18n.currencySign,
      priceSliderOptions: {
        clickable: false,
        height: 2,
        "bg-style": {
          backgroundColor: "#f2f2f2",
        },
        "tooltip-dir": ["bottom", "bottom"],
        formatter: "€ {value}",
        "process-style": {
          backgroundColor: "#4dba87",
          fontWeight: 700,
        },
        "tooltip-style": {
          backgroundColor: "#4dba87",
          color: "#ffffff",
          "border-color": "#4dba87",
          padding: "7px 10px",
        },
      },
    };
  },
  computed: {
    // priceSliderOptions() {
    //   return {
    //     ...this.priceSliderConfig,
    //     ...this.tooltipContent,
    //     silent: true,
    //   };
    // },
    tooltipContent() {
      return { formatter: this.currencySign + " {value}" };
    },
    getMin() {
      return String(this.priceRange[0].from);
    },
    getMax() {
      return String(this.priceRange[1].to);
    },
  },
  watch: {
    $route: "validateRoute",
  },
  methods: {
    setPrice: function (e) {
      let val = e.val;
      let from = parseInt(val[0]);
      let to = parseInt(val[1]);
      let id = from.toFixed(1) + "-" + to.toFixed(1);
      this.remove = isEqual([from, to], this.priceRange);
      this.switchFilter({
        id: id,
        type: this.code,
        from: from,
        to: to,
        remove: this.remove,
      });
    },
    switchFilter(variant) {
      this.$emit("change", variant);
    },
    resetPriceSlider() {
      if (this.$refs.priceSlider) {
        this.$refs.priceSlider.setValue(this.priceRange);
      }
    },
    validateRoute() {
      const routeQueryData =
        this.$store.state.route[products.routerFiltersSource];
      if (this.$refs.priceSlider && !routeQueryData.hasOwnProperty("price")) {
        this.$nextTick(() => {
          this.$refs.priceSlider.setValue(this.priceRange);
        });
      }
    },
  },
  components: PriceSliderComponents,
};
</script>

<style lang="scss" scoped>
@import "~src/themes/default/css/variables/colors";
@import "~src/themes/default/css/helpers/functions/color";
$color-event: color(tertiary);
$color-active: color(accent);

.price-slider-container {
  padding-bottom: 50px;
  position: relative;
  z-index: 1;
}

.price-selector {
  width: 20px;
  height: 20px;

  &.active {
    .square {
      background-color: $color-active;
    }
  }
}

.square {
  width: 80%;
  height: 80%;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
</style>

<style lang="scss">
.vue-slider-component .vue-slider-dot {
  box-shadow: none;
}
</style>
Craws
  • 576
  • 4
  • 30

1 Answers1

0

I have found the solution to this problem in the following line in:

  data() {
    return {
      active: false,
      remove: false,
      value: this.priceRange,

Where value is set to an array, this is not supported. I patched this by replacing this.priceRange to:

[this.priceRange[0].from, this.priceRange[1].to],
Craws
  • 576
  • 4
  • 30