Я уже писал об одном рецепте в готовящейся к выпуску 2. Поваренной книге PrimeFaces . В этом посте я хотел бы опубликовать второй рецепт о небольшой платформе под названием Dialog Framework
. Мне лично это нравится, потому что я помню свои дорогостоящие попытки сделать то же самое с помощью Struts Framework. Если вы хотите загрузить внешнюю страницу во всплывающее окно и отправить на нее некоторые данные, вам нужно было вызвать window.open
со скрытой формой, установить переданные значения в скрытые поля, отправить форму на внешнюю страницу с помощью JavaScript и подождать, пока страница готова к использованию в window.onload
или document.ready
. Много ручной работы. PrimeFaces делает эту работу за вас и, кроме того, предоставляет p:dialog
красивый пользовательский интерфейс в качестве замены всплывающего окна.
Регулярное использование диалога PrimeFaces — декларативный подход с p:dialog
. Помимо этого декларативного подхода, существует и программный подход. Программный подход основан на программном API, в котором диалоги создаются и уничтожаются во время выполнения. Это называется Dialog Framework
. Dialog Framework используется для открытия внешних страниц в динамически генерируемом диалоге. Использование довольно простое, RequestContext
предоставляет два метода: openDialog
и closeDialog
которые позволяют открывать и закрывать динамические диалоги. Кроме того, Dialog Framework позволяет передавать данные обратно со страницы, отображаемой в диалоговом окне, на страницу вызывающего абонента.
В этом рецепте мы продемонстрируем все функции, доступные в Dialog Framework. Мы откроем диалог с опциями программно и передадим параметры на страницу, отображаемую в этом диалоге. Мы также встретимся с возможностью общения между исходной (вызывающей) страницей и диалогом.
Готовиться
Для Dialog Framework требуется следующая конфигурация в faces-config.xml
:
1
2
3
4
5
|
< application > < action-listener >org.primefaces.application.DialogActionListener</ action-listener > < navigation-handler >org.primefaces.application.DialogNavigationHandler</ navigation-handler > < view-handler >org.primefaces.application.DialogViewHandler</ view-handler > </ application > |
Как это сделать…
Мы разработаем страницу с переключателями, чтобы выбрать одну из доступных книг PrimeFaces для рейтинга. Сам рейтинг происходит в диалоге после нажатия на кнопку « Rate the selected book
.
Фрагмент кода XHTML на снимок экрана приведен ниже.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
< p:messages id = "messages" showSummary = "true" showDetail = "false" /> < p:selectOneRadio id = "books" layout = "pageDirection" value = "#{dialogFrameworkBean.bookName}" > < f:selectItem itemLabel = "PrimeFaces Cookbook" itemValue = "PrimeFaces Cookbook" /> < f:selectItem itemLabel = "PrimeFaces Starter" itemValue = "PrimeFaces Starter" /> < f:selectItem itemLabel = "PrimeFaces Beginner's Guide" itemValue = "PrimeFaces Beginner's Guide" /> < f:selectItem itemLabel = "PrimeFaces Blueprints" itemValue = "PrimeFaces Blueprints" /> </ p:selectOneRadio > < p:commandButton value = "Rate the selected book" process = "@this books" actionListener = "#{dialogFrameworkBean.showRatingDialog}" style = "margin-top: 15px" > < p:ajax event = "dialogReturn" update = "messages" listener = "#{dialogFrameworkBean.onDialogReturn}" /> </ p:commandButton > |
Страница в диалоговом окне представляет собой полную страницу bookRating.xhtml
с компонентом рейтинга p:rating
. Он также показывает название книги, выбранной для рейтинга.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<! DOCTYPE html> < f:view contentType = "text/html" locale = "en" > < f:metadata > < f:viewParam name = "bookName" value = "#{bookRatingBean.bookName}" /> </ f:metadata > < h:head > < title >Rate the book!</ title > </ h:head > < h:body > < h:form > What is your rating for the book < strong >#{bookRatingBean.bookName}</ strong >? < p /> < p:rating id = "rating" > < p:ajax event = "rate" listener = "#{bookRatingBean.onrate}" /> < p:ajax event = "cancel" listener = "#{bookRatingBean.oncancel}" /> </ p:rating > </ h:form > </ h:body > </ f:view > </ html > |
Следующий скриншот демонстрирует, как выглядит диалог.
Щелчок по звездочке рейтинга или символ отмены закрывает диалог. На странице источника (звонящего) отображается сообщение с выбранным значением рейтинга в диапазоне от 0 до 5.
Самая интересная часть — логика в бобах. Компонент DialogFrameworkBean
открывает страницу рейтинга в диалоговом окне, вызывая метод openDialog()
с результатом, параметрами и параметрами POST для экземпляра RequestContext
. Кроме того, bean-компонент определяет прослушиватель AJAX onDialogReturn()
который вызывается, когда данные (выбранный рейтинг) возвращаются из диалога после его закрытия.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@Named @ViewScoped public class DialogFrameworkBean implements Serializable { private String bookName; public void showRatingDialog() { Map<String, Object> options = new HashMap<String, Object>(); options.put( "modal" , true ); options.put( "draggable" , false ); options.put( "resizable" , false ); options.put( "contentWidth" , 500 ); options.put( "contentHeight" , 100 ); options.put( "includeViewParams" , true ); Map<String, List<String>> params = new HashMap<String, List<String>>(); List<String> values = new ArrayList<String>(); values.add(bookName); params.put( "bookName" , values); RequestContext.getCurrentInstance().openDialog( "/views/chapter11/bookRating" , options, params); } public void onDialogReturn(SelectEvent event) { Object rating = event.getObject(); FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "You rated the book with " + rating, null ); FacesContext.getCurrentInstance().addMessage( null , message); } // getters / setters ... } |
Компонент BookRatingBean
определяет двух слушателей для Rating component
. Они вызываются, когда пользователь нажимает на звездочку и символ отмены соответственно. Мы вызываем closeDialog()
для экземпляра RequestContext
чтобы запустить закрытие диалога и передать текущее значение рейтинга упомянутому слушателю onDialogReturn()
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@Named @RequestScoped public class BookRatingBean { private String bookName; public void onrate(RateEvent rateEvent) { RequestContext.getCurrentInstance().closeDialog(rateEvent.getRating()); } public void oncancel() { RequestContext.getCurrentInstance().closeDialog( 0 ); } // getters / setters ... } |
Как это работает…
RequestContext
предоставляет два метода с одинаковым именем openDialog
для динамического открытия диалога во время выполнения. Первый имеет только один параметр — логический результат, используемый для разрешения случая навигации. Второй имеет три параметра — результат, параметры конфигурации диалога и параметры, которые отправляются в представление, отображаемое в диалоге. Мы использовали второй вариант в примере. Опции помещаются в Map
как ключ, пары значений. Параметры также помещаются в Map
. В нашем случае мы ставим название выбранной книги. После этого имя получено на странице bookRating.xhtml
через f:viewParam
. f:viewParam
устанавливает переданный параметр в BookRatingBean
, чтобы он был доступен в заголовке над компонентом Rating
.
Совет: Пожалуйста, обратитесь к Руководству пользователя PrimeFaces, чтобы увидеть полный список поддерживаемых параметров конфигурации диалога.
Давайте пройдем через жизненный цикл запрос-ответ. Как только ответ получен от запроса, вызванного командной кнопкой, создается диалог с iframe
внутри. URL-адрес iframe
указывает на полную страницу, в нашем случае bookRating.xhtml
. Страница будет перемещена вниз и показана в диалоговом окне. Как видите, всегда есть два запроса: первый начальный POST и второй GET, отправленный iframe. Обратите внимание, что Dialog Framework работает только с начальными AJAX-запросами. Не AJAX-запрос игнорируется. Также обратите внимание, что заголовок диалога взят из HTML-элемента title
.
Как мы уже упоминали выше, диалог можно закрыть программным способом, invoking
метод closeDialog
для экземпляра RequestContext
. На странице вызывающей стороны кнопка, запускающая диалог, должна иметь прослушиватель AJAX, чтобы событие dialogReturn
могло получать любые данные из диалога. Данные передаются в качестве параметра в метод closeDialog(Object data)
. В этом примере мы передаем положительное целочисленное значение rateEvent.getRating()
или 0
.
Ссылка: | PrimeFaces: Открытие внешних страниц в динамически генерируемом диалоге от нашего партнера по JCG Олега Вараксина в блоге « Мысли о разработке программного обеспечения» . |