Поиск по этому блогу

суббота, 11 октября 2014 г.

GWT + Bootstrap Tooltips and Popovers. How to hide popover

Tooltip - всплывающая подсказка при наведении курсора мыши на элемент.
Popover - всплывающее окно, появляющееся при клике на элементе.

Официальная документация Bootstrap


Как работают Tooltips в Bootstrap

Как работают Popovers в Bootstrap

Пример работы с Tooltip и Popover


Для того, чтобы у элемента показывался tooltip достаточно написать ему атрибуты
<button type="button" 
  class="btn btn-default" 
  data-toggle="tooltip" 
  data-placement="left" 
  title="Tooltip on left">
  Tooltip on left
</button>

Эти атрибуты определяют следующее

  1. data-toogle = "tooltip" свойство задает что у элемента будет tooltip
  2. data-placement = "left" позиция, в которой будет показываться tooltip
  3. title = "Help text" текст, который будет показываться в tooltip

Теперь для того чтобы по наведению на элемент показывался tooltip необходимо написать код 
$('.btn').tooltip();

Теперь у всех элементов у которых прописан class="btn" и заданы атрибуты title, data-toogle, data-placement будет показываться tooltip при наведении курсора.

Для того, чтобы у элемента по клику показывался popover достаточно написать ему атрибуты
<button type="button" 
  class="btn btn-default" 
  data-container="body" 
  data-toggle="popover" 
  data-placement="top" 
  data-content="Lorem ipsum dolor sit amet, consectetur adipisicing elit.">
  Popover on top
</button>

Тут атрибуты немного поменялись
  1. data-toogle = "popover" теперь у элемента будет pover
  2. data-placement = "top" позиция для popver теперь будет top
  3. data-content = "Popover text" тут задается текст, который будет показываться в Popover

Точно также как и с tooltip для того чтобы popover показывался по клику необходимо написать код 
$('.btn').popover();

Теперь у всех элементов у которых прописан class="btn" и заданы атрибуты data-toogle, data-placement и data-content будет показываться popover при клике.

Как убрать Popover по клику в другом месте


Если с появлением и исчезанием tooltip все просто, он появляется и исчезает при наведении и убирании курсора соответственно. То с Popover ситуации поинтереснее, он появляется по клику на элементе и исчезает тоже по клику на элементе, но нам необходимо чтобы он убирался когда пользователь просто кликает в любое место на экране. Вот демонстрация как это сделать.

Демонстрация как убирать Popover

Вот код который убирает Popover при клике на любое место на экране. Здесь мы слушаем события клика по элементу body, в котором лежат все элементы интерфейса. Далее для всех элементов, у которых есть атрибут data-toggle="popover" мы проверяем условие и если условие выполняется, то убираем Popover.

$('body').on('click', function (e) {
    $('[data-toggle="popover"]').each(function () {
        if (!$(this).is(e.target) 
            && $(this).has(e.target).length === 0 
            && $('.popover').has(e.target).length === 0) {
               $(this).popover('hide');
        }
    });
});

GWT + Bootstrap Tooltips and Popovers


Теперь самое интересное - как соединить Bootstrap и GWT. Будем считать что библиотека Bootstrap.js уже подключена к нашему gwt проекту и поэтому мы можем писать нативный JavaScript код и вызывать методы для работы с Tooltip и Popover.  Допустим у нас есть элемент интерфейса, для которого мы хотим показывать tooltip или по клику на него показывать Popover.
Он может быть описан в uiBinder так
<span class="help-text" ui:field="learnMoreButton">Learn More</span>

или так (это для показа Tooltip)
<span ui:field="learnMoreButton"
      class=="has-tooltip-users" 
      title="learn Much More" 
      tooltipPlace="left">Learn More
</span>

В Java классе для него создано соответствующее поле.
@UiField
Element learnMoreButton;

Создадим специальный класс для работы с Tooltip и Popover. В нем мы напишем нативные методы для вызова Bootstrap методов.

Класс BootstrapUtilities  для работы с нативным JavaScript кодом


public class BootstrapUtilities {
 
 public static native void initializeTooltips(String className)/*-{
  $wnd.$('.' + className).tooltip('destroy');
  $wnd.$('.' + className).tooltip();
 }-*/;
 
 public static void initializeTooltip(Element element, 
            String position, String title) {
  element.setAttribute("data-toggle", "tooltip");
  element.setAttribute("data-placement", position);
  element.setAttribute("title", title);
  initializeTooltip(element);
 }
 
 public static native void initializeTooltip(Element element)/*-{
  $wnd.$(element).tooltip();
 }-*/;
 
 public static native void initializePopover(Element element)/*-{
  $wnd.$(element).popover();
 }-*/;
 
 public static void initializePopover(Element element, String position, 
   String content) {
  element.setAttribute("data-toggle", "popover");
  element.setAttribute("data-placement", position);
  element.setAttribute("data-content", content);
  initializePopover(element);
 };
 
 public static native void hidePopover(Element element)/*-{
  $wnd.$(element).popover('hide');
 }-*/;
 
}
 

Все что нам теперь осталось - это просто обратится к методам из класса BootstrapUtilities для того, чтобы показывать Tooltip или Popover.

Теперь для всех элементов у которых прописан class="has-tooltip-users" будет показываться tooltip.
BootstrapUtilities.initializeTooltips("has-tooltip-users");

Теперь по клику на элемент learnMoreButton будет показываться Popover.
BootstrapUtilities.initializePopover(learnMoreButton, "top", message);


Как в GWT убрать появившийся Popover


Для этого нам понадобится специальное поле типа Long, в котором мы будем хранить время, когда был произведен клик по элементу. 
private Long learnMoreClicked;

В момент клика по элементу мы будем запоминать время
learnMoreClicked = System.currentTimeMillis();

Далее при нажатии по свободному месту на экране мы будем отслеживать, что с момента клика по элементу, к которому привязан Popover прошло более 250 миллисекунд.
System.currentTimeMillis() - learnMoreClicked > 250

RootPanel - корневая панель, в которой содержаться все элементы интерфейса. Поэтому нужно слушать клики пользователя по этой панели, чтобы убирать Popover.

Вешаем слушателя событий на кнопку и тут же подписываем RootPanel на событие Click. Также запоминаем время клика.
Event.sinkEvents(learnMoreButton, Event.ONCLICK);
Event.setEventListener(learnMoreButton, new EventListener() {
 
    @Override
    public void onBrowserEvent(Event event) {
      RootPanel.get().sinkEvents(Event.ONCLICK);
      learnMoreClicked = System.currentTimeMillis();
    }
 
});

Вешаем слушателя событий на RootPanel и при выполнении условия, что с момента клика по элементу до момента клика по RootPanel прошло более 250 миллисекунд
убираем Popover и отписываем панель от слушания событий
RootPanel.get().addHandler(new ClickHandler() {
 
    @Override
    public void onClick(ClickEvent event) {
 if (learnMoreClicked != null 
          && System.currentTimeMillis() - learnMoreClicked > 250) {
         BootstrapUtilities.hidePopover(learnMoreButton);
  RootPanel.get().unsinkEvents(Event.ONCLICK);
 }
    }
}, ClickEvent.getType());

Убирается Popover c помощью метода hidePopover() из класса BootstrapUtilities
BootstrapUtilities.hidePopover(learnMoreButton);

public static native void hidePopover(Element element)/*-{
  $wnd.$(element).popover('hide');
 }-*/;

Комментариев нет:

Отправить комментарий