Daniel YC Lin
Daniel YC Lin

Reputation: 16042

force input form enter uppercase to backend in vue.js

I've tried to input 'a001', the display will show 'A001' because the CSS rule. What's the proper/best way to convert it to uppercase before passing to backend?

new Vue({
  el: '#app',
  data: {
    myid: ''
  },
  methods: {
    click: function() {
      console.log('clicked id=', this.myid)
    }
  }
});
div input {
  text-transform: uppercase
}
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<div id="app">
  <input type="text" v-model="myid" placeholder="My ID" />
  <button type="button" @click="click">Submit</button>
</div>

Upvotes: 12

Views: 26592

Answers (8)

Bhaskar
Bhaskar

Reputation: 1946

The simple way without any computed or $event

<v-text-field
   v-model="batchNo"
   label="Batch Number"
   @input="(val) => (batchNo = batchNo.toUpperCase())"
   >
</v-text-field>

Here a text-field from Vuetify is being used but you can use it with an HTML input as well.

Upvotes: 13

Leonardo Cavalcante
Leonardo Cavalcante

Reputation: 1303

The only way I get it to work is:

Vue.directive('uppercase', {
  bind(el, _, vnode) {
    el.addEventListener('input', (e) => {
      e.target.value = e.target.value.toUpperCase()
      vnode.componentInstance.$emit('input', e.target.value.toUpperCase())
    })
  },
})

<v-text-field
    v-model="model"
    v-uppercase
    type="text"
/>

Upvotes: 2

frank
frank

Reputation: 1201

The first answer has problem: the last character is still lower case.

<textarea v-model="remark" 
                    @input="remark=$event.target.value.toUpperCase()"></textarea>

this works, but it requires to write more code if there are many fields.

maybe there is a better solution.

Upvotes: 2

Samson Iyanda
Samson Iyanda

Reputation: 582

I know this is probably an old question but somebody maybe here someday looking for help so why not share what works for me. Two things, the first is, you're going to make a custom component that emits an input event but before tying up this event you're going to use Javascript 'toUpperCase()' method on the value that will be emitted. Second- A custom component also but this time you can watch for the value when it changes then turn the current value to uppercase and bind that value to the internal model changes. Well to save some ink lets dive into some coding...

Vue.component('app-input', {
  props: ['value'],
  template: `<input class="input__field input__first" :value="value" @keyup="keyUpHandler"/>`,
  methods: {
    keyUpHandler($event) {
      this.$emit('input', String($event.target.value).toUpperCase());
    },
  },
});

Vue.component('app-input2', {
  props: ['value'],
  data() {
    return {
      innerValue: '',
    }
  },
  template: `<input class="input__field input__second" v-model="innerValue"/>`,
  watch: {
    // Handles internal model changes.
    innerValue(newVal) {
      this.$nextTick(() => {
        this.$emit('input', newVal);      
      });
    },
    // Handles external model changes.
    value(newVal) {
      this.innerValue = String(newVal).toUpperCase();
    },
  },
  created() {
    if (this.value) {
      this.innerValue = String(this.value).toUpperCase();
    }
  },
});

new Vue({
  el: '#app',
  data: {
    obj: {},
  }
});
.input__field {
  border: 1px solid #000;
  font-size: 20px;
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div class="input">
    <!-- C U S T O M - C O M P O N E N T - 1 -->
    <app-input v-model="obj.first"/>
  </div>
  <p>FIRST- {{ obj.first }}</p>
  <br/>
  <div class="input">
    <!-- C U S T O M - C O M P O N E N T - 2 -->
    <app-input2 v-model="obj.second"/>
  </div>
  <p>SECOND- {{ obj.second }}</p>
</div>

I always prefer the second method but you can play with these two and hopefully it helps you or somebody else.

Upvotes: 0

Jonas Flaam
Jonas Flaam

Reputation: 251

Custom directive:

Vue.directive("uppercase", {
    update: function (el) {
        el.value = el.value.toUpperCase()
    }
})

<input type="text" v-model="myid" placeholder="My ID" v-uppercase/>

Upvotes: 17

D Durham
D Durham

Reputation: 1341

If you only want to store the uppercase value, then the two provided answers would work IF you pass the computed value to the server - I think some mau have missed the "before passing it to the backend" part of you question. However if you want to DISPLAY it in the input in uppercase as the user types and update the actual input v-model in parallel (which is what you are probably already passing to the backend), you would need something like:

new Vue({
  el: '#app',
  data: {
    form: {
      id:''
    }
  },
  methods: {
    forceUpper (e, obj, prop) {
      const start = e.target.selectionStart
      e.target.value = e.target.value.toUpperCase()
      this.$set(obj, prop, e.target.value)
      e.target.setSelectionRange(start, start)
    }
  }
});
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<div id="app">
  <input
    v-model="form.id"
    @input="forceUpper($event, form, 'id')"
  />
  <br><br>
  {{ form }}
</div>

NOTE: If you are using a UI/CSS framework that wraps input elements (such as Quasar), you may need to use the @input.native event instead of @input. @input in those normally just passes the value and not the whole event.

Upvotes: 0

MHD Alaa Alhaj
MHD Alaa Alhaj

Reputation: 3213

You can use javascript function called toUpperCase() like this:

new Vue({
  el: '#app',
  data: {
    myid: ''
  },
  methods: {
    click: function() {
    var str = this.myid.toUpperCase();
      console.log('clicked id=', str)
    }
  }
});
div input {
  text-transform: uppercase
}
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<div id="app">
  <input type="text" v-model="myid" placeholder="My ID" />
  <button type="button" @click="click">Submit</button>
</div>

Now you can remove the css rule if you only want to pass the value capitalized without showing it or either you can keep it. Hope that helps :)

Upvotes: 0

unknowncodder
unknowncodder

Reputation: 246

HTML:

<div id="app">
   <input type="text" v-model="message" />
   <h4>{{ message | uppercase }}</h4>
</div>

Controller:

Vue.filter('uppercase', function (value) {
   return value.toUpperCase()
})

new Vue({
  el: '#app',
  data: {
    message: 'foo'
   }
})

I wish this solves your problem.

Upvotes: -1

Related Questions