К основному контенту

XPages. Как сделать тур (Feature Tour) по приложению

Если вы задавались вопросом: как сделать обучение по возможностям своего приложения или рассказать о новых возможностях? - эта статья для вас.
Я опробовал 2 плагина для создания этой возможности: JQuery JoyRide и Bootstrap Tour. В итоге остановился на Bootstrap Tour.
Причин на то несколько:
1. Использую Bootstrap для своих приложений и стилистически больше походит.
2. На мой взгляд, Bootstrap Tour более корректно работает с Bootstrap темой.

В статье я описываю как подключить и использовать именно Bootstrap Tour. По тому, как подключить и использовать JoyRide можно прочесть в блоге Mark Roden - Xomino.com.

Шаг 1. Скачиваем и подключаем ресурсы

  1. Скачиваем последнюю версию с GitHub
  2. Распаковав все идем в папочку build, где лежат css- и js-файлы.
  3. Если вы используете Bootstrap в своем приложении, вам понадобятся только
    • bootstrap-tour.min.css
    • bootstrap-tour.min.js
  4. В противном случае вам нужны
    • bootstrap-tour-standalone.min.css
    • bootstrap-tour-standalone.min.js
    • + библиотека jquery
  5. В Domino Designer открываем Navigator или Package Explorer, ищем папку WebContent и перетаскиваем туда нужные файлы. Желательно в подпапку.

Шаг 2. Подключаем ресурсы к XPage

Так как Bootstrap Tour требует инициализацию объектов, воспользуемся финтом, который уже был использован при подключении dGrowl уведомлений - Dojo Module Path + AMD loading.
<xp:this.resources>
 <xp:dojoModulePath url="/boot-tour/bootstrap-tour.min" prefix="bootTour">
 </xp:dojoModulePath>
 <xp:styleSheet href="/boot-tour/bootstrap-tour.min.css"></xp:styleSheet>  
</xp:this.resources>

Шаг 3. Инициализируем тур параметрами

В блоке <script> или <xp:scriptBlock> пишем:
var tour;
require([ "bootTour", "dojo/domReady!" ],
 function(bootTour) {
  tour = new Tour({
   //задаем параметры тура и шагов
   //пример тут
   //об основных опциях чуть ниже
  });
 }   
);

Некоторые атрибуты объекта Tour и его шагов.

  • name - название тура. Используется для хранения информации о шагах тура (чтобы в рамках приложения или страницы можно было использовать более одного тура)
  • steps - json описание списка шагов. Индекс шага начинается с 0.
  • backdrop - boolean значение, означающее отображать ли рамку вокруг элемента, к которому идет пояснение
Шаг (step)
  • element - строковое значение jquery селектор id элемента или класса. Если id, то значение должно быть "#id". Важно! Речь идет о статическом id html тега, а не о динамическом id, который генерирует XPages. О том, как обойти данный момент и подставить динамический id - см
  • placement - то, с какой стороны будет отображаться подсказка. У объекта Tour и у каждого Step есть атрибут smartPlacement, установленный по умолчанию в true. Отвечает он за то, чтобы подсказка сама определяла, где лучше быть ей показанной. НО атрибут placement у step по умолчанию определен как right, а значит именно справа будет всегда появляться подсказка. Для работы smartPlacement нужно переставить значение в 'auto'
  • title - название подсказки. Поддерживает HTML. Не обязателен
  • content - содержимое подсказки. Поддерживает HTML. Не обязателен
Подробнее об этих и других атрибутах и методах см. в документации к BootstrapTour.

Шаг 4. Запускам тур

Тут все просто:
tour.init();
tour.start();

Есть некоторые нюансы.

  1. Если тур был закончен (закрыт) на любом из шагов, в переменных проставляется, что тур завершен и метод .ended() вернет true. В этом случае .start() ничего не даст. Но в метод .start() принимает так же boolean параметр force. Вызов .start(true) вызовет тур с того шага, на котором он был закрыт (последний шаг так же храниться в переменных).
  2. Если нужно полностью перезапустить тур с первого (нулевого) шага, нужно выполнить .restart().

Шаг 5. Как привязаться к компоненту, а не HTML тегу

Как известно, XPages генерирует итоговый id динамически, исходя из дерева компонентов и можно получить его в клиентском скрипте через '#{id:elementId}'. Но для jquery селектора это не походит, т.к. id содержит ":". Mark Roden написал сниппет, заменяющий селектор $('#id'). Но в случае с BootstrapTour нужен не сам селектор, а только его внутренняя часть, поэтому я немного дописал сниппет, добавив еще 1 параметр:
function x$(idTag, idOnly, param){
   idTag=idTag.replace(/:/gi, "\\:")+(param ? param : "");
   if (idOnly)
    return "#"+idTag;
   else
    return($("#"+idTag));
}

Итого

Плагин интересный, довольно функциональный. В реалиях XPages с ним нужно несколько помучиться, конечно. Можно посмотреть итог в Демо-приложении на Bluemix (к сожалению, это демо на Bluemix пока не доступно из-за некоторых проблем) или скачав демо-базу с Google.Drive или Bitbucket

Комментарии

Популярные сообщения из этого блога

Занимательные алгоритмы. Поиск цикла в односвязном списке

И снова про тараканов, которые иногда возникают в голове. Как-то раз, засыпая, я задумался на курьезными задачками из своей сферы деятельности (Lotus Notes), которые можно было бы задать на собеседовании, плавно перешел к воспоминаниям о своих первых собеседования, когда опыта работы еще не было. Опыт самих собеседований у меня не велик а места, где задавались действительно интересные задачи (а не задачки типа: написать сортировку массива любым известным способом) вообще равны одному - это ABBYY. Как минимум одна задачка в списке на знание и понимание классических алгоритмов, описанных в книге Дональда Кнута -  Искусство программирования .

Unit-testing object validation when validator has DI

Summary Unit test object validation when validator(s) has a dependency. For instance, we have some custom field and cross-field validators. Want to test their combination. Additionally some of validators have dependencies, injected through constructor or setters. You're not using property injection, right? Shortcut If you are just searching for an answer, here's the fast way: Declare CustomConstraintValidatorFactory that implements javax.validation.ConstraintValidatorFactory Override getInstance method and on facing your constraint validator class instantiate it Otherwise delegate validator construction to org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorFactoryImpl Build validator factory and provide it your CustomConstraintValidatorFactory Build validator, using that factory... Go to demo project on GitHub for details:  https://github.com/MrArtemAA/blog-demos/blob/master/test-validator-with-injection/src/test/java/ru/artemaa/d

Lotus Notes FAQ. 8/9 Eclipse. Как настроить уведомления о Sametime сообщениях

Н а написание данной "инструкцию" натолкнул мой коллега. Помню, первый раз сам долго искал, как отключить постоянно выпрыгивающие уведомления о новых сообщениях в Sametime. И так, речь идет о клиентах IBM Notes 8+ версии Standart (Eclipse based). Как настроить уведомления о Sametime сообщениях?