/*
* � Copyright IBM Corp. 2014, 2015
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.ibm.xsp.theme.bootstrap.renderkit.html.extlib.outline.tree;
import java.io.IOException;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import com.ibm.xsp.theme.bootstrap.util.BootstrapUtil;
import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.extlib.component.outline.AbstractOutline;
import com.ibm.xsp.extlib.renderkit.html_extended.outline.tree.AbstractTreeRenderer;
import com.ibm.xsp.extlib.tree.ITreeNode;
import com.ibm.xsp.extlib.util.ExtLibRenderUtil;
import com.ibm.xsp.extlib.util.ExtLibUtil;
import com.ibm.xsp.renderkit.html_basic.HtmlRendererUtil;
public class AccordionRenderer extends AbstractTreeRenderer {
private static final long serialVersionUID = 1L;
private String accordionClientId;
private String accordionInnerId;
public AccordionRenderer(String accordionClientId) {
this.accordionClientId = accordionClientId;
if(StringUtil.isNotEmpty(accordionInnerId)) {
this.accordionInnerId = StringUtil.replace(this.accordionClientId, ':', '_');
} else {
this.accordionInnerId = BootstrapUtil.computeUniqueId();
}
}
public String getClientId() {
return accordionClientId;
}
public String getInnerId() {
return accordionInnerId;
}
@Override
protected void preRenderTree(FacesContext context, ResponseWriter writer, TreeContextImpl tree) throws IOException {
AbstractOutline outline = (AbstractOutline)tree.getComponent();
writer.startElement("div", null); // $NON-NLS-1$
String id = getClientId();
if(StringUtil.isNotEmpty(id)) {
writer.writeAttribute("id",id,null); // $NON-NLS-1$
}
writer.writeAttribute("role", "tablist", null); // $NON-NLS-1$ $NON-NLS-2$
String style = outline.getStyle();
if(StringUtil.isNotEmpty(style)) {
writer.writeAttribute("style",style,null); // $NON-NLS-1$
}
String styleClass = outline.getStyleClass();
if(StringUtil.isNotEmpty(styleClass)) {
writer.writeAttribute("class",styleClass,null); // $NON-NLS-1$
}
writer.startElement("div", null); // $NON-NLS-1$
writer.writeAttribute("id",getInnerId(),null); // $NON-NLS-1$
writer.writeAttribute("class","xspAccordion panel-group",null); // $NON-NLS-1$ $NON-NLS-2$
writer.write('\n');
}
@Override
protected void postRenderTree(FacesContext context, ResponseWriter writer, TreeContextImpl tree) throws IOException {
writer.endElement("div"); // panel-group //$NON-NLS-1$
writer.endElement("div"); // main // $NON-NLS-1$
writer.write('\n');
}
@Override
protected void preRenderList(FacesContext context, ResponseWriter writer, TreeContextImpl tree) throws IOException {
// Don't need to perform any output here
}
@Override
protected void postRenderList(FacesContext context, ResponseWriter writer, TreeContextImpl tree) throws IOException {
// Don't need to perform any output here
}
@Override
protected void renderNode(FacesContext context, ResponseWriter writer, TreeContextImpl tree) throws IOException {
// Generate a separator
int type = tree.getNode().getType();
if(type==ITreeNode.NODE_SEPARATOR) {
// Not supported in a accordion
return;
}
// JSF inserts a ':' that breaks CSS queries and thus Bootstrap
int idx = tree.getNodeContext().getIndexInParent();
String bodyId = getInnerId()+'_'+idx;
// Generate a regular node
String label = tree.getNode().getLabel();
String image = tree.getNode().getImage();
boolean enabled = tree.getNode().isEnabled();
String style = getItemStyle(tree,enabled,false);
String styleClass = getItemStyleClass(tree,enabled,false);
boolean leaf = tree.getNode().getType()==ITreeNode.NODE_LEAF;
String href = null;
String onclick = null;
if(leaf) {
href = tree.getNode().getHref();
onclick = findNodeOnClick(tree);
}
boolean hasLink = leaf && enabled && (StringUtil.isNotEmpty(onclick) || StringUtil.isNotEmpty(href));
boolean hasImage = StringUtil.isNotEmpty(image);
writer.startElement("div", null); // $NON-NLS-1$
if(StringUtil.isNotEmpty(style)) {
writer.writeAttribute("style",style,null); // $NON-NLS-1$
}
styleClass = ExtLibUtil.concatStyleClasses("panel panel-default",styleClass); // $NON-NLS-1$
writer.writeAttribute("class",styleClass,null); // $NON-NLS-1$
if(hasLink) {
if (StringUtil.isNotEmpty(onclick)) {
// What to do here?
//attrs.put("onClick", onclick); // $NON-NLS-1$ $NON-NLS-2$
}
}
writer.startElement("div", null); // $NON-NLS-1$
writer.writeAttribute("class","panel-heading",null); // $NON-NLS-1$ $NON-NLS-2$
writer.startElement("h4", null); // $NON-NLS-1$
writer.writeAttribute("class","panel-title",null); // $NON-NLS-1$ $NON-NLS-2$
writer.startElement("a", null); // $NON-NLS-1$
writer.writeAttribute("class","accordion-toggle",null); // $NON-NLS-1$ $NON-NLS-2$
writer.writeAttribute("data-toggle","collapse",null); // $NON-NLS-1$ $NON-NLS-2$
writer.writeAttribute("data-parent","#"+getInnerId(),null); // $NON-NLS-1$
writer.writeAttribute("href","#"+bodyId,null); // $NON-NLS-1$
writer.writeAttribute("role","tab",null); // $NON-NLS-1$ $NON-NLS-2$
writer.writeAttribute("aria-controls", bodyId, null); // $NON-NLS-1$
if(hasImage) {
writer.startElement("img", null); // $NON-NLS-1$
if(StringUtil.isNotEmpty(image)) {
image=HtmlRendererUtil.getImageURL(context, image);
writer.writeAttribute("src", image, null); // $NON-NLS-1$
}
String imageAlt = tree.getNode().getImageAlt();
if(ExtLibRenderUtil.isAltPresent(imageAlt)) {
writer.writeAttribute("alt", imageAlt, null); // $NON-NLS-1$
}
writer.endElement("img"); // $NON-NLS-1$
}
if(StringUtil.isNotEmpty(label)) {
writer.writeText(label, null); // $NON-NLS-1$
}
writer.endElement("a"); // $NON-NLS-1$
writer.endElement("h4"); // $NON-NLS-1$
writer.write('\n');
writer.endElement("div"); // panel-heading // $NON-NLS-1$
writer.write('\n');
writer.startElement("div", null); // $NON-NLS-1$
writer.writeAttribute("role", "tabpanel", null); // $NON-NLS-1$ $NON-NLS-2$
// "Accordion tab panel"
String accordionAriaLabel = com.ibm.xsp.extlib.controls.ResourceHandler.getString("DojoAccordionRenderer.Accordiontabpanel"); // $NON-NLS-1$
writer.writeAttribute("aria-label", accordionAriaLabel, null); // $NON-NLS-1$
writer.writeAttribute("id",bodyId,null); // $NON-NLS-1$
String bodyClass = "panel-collapse collapse"; // $NON-NLS-1$
if(tree.getNode().isSelected()) {
bodyClass = ExtLibUtil.concatStyleClasses(bodyClass,"in"); // $NON-NLS-1$
}
writer.writeAttribute("class",bodyClass,null); // $NON-NLS-1$
writer.startElement("div", null); // $NON-NLS-1$
//TODO remove this if com.ibm.xsp.theme.bootstrap.renderkit.html.extlib.outline.tree.AccordionListRenderer is used in getChildrenRenderer
//writer.writeAttribute("class","panel-body",null); // $NON-NLS-1$
writer.writeAttribute("role", "presentation", null); // $NON-NLS-1$ $NON-NLS-2$
writer.writeAttribute("aria-hidden", !tree.getNode().isExpanded(), null); // $NON-NLS-1$
writer.startElement("ul", null); // $NON-NLS-1$
writer.writeAttribute("class","list-group",null); // $NON-NLS-1$ $NON-NLS-2$
//writer.writeAttribute("role", "presentation", null); // $NON-NLS-1$ $NON-NLS-2$
writer.writeAttribute("aria-hidden", !tree.getNode().isExpanded(), null); // $NON-NLS-1$
renderChildren(context, writer, tree);
writer.endElement("ul"); // $NON-NLS-1$
writer.endElement("div"); // panel-body // $NON-NLS-1$
writer.endElement("div"); // panel-collapse // $NON-NLS-1$
writer.write('\n');
writer.endElement("div"); // panel panel-default // $NON-NLS-1$
writer.write('\n');
}
@Override
protected AbstractTreeRenderer getChildrenRenderer(TreeContextImpl tree) {
if(tree.getDepth()==1) {
return this;
}
// UIComponent c = tree.getComponent();
//return new AccordionListRenderer();
return new com.ibm.xsp.theme.bootstrap.renderkit.html.extlib.outline.tree.AccordionListRenderer();
}
}