it-roy-ru.com

Twitter bootstrap фокус модального поля ввода

У меня есть следующая модальная форма из примера:

<!-- Button to trigger modal -->
<a href="#myModal" role="button" class="btn" data-toggle="modal">Launch demo modal</a>

<!-- Modal -->
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 id="myModalLabel">Modal header</h3>
  </div>
  <div class="modal-body">
    Enter something: <input type="text" id="myInput">
  </div>
  <div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <button class="btn btn-primary">Save changes</button>
  </div>
</div>

Я хочу, чтобы мое поле ввода было сфокусировано после показа модального окна.
Я попробовал как автофокус, так и установить фокусировку поля на событии $('modal').shown(). Это своего рода поле фокусировки (у меня есть другое событие, которое показывает метку, когда поле сфокусировано), но на самом деле поле не сфокусировано, и мне нужно нажать TAB, чтобы снова сфокусировать его. Я также попробовал что-то вроде этого:

$(".modal").on('shown', function() {
    $(this).find("[autofocus]:first").focus();
});

и установка атрибута autofocus:"autofocus" для моего поля. Это дало тот же эффект.
Все, что я пробовал, работает, когда модальный - просто обычный div, он фокусируется на загрузке страницы. Но когда модал вызывается кнопкой - ничего не работает (конечно, я также меняю логику, когда модал - это просто обычный div, я могу сфокусировать его на нагрузке, когда я запускаю кнопкой, я принимаю это во внимание и пытаюсь решить его соответствующим образом).

То, что я хочу, это просто поле для фокусировки после загрузки модального режима, чтобы на нем был мигающий курсор, и пользователь мог просто начать печатать.

Единственное, что сработало, - это изменение самого bootstrap.js, я поместил $("#myInput").focus() где-то внутри модального раздела bootstrap.js, но я забыл, где это было, и второе - я думаю, что не очень хорошо менять API bootstrap.js, там должно быть проще и более элегантное решение. Посоветуйте мне пожалуйста, спасибо xD

UPDATE:
Прежде всего, спасибо за вашу помощь! Благодаря вам я понял, что у меня есть проблема Rails.

Вот что я сделал:
1). Rails generate controller home index
2). app/views/home/index.html и app/assets/javascript/something.js похожи на этот jsFiddle, предоставленный robertklep : http://jsfiddle.net/JCaFp/
4). jquery-1.9.1.js и bootstrap.js находятся в app/assets/javascript/ (оба свежие с сайта, ничего не изменилось)
5). app/views/layouts/application.html.erb - я думаю, этот файл является ключом нашего решения:

<!DOCTYPE html>
<html>
<head>
  <title>Udc</title>
  <%= stylesheet_link_tag    "application", :media => "all" %>
  <%= javascript_include_tag "application" %>
  <%= csrf_meta_tags %>
</head>
<body>

<%= yield %>

</body>
</html>

Все еще не работает. Все js-файлы включаются, но когда я открываю свой модал в браузере - ввод фокусируется на мгновение и снова становится не сфокусированным.

Я также попробовал это:

  <%= javascript_include_tag "jquery" %>
  <%= javascript_include_tag "bootstrap" %>
  <%= javascript_include_tag "somehow" %>

Все тот же материал.
Предложения? :)

UPDATE:

Решил это!

После изменения моего somehow.js на

$(document).ready(function() {
    $(".modal").on('shown', function() {
        $(this).find("[autofocus]:first").focus();
    });
});

и application.html.erb таблицу стилей для:

  <%= javascript_include_tag "jquery" %>
  <%= javascript_include_tag "bootstrap" %>
  <%= javascript_include_tag "somehow" %>

это работает как ожидалось. Еще раз спасибо!

53
konnigun

Я думаю, что имя показанного изменилось в Bootstrap 3, как описано в посте в этом .

Как отмечает @MrDBA , в Bootstrap 3, имя события изменено на shown.bs.modal.

Итак, для Bootstrap 3 используйте:

$('#myModal').on('shown.bs.modal', function () {
    $('#myInput').focus();
})
81
David Kirkland

Для общего решения, которое не требует определенного кода для каждого диалога, вы можете использовать это:

$('.modal').on('shown.bs.modal', function () {
  $(this).find('input:text:visible:first').focus();
})
39
pschwamb

Попробуйте удалить tabindex="-1", и это работает хорошо.

Так что измени это:

<div class="modal fade" id="modalID" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">

К этому:

<div class="modal fade" id="modalID" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
11
Sunil Shivalkar

Просто изменив $(this).find("[autofocus]:first").focus(); на $(this).find("#myInput").focus();, он заработал для меня. Если вы изменили Bootstrap API и хотите отменить это изменение, вы всегда можете просто повторно загрузить и заменить файл.

7
Austin Cummings

Я удалил tabindex = "- 1", и это работает так хорошо.

Мой HTML-код до изменений:

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">

Мой HTML-код после изменений:

<div class="modal fade" id="myModal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">

Мой входной код:

<input id="tblModalNombreConductor" type="text" maxlength="50" placeholder="Ej: Armando Casas" autofocus/>

И у меня нет конфигураций в моем коде Javascript.

6
Richard Rebeco

Если у вас есть проблемы с «connected.bs.modal», просто установите время ожидания.

setTimeout(function() {
$('#myInput').focus();
}, 500);
6
hacklover

Я думаю, что обновленный ответ довольно умный. Вот еще один способ решить это.

Js-файл Bootstrap 3.2 содержит скрипт для управления фокусом во время и после перехода модального фейда. Это мешает любому jQuery, javascript или Rails + HTML5, фокусирующемуся на поле формы в модальном режиме - bootstrap удаляет ваш фокус после модальных загрузок. 

Чтобы удалить возможность начальной загрузки переопределить ваш фокус, закомментируйте эту строку в области модального скрипта:

transition ?
    that.$element.find('.modal-dialog') // wait for modal to slide in
      .one($.support.transition.end, function () {
        // that.$element.focus().trigger(e)
        // the line above is stealing your focus after modal loads!
      })
      .emulateTransitionEnd(300) :
    that.$element.focus().trigger(e) 

Теперь ваше поле должно иметь возможность фокусироваться в любой модальной форме. 

3
Deborah

Вы можете сделать: Например 

<%= f.text_field :first_name, class: "form-control", placeholder: "Enter first name", autofocus: true%>

просто добавьте это: автофокус: правда

1
Raz

Вы также можете попробовать

$('#the-modal').on('shown.bs.modal', function(e) {
    $('#the-input').focus();
});
0
ctf0