META-INF.resources.primefaces.menu.menu.panelmenu.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of primefaces Show documentation
Show all versions of primefaces Show documentation
PrimeFaces is one of the most popular UI libraries in Java EE Ecosystem and widely used by software companies, world renowned brands, banks, financial institutions, insurance companies, universities and more.
PrimeFaces.widget.PanelMenu = PrimeFaces.widget.BaseWidget.extend({
init: function(cfg) {
this._super(cfg);
this.headers = this.jq.find('> .ui-panelmenu-panel > h3.ui-panelmenu-header:not(.ui-state-disabled)');
this.menuContent = this.jq.find('> .ui-panelmenu-panel > .ui-panelmenu-content');
this.menuitemLinks = this.menuContent.find('.ui-menuitem-link:not(.ui-state-disabled)');
this.menuText = this.menuitemLinks.find('.ui-menuitem-text');
this.treeLinks = this.menuContent.find('.ui-menu-parent > .ui-menuitem-link:not(.ui-state-disabled)');
//keyboard support
this.focusedItem = null;
this.menuText.attr('tabindex', -1);
//ScreenReader support
this.menuText.attr('role', 'menuitem');
this.treeLinks.find('> .ui-menuitem-text').attr('aria-expanded', false);
this.bindEvents();
if(this.cfg.stateful) {
this.stateKey = 'panelMenu-' + this.id;
}
this.restoreState();
},
bindEvents: function() {
var $this = this;
this.headers.mouseover(function() {
var element = $(this);
if(!element.hasClass('ui-state-active')) {
element.addClass('ui-state-hover');
}
}).mouseout(function() {
var element = $(this);
if(!element.hasClass('ui-state-active')) {
element.removeClass('ui-state-hover');
}
}).click(function(e) {
var header = $(this);
if(header.hasClass('ui-state-active'))
$this.collapseRootSubmenu($(this));
else
$this.expandRootSubmenu($(this), false);
$this.removeFocusedItem();
header.focus();
e.preventDefault();
});
this.menuitemLinks.mouseover(function() {
$(this).addClass('ui-state-hover');
}).mouseout(function() {
$(this).removeClass('ui-state-hover');
}).click(function(e) {
var currentLink = $(this);
$this.focusItem(currentLink.closest('.ui-menuitem'));
var href = currentLink.attr('href');
if(href && href !== '#') {
window.location.href = href;
}
e.preventDefault();
});
this.treeLinks.click(function(e) {
var link = $(this),
submenu = link.parent(),
submenuList = link.next();
if(submenuList.is(':visible'))
$this.collapseTreeItem(submenu);
else
$this.expandTreeItem(submenu, false);
e.preventDefault();
});
this.bindKeyEvents();
},
bindKeyEvents: function() {
var $this = this;
if(PrimeFaces.env.isIE()) {
this.focusCheck = false;
}
this.headers.on('focus.panelmenu', function(){
$(this).addClass('ui-menuitem-outline');
})
.on('blur.panelmenu', function(){
$(this).removeClass('ui-menuitem-outline ui-state-hover');
})
.on('keydown.panelmenu', function(e) {
var keyCode = $.ui.keyCode,
key = e.which;
if(key === keyCode.SPACE || key === keyCode.ENTER || key === keyCode.NUMPAD_ENTER) {
$(this).trigger('click');
e.preventDefault();
}
});
this.menuContent.on('mousedown.panelmenu', function(e) {
if($(e.target).is(':not(:input:enabled)')) {
e.preventDefault();
}
}).on('focus.panelmenu', function(){
if(!$this.focusedItem) {
$this.focusItem($this.getFirstItemOfContent($(this)));
if(PrimeFaces.env.isIE()) {
$this.focusCheck = false;
}
}
});
this.menuContent.off('keydown.panelmenu blur.panelmenu').on('keydown.panelmenu', function(e) {
if(!$this.focusedItem) {
return;
}
var keyCode = $.ui.keyCode;
switch(e.which) {
case keyCode.LEFT:
if($this.isExpanded($this.focusedItem)) {
$this.focusedItem.children('.ui-menuitem-link').trigger('click');
}
else {
var parentListOfItem = $this.focusedItem.closest('ul.ui-menu-list');
if(parentListOfItem.parent().is(':not(.ui-panelmenu-content)')) {
$this.focusItem(parentListOfItem.closest('li.ui-menuitem'));
}
}
e.preventDefault();
break;
case keyCode.RIGHT:
if($this.focusedItem.hasClass('ui-menu-parent') && !$this.isExpanded($this.focusedItem)) {
$this.focusedItem.children('.ui-menuitem-link').trigger('click');
}
e.preventDefault();
break;
case keyCode.UP:
var itemToFocus = null,
prevItem = $this.focusedItem.prev();
if(prevItem.length) {
itemToFocus = prevItem.find('li.ui-menuitem:visible:last');
if(!itemToFocus.length) {
itemToFocus = prevItem;
}
}
else {
itemToFocus = $this.focusedItem.closest('ul').parent('li');
}
if(itemToFocus.length) {
$this.focusItem(itemToFocus);
}
e.preventDefault();
break;
case keyCode.DOWN:
var itemToFocus = null,
firstVisibleChildItem = $this.focusedItem.find('> ul > li:visible:first');
if(firstVisibleChildItem.length) {
itemToFocus = firstVisibleChildItem;
}
else if($this.focusedItem.next().length) {
itemToFocus = $this.focusedItem.next();
}
else {
if($this.focusedItem.next().length === 0) {
itemToFocus = $this.searchDown($this.focusedItem);
}
}
if(itemToFocus && itemToFocus.length) {
$this.focusItem(itemToFocus);
}
e.preventDefault();
break;
case keyCode.ENTER:
case keyCode.NUMPAD_ENTER:
case keyCode.SPACE:
var currentLink = $this.focusedItem.children('.ui-menuitem-link');
//IE fix
setTimeout(function(){
currentLink.trigger('click');
},1);
$this.jq.blur();
var href = currentLink.attr('href');
if(href && href !== '#') {
window.location.href = href;
}
e.preventDefault();
break;
case keyCode.TAB:
if($this.focusedItem) {
if(PrimeFaces.env.isIE()) {
$this.focusCheck = true;
}
$(this).focus();
}
break;
}
}).on('blur.panelmenu', function(e) {
if(PrimeFaces.env.isIE() && !$this.focusCheck) {
return;
}
$this.removeFocusedItem();
});
var clickNS = 'click.' + this.id;
//remove focusedItem when document is clicked
$(document.body).off(clickNS).on(clickNS, function(event) {
if(!$(event.target).closest('.ui-panelmenu').length) {
$this.removeFocusedItem();
}
});
},
searchDown: function(item) {
var nextOfParent = item.closest('ul').parent('li').next(),
itemToFocus = null;
if(nextOfParent.length) {
itemToFocus = nextOfParent;
}
else if(item.closest('ul').parent('li').length === 0){
itemToFocus = item;
}
else {
itemToFocus = this.searchDown(item.closest('ul').parent('li'));
}
return itemToFocus;
},
getFirstItemOfContent: function(content) {
return content.find('> .ui-menu-list > .ui-menuitem:visible:first-child');
},
getItemText: function(item) {
return item.find('> .ui-menuitem-link > span.ui-menuitem-text');
},
focusItem: function(item) {
this.removeFocusedItem();
this.getItemText(item).addClass('ui-menuitem-outline').focus();
this.focusedItem = item;
},
removeFocusedItem: function() {
if(this.focusedItem) {
this.getItemText(this.focusedItem).removeClass('ui-menuitem-outline');
this.focusedItem = null;
}
},
isExpanded: function(item) {
return item.children('ul.ui-menu-list').is(':visible');
},
collapseRootSubmenu: function(header) {
var panel = header.next();
header.attr('aria-expanded', false).removeClass('ui-state-active ui-corner-top').addClass('ui-state-hover ui-corner-all')
.children('.ui-icon').removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
panel.attr('aria-hidden', true).slideUp('normal', 'easeInOutCirc');
this.removeAsExpanded(panel);
},
expandRootSubmenu: function(header, restoring) {
var panel = header.next();
header.attr('aria-expanded', true).addClass('ui-state-active ui-corner-top').removeClass('ui-state-hover ui-corner-all')
.children('.ui-icon').removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-s');
if(restoring) {
panel.attr('aria-hidden', false).show();
}
else {
panel.attr('aria-hidden', false).slideDown('normal', 'easeInOutCirc');
this.addAsExpanded(panel);
}
},
expandTreeItem: function(submenu, restoring) {
var submenuLink = submenu.find('> .ui-menuitem-link');
submenuLink.find('> .ui-menuitem-text').attr('aria-expanded', true);
submenuLink.find('> .ui-panelmenu-icon').addClass('ui-icon-triangle-1-s');
submenu.children('.ui-menu-list').show();
if(!restoring) {
this.addAsExpanded(submenu);
}
},
collapseTreeItem: function(submenu) {
var submenuLink = submenu.find('> .ui-menuitem-link');
submenuLink.find('> .ui-menuitem-text').attr('aria-expanded', false);
submenuLink.find('> .ui-panelmenu-icon').removeClass('ui-icon-triangle-1-s');
submenu.children('.ui-menu-list').hide();
this.removeAsExpanded(submenu);
},
saveState: function() {
if(this.cfg.stateful) {
var expandedNodeIds = this.expandedNodes.join(',');
PrimeFaces.setCookie(this.stateKey, expandedNodeIds, {path:'/'});
}
},
restoreState: function() {
var expandedNodeIds = null;
if(this.cfg.stateful) {
expandedNodeIds = PrimeFaces.getCookie(this.stateKey);
}
if(expandedNodeIds) {
this.collapseAll();
this.expandedNodes = expandedNodeIds.split(',');
for(var i = 0 ; i < this.expandedNodes.length; i++) {
var element = $(PrimeFaces.escapeClientId(this.expandedNodes[i]));
if(element.is('div.ui-panelmenu-content'))
this.expandRootSubmenu(element.prev(), true);
else if(element.is('li.ui-menu-parent'))
this.expandTreeItem(element, true);
}
}
else {
this.expandedNodes = [];
var activeHeaders = this.headers.filter('.ui-state-active'),
activeTreeSubmenus = this.jq.find('.ui-menu-parent > .ui-menu-list:not(.ui-helper-hidden)');
for(var i = 0; i < activeHeaders.length; i++) {
this.expandedNodes.push(activeHeaders.eq(i).next().attr('id'));
}
for(var i = 0; i < activeTreeSubmenus.length; i++) {
this.expandedNodes.push(activeTreeSubmenus.eq(i).parent().attr('id'));
}
}
},
removeAsExpanded: function(element) {
var id = element.attr('id');
this.expandedNodes = $.grep(this.expandedNodes, function(value) {
return value != id;
});
this.saveState();
},
addAsExpanded: function(element) {
this.expandedNodes.push(element.attr('id'));
this.saveState();
},
clearState: function() {
if(this.cfg.stateful) {
PrimeFaces.deleteCookie(this.stateKey, {path:'/'});
}
},
collapseAll: function() {
this.headers.filter('.ui-state-active').each(function() {
var header = $(this);
header.removeClass('ui-state-active').children('.ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e').removeClass('ui-icon-triangle-1-s');
header.next().addClass('ui-helper-hidden');
});
this.jq.find('.ui-menu-parent > .ui-menu-list:not(.ui-helper-hidden)').each(function() {
$(this).addClass('ui-helper-hidden').prev().children('.ui-panelmenu-icon').removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
});
}
});