Posted under JSF
Permalink
Tags jQuery, JSF, Primefaces, Tip, Tutorial
This post details some tips discovered whilst experimenting with p:panel.
1/ The toggle button on the right hand side of the panel is rendered with ui-state-default. This does not look attractive with some themes – it often looks like a bit of a zit due to the background on the thick plus sign icon. I noticed that the dialog component p:dialog does not render its close icon in the header with ui-state-default, and this looks much more attractive as the surrounding highlight on the icon only shows on hover.
This can be applied to p:panel by removing the ui-state-default class from the anchor tags around the icons on the panel header. The following example jQuery performs this (in my case, the panelDivId argument is the ID of an h:paneGroup/div surrounding the panel:-
function ss_PanelFixIcons(panelDivId) {
var escapedPanelDivId = panelDivId.replace(/:/g, ‘\\3A ‘);
var panelIcons = jQuery(‘div#’ + escapedPanelDivId + ‘ div.ui-panel-titlebar > a.ui-panel-titlebar-icon’);
panelIcons.removeClass(‘ui-state-default’);
}
2/ It would be nice to be able to explicitly expand and collapse the panel as well as to just toggle it. In fact the panel widget does expose its current state via its cfg property, although this is not publicly documented. The following example functions use this to provide explict expand, collapse, and set to passed boolean state functions. In addition a function is provided to get the current panel state:-
function ss_PanelExpand(widgetVar) {
if (widgetVar.cfg.collapsed) {
widgetVar.toggle();
}
}function ss_PanelCollapse(widgetVar) {
if (!widgetVar.cfg.collapsed) {
widgetVar.toggle();
}
}function ss_PanelSetCollapsed(widgetVar, state) {
if (!widgetVar.cfg.collapsed == state) {
widgetVar.toggle();
}
}function ss_PanelGetCollapsed(widgetVar) {
return widgetVar.cfg.collapsed;
}
3/ A query came up on the Primefaces forum on how to lazy load the panel, as it eagerly loads and the expand/collapse is all done client side. The post is available here. the solution is straightforward:-
- Use a toggleListener to update a renderPanel property to true if the panel state from the event was visible, and false if it was hidden.
- Then conditionally render a content h:panelGroup inside the panel, using the above property as the rendered property.
- One issue with this is that the actual panel toggle occurs before the ajax update of the panel not after, so with the slide toggle effect on (say with toggleSpeed=”1000”), you see an empty sliding toggle first, then a non sliding ajax update. In this case it is best to turn off the slide effect with toggleSpeed=”0”. If you use another button to toggle the panel you can get around this, as the onComplete event for the button can toggle the panel (via its widget/ as per the above JavaScript), and this happens after the Ajax to render the panel. In practice you would have to somehow overlay the standard toggle button with another one of your own, or manually disable the standard one via CSS, as if you set toggleable=”false” for the panel this completely disables toggling via the widget as well as removing the toggle button.
- It is probably not worth the trouble of trying to get sliding to work if you are lazy loading. Note that when I tried some older/slow machines the slide effect rendered poorly anyway, so this should also be born in mind.