Is there a way to change a value in the model when an input gets/loses focus?
The use case here is a search input that shows results as you type, these should only show when the focus is on the search box.
Here's 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 here is that magic_flag
should turn to true
when the search box has focus. I could do this manually (using jQuery, for example), but I want a pure Vue.JS solution.
You might also want to activate the search when the user mouses over the input - @mouseover=...
Another approach to this kind of functionality is that the filter input is always active, even when the mouse is in the result list. Typing any letters modifies the filter input without changing focus. Many implementations actually show the filter input box only after a letter or number is typed.
Look into @event.capture.
Another way to handle something like this in a more complex scenario might be to allow the form to track which field is currently active, and then use a watcher.
I will show a quick sample:
...
In my sample here, if the currently-active field is
foo
and the value is 4 characters long, then the next fieldbar
will automatically be focused. This type of logic is useful when dealing with forms that have things like credit card number, credit card expiry, and credit card security code inputs. The UX can be improved in this way.I hope this could stimulate your creativity. Watchers are handy because they allow you to listen for changes to your data model and act according to your custom needs at the time the watcher is triggered.
In my example, you can see that each input is named, and the component knows which input is currently focused because it is tracking the
currentlyActiveField
.The watcher I have shown is a bit more complex in that it is a "deep" watcher, which means it is capable of watching Objects and Arrays. Without
deep: true
, the watcher would only be triggered ifuser
was reassigned, but we don't want that. We are watching the keysfoo
andbar
onuser
.Behind the scenes,
deep: true
is adding observers to all keys onthis.user
. Otherwise Vue does not incur the cost of doing this.A simple watcher would be like this:
Note: If you discover that where I have
handler(user) {
, you could havehandler(oldValue, newValue) {
but you notice that both show the same value, it's because both are a reference to the sameuser
object. Read more here: https://github.com/vuejs/vue/issues/2164Apparently, this is as simple as doing a bit of code on event handlers.