org.richfaces.renderkit.html.PanelMenuGroupRenderer Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright ${year}, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.renderkit.html;
import static org.richfaces.renderkit.HtmlConstants.CLASS_ATTRIBUTE;
import static org.richfaces.renderkit.HtmlConstants.DIV_ELEM;
import static org.richfaces.renderkit.HtmlConstants.ID_ATTRIBUTE;
import static org.richfaces.renderkit.HtmlConstants.INPUT_ELEM;
import static org.richfaces.renderkit.HtmlConstants.INPUT_TYPE_HIDDEN;
import static org.richfaces.renderkit.HtmlConstants.NAME_ATTRIBUTE;
import static org.richfaces.renderkit.HtmlConstants.TYPE_ATTR;
import static org.richfaces.renderkit.HtmlConstants.VALUE_ATTRIBUTE;
import static org.richfaces.renderkit.html.TogglePanelRenderer.addEventOption;
import static org.richfaces.renderkit.html.TogglePanelRenderer.getAjaxOptions;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.event.ActionEvent;
import org.ajax4jsf.javascript.JSObject;
import org.richfaces.PanelMenuMode;
import org.richfaces.cdk.annotations.JsfRenderer;
import org.richfaces.component.AbstractPanelMenuGroup;
import org.richfaces.component.AbstractPanelMenuItem;
import com.google.common.base.Strings;
/**
* @author akolonitsky
* @since 2010-10-25
*/
@JsfRenderer(type = "org.richfaces.PanelMenuGroupRenderer", family = AbstractPanelMenuGroup.COMPONENT_FAMILY)
public class PanelMenuGroupRenderer extends DivPanelRenderer {
public static final String COLLAPSE = "collapse";
public static final String EXPAND = "expand";
public static final String SWITCH = "switch";
public static final String BEFORE_COLLAPSE = "beforecollapse";
public static final String BEFORE_EXPAND = "beforeexpand";
public static final String BEFORE_SWITCH = "beforeswitch";
public static final String BEFORE_SELECT = "beforeselect";
public static final String SELECT = "select";
private static final String CSS_CLASS_PREFIX = "rf-pm-gr";
// TODO nick - shouldn't this be rf-pm-gr-top?
private static final String TOP_CSS_CLASS_PREFIX = "rf-pm-top-gr";
private static final String DEFAULT_EXPAND_EVENT = "click";
private static final String DEFAULT_COLLAPSE_EVENT = "click";
private final TableIconsRendererHelper headerRenderer = new PanelMenuGroupHeaderRenderer(
CSS_CLASS_PREFIX);
private final TableIconsRendererHelper topHeaderRenderer = new PanelMenuGroupHeaderRenderer(
TOP_CSS_CLASS_PREFIX);
@Override
protected void doDecode(FacesContext context, UIComponent component) {
AbstractPanelMenuGroup menuGroup = (AbstractPanelMenuGroup) component;
if (menuGroup.isDisabled()) {
return;
}
Map requestMap = context.getExternalContext().getRequestParameterMap();
// Don't overwrite the value unless you have to!
// TODO! nick - ":expanded" suffix is not necessary
String newValue = requestMap.get(component.getClientId(context) + ":expanded");
if (newValue != null) {
menuGroup.setSubmittedExpanded(newValue);
}
String clientId = component.getClientId(context);
if (requestMap.get(clientId) != null) {
new ActionEvent(component).queue();
context.getPartialViewContext().getRenderIds().add(clientId);
}
}
@Override
protected void doEncodeBegin(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
super.doEncodeBegin(writer, context, component);
AbstractPanelMenuGroup menuGroup = (AbstractPanelMenuGroup) component;
writer.startElement(INPUT_ELEM, component);
// TODO nick - there is no need to encode this input - group state can be extracted from class
final String expanded = component.getClientId(context) + ":expanded";
writer.writeAttribute(ID_ATTRIBUTE, expanded, null);
writer.writeAttribute(NAME_ATTRIBUTE, expanded, null);
writer.writeAttribute(TYPE_ATTR, INPUT_TYPE_HIDDEN, null);
writer.writeAttribute(VALUE_ATTRIBUTE, String.valueOf(menuGroup.getState()), null);
writer.endElement(INPUT_ELEM);
encodeHeader(writer, context, menuGroup);
encodeContentBegin(writer, context, menuGroup);
}
private void encodeHeader(ResponseWriter writer, FacesContext context, AbstractPanelMenuGroup menuGroup) throws IOException {
writer.startElement(DIV_ELEM, null);
writer.writeAttribute(ID_ATTRIBUTE, menuGroup.getClientId(context) + ":hdr", null);
writer.writeAttribute(
CLASS_ATTRIBUTE,
concatClasses(
getCssClass(menuGroup, "-hdr"),
"rf-pm-hdr-" + (menuGroup.getState() ? "exp" : "colps"),
(menuGroup.getPanelMenu().isBubbleSelection()
&& menuGroup.hasActiveItem(menuGroup, menuGroup.getPanelMenu().getActiveItem()) ? getCssClass(menuGroup,
"-sel") : ""),
PanelMenuItemRenderer.isParentPanelMenuDisabled(menuGroup) || menuGroup.isDisabled() ? getCssClass(menuGroup,
"-hdr-dis") : null), null);
(menuGroup.isTopItem() ? topHeaderRenderer : headerRenderer).encodeHeader(writer, context, menuGroup);
writer.endElement(DIV_ELEM);
}
public String getCssClass(AbstractPanelMenuItem item, String postfix) {
return (item.isTopItem() ? TOP_CSS_CLASS_PREFIX : CSS_CLASS_PREFIX) + postfix;
}
private void encodeContentBegin(ResponseWriter writer, FacesContext context, AbstractPanelMenuGroup menuGroup)
throws IOException {
writer.startElement(DIV_ELEM, null);
writer.writeAttribute(ID_ATTRIBUTE, menuGroup.getClientId(context) + ":cnt", null);
writer.writeAttribute(CLASS_ATTRIBUTE,
concatClasses(getCssClass(menuGroup, "-cnt"), menuGroup.getState() ? "rf-pm-exp" : "rf-pm-colps"), null);
writeJavaScript(writer, context, menuGroup);
}
private void encodeContentEnd(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
writer.endElement(DIV_ELEM);
}
@Override
protected String getStyleClass(UIComponent component) {
AbstractPanelMenuItem menuItem = (AbstractPanelMenuItem) component;
return concatClasses(
getCssClass(menuItem, ""),
attributeAsString(component, "styleClass"),
PanelMenuItemRenderer.isParentPanelMenuDisabled(menuItem) || menuItem.isDisabled() ? getCssClass(menuItem, "-dis")
: "",
PanelMenuItemRenderer.isParentPanelMenuDisabled(menuItem) || menuItem.isDisabled() ? attributeAsString(component,
"disabledClass") : "");
}
@Override
protected JSObject getScriptObject(FacesContext context, UIComponent component) {
return new JSObject("RichFaces.ui.PanelMenuGroup", component.getClientId(context), getScriptObjectOptions(context,
component));
}
private String getExpandEvent(AbstractPanelMenuGroup group) {
String expandEvent = group.getExpandEvent();
if (Strings.isNullOrEmpty(expandEvent)) {
expandEvent = group.getPanelMenu().getExpandEvent();
}
if (Strings.isNullOrEmpty(expandEvent)) {
expandEvent = DEFAULT_EXPAND_EVENT;
}
return expandEvent;
}
private String getCollapseEvent(AbstractPanelMenuGroup group) {
String collapseEvent = group.getCollapseEvent();
if (Strings.isNullOrEmpty(collapseEvent)) {
collapseEvent = group.getPanelMenu().getCollapseEvent();
}
if (Strings.isNullOrEmpty(collapseEvent)) {
collapseEvent = DEFAULT_COLLAPSE_EVENT;
}
return collapseEvent;
}
@Override
protected Map getScriptObjectOptions(FacesContext context, UIComponent component) {
AbstractPanelMenuGroup panelMenuGroup = (AbstractPanelMenuGroup) component;
Map options = new HashMap();
// TODO nick - non-default values should not be rendered
options.put("ajax", getAjaxOptions(context, panelMenuGroup));
options.put("name", panelMenuGroup.getName());
options.put("mode", panelMenuGroup.getMode());
options.put("disabled", PanelMenuItemRenderer.isParentPanelMenuDisabled(panelMenuGroup) || panelMenuGroup.isDisabled());
options.put("expandEvent", getExpandEvent(panelMenuGroup));
options.put("collapseEvent", getCollapseEvent(panelMenuGroup));
options.put("expanded", panelMenuGroup.getState());
options.put("selectable", panelMenuGroup.getSelectable());
options.put("unselectable", panelMenuGroup.getUnselectable());
options.put("stylePrefix", getCssClass(panelMenuGroup, ""));
addEventOption(context, panelMenuGroup, options, COLLAPSE);
addEventOption(context, panelMenuGroup, options, EXPAND);
addEventOption(context, panelMenuGroup, options, SWITCH);
addEventOption(context, panelMenuGroup, options, BEFORE_COLLAPSE);
addEventOption(context, panelMenuGroup, options, BEFORE_EXPAND);
addEventOption(context, panelMenuGroup, options, BEFORE_SWITCH);
addEventOption(context, panelMenuGroup, options, BEFORE_SELECT);
addEventOption(context, panelMenuGroup, options, SELECT);
return options;
}
@Override
protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
encodeContentEnd(writer, context, component);
writer.endElement(DIV_ELEM);
Map requestMap = context.getExternalContext().getRequestParameterMap();
String clientId = component.getClientId(context);
if (requestMap.get(clientId) != null) {
addOnCompleteParam(context, clientId);
}
}
@Override
protected Class extends UIComponent> getComponentClass() {
return AbstractPanelMenuGroup.class;
}
@Override
public boolean getRendersChildren() {
return true;
}
@Override
protected void doEncodeChildren(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
AbstractPanelMenuGroup group = (AbstractPanelMenuGroup) component;
boolean isClientMode = group.getMode() == PanelMenuMode.client;
if (isClientMode || group.getState()) {
renderChildren(context, component);
}
}
}