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

XPages. Диалог с пользователем. Уведомления с помощью FacesMassage. Часть 2

В прошлой части я дал некоторую теоретическую подоснову о том, что такое FacesMessage в JSF и показал, как можно добавить и отобразить сообщение для пользователя, используя FacesContext.addMessage и компонент xp:messages. Сегодня продолжим: поработаем над отображением сообщений.
Перед тем как продолжить:
1. Здесь и далее работаем с темой Bootstrap. В предыдущем посте описал переход на нее.
2. Я был немного не прав, в том, что все типы сообщения в компоненте xp:messages отображаются одинаково. Если посмотреть внимательно, то в разделе styling свойств компонента можно задать стили отображения для разных типов сообщений: errorClass, fatalClass, infoClass, warnClass. для Bootstrap эти значения следует заполнить соответственно: alert-danger (или alert-error, он чуть отличается), alert-danger/alert-error, alert-info, alert-warning. А свойства styleClass самого компонента выставить на alert, тогда все примет чуть более симпатичный вид.


Тем не менее, хотелось бы несколько доработать отображение. Для отображения сообщений будет использовать Custom Control (он бы все равно понадобился, если давать компоненту xp:messages стилевое оформление).

Шаг 1. Создание Custom Control
Основа для создания была взята отсюда.
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:div rendered="#{javascript:MessageBean.hasMessages()}"
styleClass="#{MessageBean.styleClass}">
<a class="close" data-dismiss="alert" href="#">&#215;</a>
<xp:repeat id="repeat1" rows="30" var="message"
disableOutputTag="true" value="#{MessageBean.messages}">
<xp:text escape="false" id="computedField1" value="#{message.summary}"
style="font-weight:bold">
</xp:text>
<xp:br></xp:br>
<xp:text escape="false" id="computedField2" value="#{message.detail}">
</xp:text>
<br />
</xp:repeat>
</xp:div>
</xp:view>

Пояснения:
1. <xp:div rendered="#{javascript:MessageBean.hasMessages()}" - наши сообщения будут отображаться, только, если в JSF есть сообщения. Для этого обращаемся к методу нашего класса MessageBean.hasMessages(). Он сам чуть ниже, в шаге 2.
2. styleClass="#{MessageBean.styleClass}" - стилевой класс так же определяем динамически
3. <a class="close" data-dismiss="alert" href="#">&#215;</a> - добавим закрывающий крестик, чтобы пользователь мог закрыть (скрыть) сообщение.
4. <xp:repeat id="repeat1" rows="30" var="message"
disableOutputTag="true" value="#{MessageBean.messages}"> - сами получаем из JavaBean.

Шаг 2. Изменения в Java-класса
1. Проверяем, есть ли сообщения
 public static boolean hasMessages() {
return FacesContext.getCurrentInstance().getMessages().hasNext();
}

2. Получаем стилевой класс
 public String getStyleClass() {
FacesMessage message = (FacesMessage) FacesContext.getCurrentInstance().getMessages().next();
Severity severity = message.getSeverity();
String result = "alert fade in";
if (severity == FacesMessage.SEVERITY_INFO)
result += " alert-info";
else if (severity == FacesMessage.SEVERITY_WARN)
result += " alert-warning";
else if (severity == FacesMessage.SEVERITY_ERROR || severity == FacesMessage.SEVERITY_FATAL)
result += " alert-danger";
return result;
}

3. Получаем сообщения
 @SuppressWarnings("unchecked")
public Collection<FacesMessage> getMessages() {
Iterator<FacesMessage> it = FacesContext.getCurrentInstance().getMessages();
Collection<FacesMessage> result = new Vector<FacesMessage>();
while (it.hasNext())
result.add(it.next());
return result;
}

Примечание:
Я не знаю (поверхностный гугл поиск не дал результатов), почему статические методы класса, подключенного как bean и возвращающие значения не воспринимаются на xPage. Может кто-то знает?:) Именно в силу этого новые методы не статичные.

Потрогать и посмотреть текущее решение можно в Demo-приложении.

Недостатки решения и остающиеся проблемы:
1. Если отправить несколько сообщений разного типа (можно попробовать в Demo-приложении), то стиль отображаемого будет = стилю первого сообщения, что не очень корректно. Нужно дорабатывать.
2. Если у самого сообщения, например, отсутствует (пустой) заголовок - то отображается пустая строка. Это тоже не очень.
3. Хотелось бы отображать тип сообщений об успешном действии. Под это дело даже есть стилевое решение - alert-success, но вот проблема - в FacesMessage нет такого типа. И, к сожалению, переопределить класс FacesMessage не удастся. Вернее его переопределить можно, но вот добавить еще один типа сообщения - нет, т.к. класс FacesMessage.Severity имеет private конструктор и будет недоступен из подкласса FacesMessage.
4. Если после отправки сообщения вызвать редирект или открытие и другой страницы - сообщение не будет отображено. Т.е. сохранив документ и открыв исходное представление не получится отобразить сообщение, что все ок и документ сохранен.

С этими недостатками и проблемами будем героически бороться в следующей части;)

Если вам понравился пост, жмите&nbsp;+1, делитесь в соц. сетях и форумах! #xPages-по-русски

Комментарии

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

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

И снова про тараканов, которые иногда возникают в голове. Как-то раз, засыпая, я задумался на курьезными задачками из своей сферы деятельности (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 сообщениях?