简体   繁体   中英

focus() not working after axios call in Vue JS

I have a form in Vue JS which is submitted via axios call and after axios I want to focus on a specific input element but it is not working properly.

Here is the input :

<input type="text" class="form-control mb-2" :id="'txtTazkira' + s.id" 
 @input="setTxtTazkira($event, s.id)" :value="s.tazkira" />  

The following function is called on form submit:

submitForm() {
  this.form.txtTazkira = this.txtTazkira
  this.form.selectedNotebook = this.selectedNotebook.id
  this.nextSlot = document.getElementById('txtTazkira' + (this.form.slotId + 1))

  axios
    .patch('/Notebook/api/slots/' + this.form.slotId, this.form)
    .then((response) => {
      this.tazkiraSaved = true
      this.fetchSlots()

      this.nextSlot.focus()
      console.log(this.nextSlot)
    })
    .catch((errors) => {
      alert('Unable to save Tazkira, There might be some issues.')
      this.tazkiraSaved = false
    })
},

As it can be seen that after axios call I have this.nextSlot.focus() which does not set focus to the input element. I also tried to execute the following but did not work:

this.$nextTick(() => {
    this.nextSlot.focus();
});  

I also tried the following where I added :ref="'txtTazkira' + s.id" :

<input type="text" class="form-control mb-2" :id="'txtTazkira' + s.id" 
@input="setTxtTazkira($event, s.id)" :value="s.tazkira" :ref="'txtTazkira' + 
s.id">  

And then tried the following in the js but still not working:

var newSlot = 'txtTazkira' + (this.form.slotId + 1);

axios.post(.....)
{
  ...... 
  this.$nextTick(() => {
     this.$refs[newSlot].focus();
   });
}

I searched google and found some related discussions but that did not resolve my issue therefore I posted the question here.

Any help is appreciated in advance.

I started creating a test component in my Vue CLI sandbox app before the first answer was posted. I it wasn't working with

this.$refs.input2.$el.focus();

but did work when I changed it to

this.$refs.input2.focus();

Here is the test component:

<template>
  <div class="set-focus">
    <div class="row">
      <div class="col-md-3">
        <form @submit.prevent="submitForm">
          <div class="form-group">
            <label>Input One</label>
            <input type="text" class="form-control" ref="input1">
          </div>
          <div class="form-group">
            <label>Input Two</label>
            <input type="text" class="form-control" ref="input2">
          </div>
          <button type="submit" class="btn btn-primary">Submit</button>
        </form>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    methods: {
      submitForm() {
        console.log('submitForm')
        // Simulate API call
        setTimeout( () => {
          this.$refs.input2.focus();
        }, 2000)
      }
    }
  }
</script>

The solution for your problem is to use ref .

As explained in documentation :

Despite the existence of props and events, sometimes you might still need to directly access a child component in JavaScript. To achieve this you can assign a reference ID to the child component or HTML element using the ref attribute.

Have a look at this simple snippet:

 <html> <div id="app"> <p><input v-model="myvar1" ref="myvar1"></p> <p><input v-model="myvar2" ref="myvar2"></p> <button @click="doClick(1)">Focus on 1st input</button> <button @click="doClick(2)">Focus on 2nd input</button> </div> <script src="https://unpkg.com/vue@2"></script> <script> new Vue({ el: '#app', data() { return { myvar1: '', myvar2: '', } }, methods: { doClick(id) { this.$refs['myvar'+id].focus() } } }); </script> </html>

BTW, in your axios call you can use finally in order to have code executed independent of the call result:

.finally(() => {
  // your focus code here
})

You can use ref instead of trying to get element by id, it would be much easier:

<input
    type="text"
    class="form-control mb-2"
    ref="'txtTazkira"
    :value="s.tazkira"
    @input="setTxtTazkira($event, s.id)"
/> 

and in code:

this.$refs.txtTazkira.$el.focus();

Also if you set txtTazkira ref to array of inputs, this.$refs.txtTazkira will also be an array with same indexes.

More about ref here

I have a form in Vue JS which is submitted via axios call and after axios I want to focus on a specific input element but it is not working properly.

Here is the input :

<input type="text" class="form-control mb-2" :id="'txtTazkira' + s.id" 
 @input="setTxtTazkira($event, s.id)" :value="s.tazkira" />  

The following function is called on form submit:

submitForm() {
  this.form.txtTazkira = this.txtTazkira
  this.form.selectedNotebook = this.selectedNotebook.id
  this.nextSlot = document.getElementById('txtTazkira' + (this.form.slotId + 1))

  axios
    .patch('/Notebook/api/slots/' + this.form.slotId, this.form)
    .then((response) => {
      this.tazkiraSaved = true
      this.fetchSlots()

      this.nextSlot.focus()
      console.log(this.nextSlot)
    })
    .catch((errors) => {
      alert('Unable to save Tazkira, There might be some issues.')
      this.tazkiraSaved = false
    })
},

As it can be seen that after axios call I have this.nextSlot.focus() which does not set focus to the input element. I also tried to execute the following but did not work:

this.$nextTick(() => {
    this.nextSlot.focus();
});  

I also tried the following where I added :ref="'txtTazkira' + s.id" :

<input type="text" class="form-control mb-2" :id="'txtTazkira' + s.id" 
@input="setTxtTazkira($event, s.id)" :value="s.tazkira" :ref="'txtTazkira' + 
s.id">  

And then tried the following in the js but still not working:

var newSlot = 'txtTazkira' + (this.form.slotId + 1);

axios.post(.....)
{
  ...... 
  this.$nextTick(() => {
     this.$refs[newSlot].focus();
   });
}

I searched google and found some related discussions but that did not resolve my issue therefore I posted the question here.

Any help is appreciated in advance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM