Vue.JS value bound to input with focus

Is there a way to change the value in the model when the input gains / loses focus?

The use case here is a search input that shows the results as you type, they should only be displayed when the focus is on the search field.

Here is what I have so far:

<input type="search" v-model="query"> <div class="results-as-you-type" v-if="magic_flag"> ... </div> 

And then,

 new Vue({ el: '#search_wrapper', data: { query: '', magic_flag: false } }); 

The idea is that magic_flag should become true when the search box has focus. I could do it manually (e.g. using jQuery), but I need a clean Vue.JS solution.

+23
onfocus
source share
3 answers

Apparently, this is as simple as writing some code for event handlers .

 <input type="search" v-model="query" @focus="magic_flag = true" @blur="magic_flag = false" /> <div class="results-as-you-type" v-if="magic_flag"> ... </div> 
+45
source share

You can also activate the search when the user moves the mouse over the input - @mouseover = ...

Another approach to this kind of function is that the filter input is always active, even when the mouse is in the list of results. Entering any letters changes the input of the filter without changing the focus. Many implementations actually show the filter input field only after entering a letter or number.

Take a look at @ event.capture.

0
source share

Another way to handle something similar in a more complex scenario might be to let the form track which field is currently active, and then use the observer.

I will show a quick sample:

 <input v-model="user.foo" type="text" name="foo" @focus="currentlyActiveField = 'foo'" > <input ref="bar" v-model="user.bar" type="text" name="bar" @focus="currentlyActiveField = 'bar'" > 

...

 data() { return { currentlyActiveField: '', user: { foo: '', bar: '', }, }; }, watch: { user: { deep: true, handler(user) { if ((this.currentlyActiveField === 'foo') && (user.foo.length === 4)) { // the field is focused and some condition is met this.$refs.bar.focus(); } }, }, }, 

In my example here, if the current active field is foo and the value is 4 characters long, then the next bar field will be automatically focused. This type of logic is useful when working with forms that have things such as a credit card number, credit card expiration date, and entering a credit card security code. UX can be improved this way.

I hope this can stimulate your creativity. Observers are convenient in that they allow you to listen to changes in your data model and act in accordance with your needs at the time the observer is launched.

In my example, you can see that each input has a name, and the component knows which input is currently focused, because it tracks currentlyActiveField .

The observer that I showed is a little more complicated in the sense that it is a β€œdeep” observer, which means that it is capable of observing objects and arrays. Without deep: true observer will only fire if the user reassigned, but we do not want this. We look foo and bar keys on user .

Behind the scenes, deep: true adds observers to all the keys of this this.user . Otherwise, Vue does not bear the cost of this.

A simple observer would look like this:

 watch: { user() { console.log('user changed'); }, }, 

Note. If you find that where I have handler(user) { , you may have handler(oldValue, newValue) { but you will notice that both show the same value, because both are a reference to the same same user object. Find out more here: https://github.com/vuejs/vue/issues/2164

0
source share

All Articles