0

I'm using a vue component which is two way bound with an input field.

I want to append a +- and a % sign to this value solely in the input field view. I don't want to change the actual value as this will cause troubles with the component.

Here is what I am looking for:

enter image description here

Here is what I have:

enter image description here

Using this code:

<form class="form-container">

  <label for="changePercent" class="move-percent-label">Move Market</label>
  <input class="move-percent" id="changePercent" v-model="value.value" type="number">

  <span class="middle-line"></span>
  <vue-slider v-bind="value" v-model="value.value"></vue-slider>

  <div class="control-buttons">
    <button @click="" class="primary-button">Apply</button>
    <button @click.prevent="value.value = 0;" class="tertiary-button">Reset</button>
  </div>

</form>

------------------UPDATE-------------------

As per answer below using a computed property.

Good:

enter image description here

Not Good

enter image description here

So I need this to work both ways

Sisky
  • 563
  • 9
  • 26

1 Answers1

1

To have another value always formated a computed property:

new Vue({
  el: '#app',
  data: {
    value: {value: 0},
    // ..
  },
  computed: {
    readableValue() {
      return (this.value.value => 0 ? "+" : "-" ) + this.value.value + "%";
    }
  }
})

Creating an editor for the slider and showing formatted

To get what you want we will have to do a litte trick with two inputs. Because you want the user to edit in a <input type="number"> but want to also show +15% which can't be shown in a <input type="number"> (because + and % aren't numbers). So you would have to do some showing/hiding, as below:

new Vue( {
  el: '#app',
  data () {
    return {
     editing: false,
     value: {value: 0},
    }
  },
  methods: {
   enableEditing() {
      this.editing = true;
      Vue.nextTick(() => { setTimeout(() => this.$refs.editor.focus(), 100) });
    },
    disableEditing() {
      this.editing = false;
    }
  },
  computed: {
    readableValue() {
      return (this.value.value > 0 ? "+" : "" ) + this.value.value + "%";
    }
  },
  components: {
    'vueSlider': window[ 'vue-slider-component' ],
  }
})
/* styles just for testing */
#app { margin: 10px; }
#app input:nth-child(1) { background-color: yellow }
#app input:nth-child(2) { background-color: green }
<div id="app">
  
  <input :value="readableValue" type="text" v-show="!editing" @focus="enableEditing">
  <input v-model.number="value.value" type="number" ref="editor" v-show="editing" @blur="disableEditing">
  <br><br><br>
  <vue-slider v-model="value.value" min="-20" max="20">></vue-slider>

</div>
<script src="https://unpkg.com/vue@2.5.13/dist/vue.min.js"></script>
<script src="https://nightcatsama.github.io/vue-slider-component/dist/index.js"></script>
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • I don't think this method is still two way bound. The input field should still change the slider if edited. – Sisky Mar 08 '18 at 00:30
  • If you chage `this.value.value`, the computed updates. Have you tried it? – acdcjunior Mar 08 '18 at 00:36
  • The value.value will only change through using the slider. The input also needs to change this value. – Sisky Mar 08 '18 at 00:40
  • If the computed is not changing, then the slide is not updating `this.value.value`. Try adding `{{ value.value }}` to see if it changes when the slider moves. – acdcjunior Mar 08 '18 at 00:43
  • The slide is working fine. It changes the input text fine. But it needs to be two way bound. If I change the value in the input field rather than the slider the value.value needs to be updated. – Sisky Mar 08 '18 at 00:44
  • Ok, will do. Brb – acdcjunior Mar 08 '18 at 00:59
  • Which slider is that? I got one here, but I wanted to confirm if its the same. – acdcjunior Mar 08 '18 at 01:25
  • Hey thanks for the response. Unfortunately it dosen't work cross browser (firefox). I did use your dual input trick though in conjunction with a library, https://github.com/simplesmiler/vue-focus. I'll put up the final working code tomorrow fyi =) – Sisky Mar 08 '18 at 11:19
  • Put where? Anyway, the cross-browser problem is a bug on Vue (or firefox). Adding a `setTimeout` (`Vue.nextTick(() => { setTimeout(() => this.$refs.editor.focus(), 1) });`) makes it work for all browsers. Check updated answer. – acdcjunior Mar 08 '18 at 12:18