Saya menggunakan Vue.js 2.1.10 dan Bootstrap 3.3.7 untuk menampilkan modal yang membuka dialog modal lain. Setiap dialog modal terkandung dalam komponen yang berbeda. Di dalam komponen pertama, ada referensi ke komponen kedua (select-travler).

Menurut dokumentasi Bootsrap, saya harus mengatur fokus dengan mendengarkan acara shown.bs.modal. Ini berfungsi dengan baik untuk mengatur fokus pada kontrol input yang terdapat dalam modal pertama. Masalah: cara ini tidak berfungsi saat modal berada di atas modal lain.

Komponen modal pertama terlihat seperti ini:

<template>
    <div ref="tripEdit" class="modal fade" role="dialog">
        <!-- Inbeded component -->
        <select-travler ref="selectTravler"></select-travler>
        <!-- /Inbeded component -->

        <div class="modal-lg modal-dialog">
            <div class="modal-content">
                <div class="modal-body container form-horizontal">

                    <div class="form-group">
                        <label for="travler_name" class="control-label">
                            Travler's name
                        </label>
                        <input id="travler_name" ref="travler_name"
                            v-model="travler_name"/>
                    </div>
                </div>
            </div>
        </div>

    </div>
</template>

<script>
    export default {
        data () {
            return {
                travler_name: null,
            }
        },

        methods: {
            show (operationType) {
                $(this.$refs.tripEdit).modal('show');

                let that = this;
                $(this.$refs.tripEdit).on('shown.bs.modal', function () {
                    $(that.$refs.travler_name).focus();
                });

                if (operationType === 'newTravel') {
                    this.$refs.selectTravler.show();
                }
            },            
        },
    }
</script>

Komponen ke-2 berisi tata letak yang serupa dengan metode show berikut:

show () {
    $(this.$refs.selectTravler).modal('show');

    let that = this;
    $(this.$refs.selectTravler).on('shown.bs.modal', function () {
        $(that.$refs.people_names).focus();
    });
},

Ketika modal ke-2 terbuka, fokusnya masih pada modal ke-1 di belakang dialog modal ke-2 (saya bisa melihat tanda sisipan berkedip di travler_name). Bagaimana saya bisa mengatur fokus pada people_names ketika modal ke-2 ditampilkan?

1
Warrio 10 Agustus 2017, 18:01

2 jawaban

Jawaban Terbaik

Saya pikir benar-benar ada beberapa masalah yang bermain di sini. Pertama, seperti yang saya sebutkan di komentar di atas, Anda tidak menambahkan dan menghapus event handler shown.bs.modal dengan benar.

Kedua, karena modal kedua Anda bersarang di dalam modal pertama, peristiwa shown.bs.modal akan naik ke modal induk dan pengendalinya akan diaktifkan. Awalnya saya pikir stopPropagation akan menjadi cara yang baik untuk menangani ini, tetapi pada akhirnya, saya hanya menghapus komponen submodal di template.

Berikut adalah contoh dari perilaku ini yang benar-benar berfungsi.

console.clear()

Vue.component("sub-modal", {
  template: "#submodal",
  methods: {
    show() {
      $(this.$el).modal("show")
    },
    onShown(event) {
      console.log("submodal onshown")
      this.$refs.input.focus()
    }
  },
  mounted() {
   $(this.$el).on("shown.bs.modal", this.onShown)
  },
  beforeDestroy() {
    $(this.$el).off("shown.bs.modal", this.onShown)
  }
})

Vue.component("modal", {
  template: "#modal",
  methods: {
    show() {
      $(this.$refs.modal).modal("show")
    },
    showSubModal() {
      this.$refs.submodal.show()
    },
    onShown(event) {
      console.log("parent")
      this.$refs.input.focus()
    }
  },
  mounted() {
    $(this.$refs.modal).on("shown.bs.modal", this.onShown)
  },
  beforeDestroy() {
    $(this.$refs.modal).off("shown.bs.modal", this.onShown)
  }
})

new Vue({
  el: "#app",
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />


<script src="https://unpkg.com/vue@2.2.6/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div id="app">
  <modal ref="modal"></modal>
  <button @click="$refs.modal.show()" class="btn">Show Modal</button>
</div>

<template id="submodal">
  <div class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
          <h4 class="modal-title">Modal title</h4>
        </div>
        <div class="modal-body">
          <input ref="input" type="text" class="form-control">
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>
        </div>
      </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
  </div><!-- /.modal -->

</template>

<template id="modal">
  <div>
    <div ref="modal" class="modal fade" tabindex="-1" role="dialog">

      <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <h4 class="modal-title">Modal title</h4>
          </div>
          <div class="modal-body">
            Stuff
            <input ref="input" type="text" class="form-control">
          </div>
          <div class="modal-footer">
            <button @click="showSubModal" type="button" class="btn btn-primary">Show Sub Modal</button>
          </div>
        </div><!-- /.modal-content -->
      </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->
    <sub-modal ref="submodal"></sub-modal>
  </div>
</template>

Juga, untuk pembaca selanjutnya, saya mendapatkan beberapa informasi berguna tentang cara membuat template untuk komponen modal yang digunakan di atas dari jawaban ini . Khususnya, kecuali jika Anda secara manual menentukan indeks-z untuk modal, modal yang muncul terakhir di HTML akan memiliki indeks-z yang lebih tinggi. Implikasinya adalah komponen submodal harus menempati urutan kedua dalam template.

5
Bert 10 Agustus 2017, 17:56

Ini berarti bahwa elemen yang Anda coba fokuskan tidak direferensikan dengan benar. Mencoba console.log(element); baris sebelum memfokuskan people_names. Untuk melihat apakah Anda mendapatkan elemen yang tepat.

show () {
    $(this.$refs.selectTravler).modal('show');

    let element = this.$refs.people_names;
    $(this.$refs.selectTravler).on('shown.bs.modal', function () {
        $(element).focus();
    });
},

Sudahkah Anda mempertimbangkan v-show untuk membuka dan menutup modals Anda?

0
Christian Ahidjo 10 Agustus 2017, 15:39