将焦点设置在第二级引导模式中包含的输入控件上

时间:2017-08-10 15:01:49

标签: javascript vue.js components bootstrap-modal vuejs2

我使用Vue.js 2.1.10和Bootstrap 3.3.7来显示打开另一个模态对话框的模态。每个模态对话框都包含在一个不同的组件中。在第一个组件内部,有一个对第二个组件(select-travler)的引用。

根据Bootsrap documentation,我必须通过聆听事件shown.bs.modal来设定焦点。这非常适合将焦点设置在第一个模态中包含的输入控件上。 问题:当模态高于另一个模态时,这种方式不起作用。

第一个模态组件如下所示:

<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>

第二个组件包含一个类似的布局,其中包含以下show方法:

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

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

当第二个模态打开时,焦点仍然在第二个模态对话框后面的第一个模态上(我可以看到travler_name中的插入符号闪烁)。如何显示第二个模态时,如何将焦点设置在people_names上?

3 个答案:

答案 0 :(得分:4)

我认为这里确实存在几个问题。首先,正如我在上面的评论中提到的,您没有正确添加和删除shown.bs.modal事件处理程序。

其次,因为你的第二个模态嵌套在第一个模态中,shown.bs.modal事件将冒泡到父模态,它的处理程序将会触发。最初我认为stopPropagation是处理此问题的好方法,但最后,我只是在模板中解除了submodal组件的嵌套。

以下是此行为的实际工作示例。

&#13;
&#13;
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",
})
&#13;
<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>
&#13;
&#13;
&#13;

此外,对于未来的读者,我获得了一些有用的信息,有关如何从this answer构建上面使用的模态组件的模板。具体来说,除非您手动为模态指定z-index,否则HTML中最后出现的模式将具有更高的z-index。意味着submodal组件需要在模板中排在第二位。

答案 1 :(得分:1)

我遇到了类似的问题。 a b-modal 迫使焦点停留在模态中。您可以通过添加 no-enforce-focus 属性来禁用它。

<块引用>

no-enforce-focus Boolean false 禁用强制聚焦例程 在模态内保持焦点

https://bootstrap-vue.org/docs/components/modal

答案 2 :(得分:0)

这意味着您正在尝试聚焦的元素未正确引用。 在关注people_names之前尝试console.log(element);该行。看看你是否得到了正确的元素。

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

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

你有没有考虑过v-show来打开和关闭你的模态?