Недавно мне пришлось создать адаптивное многоуровневое меню с помощью 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 Олега Вараксина в блоге « Мысли о разработке программного обеспечения» . |