Bogdan Bogdanovic
Bogdan Bogdanovic

Reputation: 181

How to create double range slider using native html input range and Vue.js?

Can you please help me with creating a double range slider (I only need two handles) for the native HTML input=range and Vue.js?

My code so far: https://jsfiddle.net/

Javascript (Vue.js)

var vm = new Vue({
  el: '#app',
  data: {
    minAngle: 10,
    maxAngle: 30
  },
  computed: {
    sliderMin: {
      get: function() {
        var val = this.minAngle;
        return val;
      },
      set: function(val) {
        if (val > this.maxAngle) {
          val = this.maxAngle;
        }
        this.minAngle = val;
        console.log("minAngle:" + this.minAngle + " maxAngle:" + this.maxAngle);
      }
    },
    sliderMax: {
      get: function() {
        var val = this.maxAngle;
        return val;
      },
      set: function(val) {
        if (val < this.minAngle) {
          val = this.minAngle;
        }
        this.maxAngle = val;
        console.log("minAngle:" + this.minAngle + " maxAngle:" + this.maxAngle);
      }
    }
  }
});

HTML

<div id="app">
  <input type="range" min="0" max="180" step="1" v-model="sliderMin">
  <input type="number" min="0" max="180" step="1" v-model="sliderMin">
  <input type="range" min="0" max="180" step="1" v-model="sliderMax">
  <input type="number" min="0" max="180" step="1" v-model="sliderMax">
</div>

The problem is that I would like to limit the range of the minSlider and the maxSlider if their values come below the min. So you would not get the maxAngle be below the minAngle or minAngle be above the maxAngle. Later I will of course make one slider on the top of each other using CSS so you will get the illusion it is only one slider with two handles. I know that there are Vue components for this but I was wondering if this is possible.

Thanks in advance, Bogdan

Upvotes: 6

Views: 15400

Answers (1)

Bogdan Bogdanovic
Bogdan Bogdanovic

Reputation: 181

Nevermind, I found out the solution. I turned out that I was not far away :) Here it is:

HTML

<div id="app">
  <div class='range-slider'>
    <input type="range" min="0" max="180" step="1" v-model="sliderMin">
    <input type="number" min="0" max="180" step="1" v-model="sliderMin">
    <input type="range" min="0" max="180" step="1" v-model="sliderMax">
    <input type="number" min="0" max="180" step="1" v-model="sliderMax">
  </div>
</div>

Javascript (Vue)

var app = new Vue({
  el: '#app',
  data: {
    minPrice: "500",
    maxPrice: "50000",
    minValue: "25000"
  },
  methods: {
    slider: function() {
      if (this.minPrice > this.maxPrice) {
        var tmp = this.maxPrice;
        this.maxPrice = this.minPrice;
        this.minPrice = tmp;
      }
    }
  }
});

CSS

.range-slider {
  width: 300px;
  margin: auto;
  text-align: center;
  position: relative;
  height: 6em;
}

.range-slider input[type=range] {
  position: absolute;
  left: 0;
  bottom: 0;
}

input[type=number] {
  border: 1px solid #ddd;
  text-align: center;
  font-size: 1.6em;
  -moz-appearance: textfield;
}

input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button {
  -webkit-appearance: none;
}

input[type=number]:invalid,
input[type=number]:out-of-range {
  border: 2px solid #ff6347;
}

input[type=range] {
  -webkit-appearance: none;
  width: 100%;
}

input[type=range]:focus {
  outline: none;
}

input[type=range]:focus::-webkit-slider-runnable-track {
  background: #2497e3;
}

input[type=range]:focus::-ms-fill-lower {
  background: #2497e3;
}

input[type=range]:focus::-ms-fill-upper {
  background: #2497e3;
}

input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 5px;
  cursor: pointer;
  animate: 0.2s;
  background: #2497e3;
  border-radius: 1px;
  box-shadow: none;
  border: 0;
}

input[type=range]::-webkit-slider-thumb {
  z-index: 2;
  position: relative;
  box-shadow: 0px 0px 0px #000;
  border: 1px solid #2497e3;
  height: 18px;
  width: 18px;
  border-radius: 25px;
  background: #a1d0ff;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -7px;
}

Fiddle:

https://jsfiddle.net/bogdanb86/3dr9ktxc/28/

Upvotes: 12

Related Questions