I am creating a wizard login form where the Mobile Number is first entered and password is entered next.
Here am trying to focus the password input using
this.$$.passwordInput.focus()
however if am getting the error given below
Uncaught TypeError: Cannot read property 'focus' of undefined
The full code is below
index.html
<div id="login">
<div v-if="flow.mobile">
<form v-on="submit: checkmobile">
<p>
Mobile Number<br>
<input type="text" v-model="mobile_number" v-el="mobileNumber">
</p>
</form>
</div>
<div v-if="flow.password">
<form v-on="submit: checkpassword">
<p>
Password<br>
<input type="password" v-model="password" v-el="passwordInput">
</p>
</form>
</div>
script.js
var demo = new Vue({
el: '#login',
data: {
flow: {
mobile: true,
password: false
}
},
methods: {
checkmobile: function(e) {
e.preventDefault();
this.flow.mobile = false;
this.flow.password = true;
this.$$.passwordInput.focus();
},
checkpassword: function(e) {
e.preventDefault();
}
}
});
Here, we wrap our call to focusInput inside of a nextTick . Using nextTick will allow us to wait until the input is rendered in the DOM. Once it's there, then we can grab it, and focus on it. You can read more about using nextTick on the docs.
Vuex is a state management pattern for vue. js. $t is the injected method from vue. js or Vue. i18n.
Refs are Vue. js instance properties that are used to register or indicate a reference to HTML elements or child elements in the template of your application. If a ref attribute is added to an HTML element in your Vue template, you'll then be able to reference that element or even a child element in your Vue instance.
The $el option in Vue provides Vue with an existing HTML element to mount the Vue instance generated using the new keyword. this. $el. querySelector is used to access HTML elements and modify the element's properties.
Your passwordInput is inside a v-if block, which only gets rendered when you set flow.password
to true; However Vue uses asynchronous rendering, so the v-if block will not be rendered immediately. You can use Vue.nextTick
to wait until it does:
this.flow.password = true;
var self = this;
Vue.nextTick(function () {
self.$$.passwordInput.focus();
});
Read the guide about async rendering for more details.
In Vue.js 2.x you can create your own directive to focus a field automatically:
Vue.directive('focus', {
inserted: function (el) {
el.focus();
},
update: function (el) {
Vue.nextTick(function() {
el.focus();
})
}
})
Then you can use v-focus
attribute on inputs and other elements:
<input v-focus>
Working example: https://jsfiddle.net/LukaszWiktor/cap43pdn/
If you are using vuejs 2, you should read this:
https://v2.vuejs.org/v2/guide/migration.html#v-el-and-v-ref-replaced
--
In this case, in your template:
use ref="passwordInput"
instead v-el="passwordInput"
and in your method:
this.$refs.passwordInput.focus()
I hope this help you!
Glad this worked for some of you. I have no idea why, but after trying every conceivable variation of the accepted answer I could not get the $$.ref property when using v-repeat. I could only access the newly created dom elements like so:
new Vue({
el: '#reporting_create',
data: {
recipients: {
0: {
fname: null,
lname: null,
email: null,
registration: false,
report: false
}
},
curRec:1
},
methods: {
addRecipient: function(){
event.preventDefault();
this.recipients.$add(
this.curRec,
{
fname: null,
lname: null,
email: null,
registration: false,
report: false
}
);
var num = this.curRec;
this.$nextTick(function () {
console.log(this._children[num].$$.rowrec);
newSwitches.find('.switch').bootstrapSwitch();
})
this.curRec++;
}
}})
html:
<template v-repeat="recipients">
<div class="row" v-el="rowrec">
<div>{{$key}}</div>
</div>
</template>
The addRecipients function was called outside the v-repeat so even the suggested answer here did couldn't help
Not sure if there is an issue with doing it this way but it works and I'm tired.
Vue.js 1 works a bit different.
Example:
<textarea v-el:model_message></textarea>
JS:
this.$els.model_message.focus();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With