Недавно мне пришлось создать адаптивное многоуровневое меню с помощью JSF 2.2. Требования: меню должно:
- быть создан с динамической структурой из бэкэнда
- быть отзывчивым, то есть настольным и мобильным
- есть элементы подменю с навигационными ссылками
- поддержка сенсорных событий
- поддержка доступа к клавиатуре
Меню PrimeFaces не было выбора. Они действительно могут быть созданы программно по модели, но:
- они не очень отзывчивы
- Элементы подменю только сворачивают / раскрывают подменю и не могут содержать навигационные ссылки
- …
Ну, а почему бы не выбрать какой-либо плагин на основе jQuery для адаптивных многоуровневых меню? Есть много плагинов. См. Полезный список адаптивных шаблонов навигации и меню . Я выбрал FlexNav .
Но как вывести динамическую структуру меню? ui: повторение здесь не является выбором, потому что структура (вложенные подменю и т. д.) априори не известна. К счастью, есть OmniFaces с o: tree , который позволяет полностью контролировать разметку иерархии дерева, объявляя компоненты JSF или элементы HTML в разметке. o: дерево само по себе не отображает HTML-разметку. Именно то, что мне нужно!
Я закончил с этим XHTML-фрагментом, смешивающим элементы o: treeNode, o: treeNodeItem, o: treeInsertChildren и HTML, определенные в упомянутом меню FlexNav:
|
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
|
<h:outputScript library="js" name="jquery.flexnav.js"/><h:outputStylesheet library="css" name="flexnav.css"/><ul id="mainnavi" class="flexnav" data-breakpoint="640" role="navigation"> <o:tree value="#{mainNavigationBean.treeModel}" var="item"> <o:treeNode level="0"> <o:treeNodeItem> <li class="item"> <a href="#{item.href}" title="#{item.title}">#{item.text}</a> <o:treeInsertChildren/> </li> </o:treeNodeItem> </o:treeNode> <o:treeNode> <ul> <o:treeNodeItem> <li> <a href="#{item.href}" title="#{item.title}">#{item.text}</a> <o:treeInsertChildren/> </li> </o:treeNodeItem> </ul> </o:treeNode> </o:tree></ul><h:outputScript id="mainnaviScript" target="body"> $(document).ready(function () { $("#mainnavi").flexNav({'calcItemWidths': true}); });</h:outputScript> |
TreeModel OmniFaces с элементами меню создается программно. Код Java выглядит следующим образом:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
public TreeModel<NavigationItemDTO> getTreeModel() { // get menu model from a remote service NavigationContainerDTO rootContainer = remoteService.fetchMainNavigation(...); TreeModel<NavigationItemDTO> treeModel = new ListTreeModel<>(); buildTreeModel(treeModel, rootContainer.getNavItem()); return treeModel;}private void buildTreeModel(TreeModel<NavigationItemDTO> treeModel, List<NavigationItemDTO> items) { for (NavigationItemDTO item : items) { buildTreeModel(treeModel.addChild(item), item.getNavItem()); }} |
И конечный результат (настольный вариант):
Обратите внимание, что подменю доступны для нажатия и могут быть расширены при наведении курсора мыши.
Видите ли, JSF является гибким, и иногда вам не нужны полноценные компоненты. Повеселись!
| Ссылка: | Создание динамического адаптивного многоуровневого меню с простым HTML и OmniFaces от нашего партнера по JCG Олега Вараксина в блоге « Мысли о разработке программного обеспечения» . |
