1

I am trying to format data in this format m:ss, and limit the input textbox to only show 3 or fewer characters. (m = minute, s = seconds)

I have the below code, it formats properly in m:ss format. But if I type many characters at once, it shows more than 3 characters or it gets stuck.

I.E) If I type 11111 at once, I get 1:1111. But I want the textbox to show 1:11.

If I type 1234, sometimes it gets stuck at 1:2. Then If I wait and type again, there are more than 3 characters.

new Vue({
  el:"#app",
  data () { return { value: "" } },
  computed: {
    fValue: {
      // getter
      get () {
        if (this.value.length > 3) { return this.value.substr(0, 3); }
        return this.value;
      },
      // setter
      set (newValue) {
        this.formatTime(newValue);
      }
    }
  },
  methods: {
    formatTime (str) {
      let totalLength = str.length;
      if (totalLength > 3) { totalLength = 3; }
      let a = str.replace(/[^0-9]/g, "").substr(0, 1);
      let b = str.replace(/[^0-9]/g, "").substr(1, 1);
      if (b > 5) { b = 5; }
      const c = str.replace(/[^0-9]/g, "").substr(2, 1);
      if (totalLength >= 2) { a = `${a.substring(0, 1)}:${b}${c}`; }
      const result = a;
      this.value = result;
      return result;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input
    v-model="fValue"
    id="format-value"
    class="input"
    type="text"
  />
</div>

------ EDIT Question 2 -----

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
   <div
      v-for="(index) in valueInputs" <-- index
      :key="index"
    >
      <input
        v-model="value"     // <-- I want to track what index I'm in
        @input="formatTime" // <-- so I can set it in an array later
        maxLength="4"       // I tried formatTime[index] or value[index]
        id="format-value"
        class="input"
        type="text"
      />
  </div>
</div>

data () {
  return {
  valueInputs: [],    // a list of inputs
  allFormatValues: [] // want to store all the formatted values here by the index
 }
}

Want to set an array that stores all the formatted values:

   this.allFormatValues[index] = this.value;

I'm not sure how to associate the index with the formatted string value?

1 Answer 1

1

You can use value as the v-model and call formatTime on input. Here is a demo with some refactoring/improvements:

new Vue({
  el:"#app",
  data () { return { value: "" } },
  methods: {
    formatTime () {
      const numericValue = this.value.replace(/[^0-9]/g, "");
      let [a = '', b = '', c = ''] = numericValue.substr(0, 3).split('');
      b = b > 5 ? 5 : b;
      this.value = numericValue.length >= 2 ? `${a}:${b}${c}` : a;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <input
    v-model="value"
    @input="formatTime"
    maxLength="4"
    id="format-value"
    class="input"
    type="text"
  />
</div>

Sign up to request clarification or add additional context in comments.

5 Comments

Is there a way to pass in index information if this is in a for loop?
Can you explain the scenario in detail
Thank you for looking into it! I have added an edit to explain the scenario
@Suzy why not store the formatted values directly in valueInputs? And why is it empty?
It's empty in the beginning until the user adds more inputs. I got some help on this, but thanks for checking in!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.