Inputs always in uppercase using v-model

I want that the input become into uppercase when something is typed.

I have already tried using css, but the v-model keeps in lowercase.

form-group input {
    text-transform: uppercase;
}

This code below works fine

<input type="text" :value="customer.name" @input="customer.name = $event.target.value.toUpperCase()">

I want to do something like this below

<input type="text" v-model="customer.name" @input="upper($event)">

methods: {
    upper(e) {
        e.target.value = e.target.value.toUpperCase()
    }
}

But it doesn’t work.
Does anyone know how to do it?

Try this:

<input type="text" :value="customer.name.toUpperCase()" @input="customer.name = $event.target.value.toUpperCase()">

And you shouldn’t need any extra on the JS side to work, just the value itself, e.g.

data: {
  customer: { name: 'DEFAULTNAME' }
}
5 Likes

The first portion of code I posted works.
Your code is almost equals mine.

I want to do it with “v-model”

Then use a computed property with a setter.

1 Like

Will not that be pretty verbose?
I have more then 10 fields to do the same thing.

Should I really create all these computed properties for each one?

If you want to use v-model, then yes. Personally, I don’t see why v-model is necessary or especially useful for this. using v-bind:value and @input will be able to handle this much better.

Thank you, @LinusBorg!
I just wanted to know if there was another way to do that.
:value and @input is good to me.
I will make a custom text component with a “:case” attribute and it will solve the problem.

Thank you, once again!

You could use a watcher function on the v-model - bound variables. In the watcher, when change is detected, overwrite the value with newValue.toUpperCase()

This is an old post but I wanted to add my solution that closely matches what the op wanted. My input uses the model w/o any CSS tricks to get a real UPPERCASE string. The input and model are updated in real-time and as a bonus the text caret position is not lost.

<input type="text" v-model="obj.name" @input="forceUpper($event, obj, 'name')" />
methods: {
  forceUppercase(e, o, prop) {
    const start = e.target.selectionStart;
    e.target.value = e.target.value.toUpperCase();
    this.$set(o, prop, e.target.value);
    e.target.setSelectionRange(start, start);
  },
}
5 Likes

@LinusBorg , is it possible to achieve this with something like v-model.number does?
I want to make a custom (what is it called? I don’t think it is directive…?) one, to transform the string to uppercase v-model.uppercase="mytext".

Where should I start?

Those are called modifiers and you can’t make custom ones, they are part of the compiler, essentially.

I see.
Thanks for the answer.

After searching for custom modifier, I found this discussion and its already rejected on 2016.

I ended up using Custom Directives

Vue.directive('uppercase', {
	update (el) {
		el.value = el.value.toUpperCase()
	},
})

<input type="text" v-model="username" v-uppercase>

We can modify this further with v-case="upper" with possible options [“upper”, 'lower", “title”, …etc]
But for now, v-uppercase is all I need.

2 Likes

I have used a global custom directive, it makes text uppercased and emits event manully to update model.

Vue.directive('uppercase',
  {
    inserted: function(el, _, vnode) {
      el.addEventListener('input', async function(e) {
        e.target.value = e.target.value.toUpperCase()
        vnode.componentInstance.$emit('input', e.target.value.toUpperCase())
      })
    }
  })
1 Like

I have the same Issue, I have used @omerciftci but gives error on $emit .

Vue.directive('uppercase', {
  bind(el) {
    el.addEventListener('keyup', () => {
      el.value = el.value.toUpperCase();
    })
  }
})

but this one gives the last charectec to lowercase

You need to separate the binding in two line of codes. First manipulate target element value, then fire input event to update the model/variable.

And try this one I hope it works…

There are some variables missing,

try this…

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

put a variable “e” on the keyup eventListener

1 Like
Vue.directive('uppercase', (el: any, binding: any) => {
   let processedValue = el.value.toUpperCase();
   el.value = processedValue;
   binding.value = el.value;
});