Matt-

you are using name space "org.apache.myfaces.shared_impl.**;"

I strongly recommend to use "org.apache.myfaces.shared_tomahawk.**;"

The shared classes are *integrated* in tomahawk.jar and myfaces-impl.jar.
If you use shared_impl your Renderer depends on myfaces as your jsf runtime.
By using "shared_tomahawk" namespace your Renderer  *only* depends on
Tomahawk, which *should* run w/ RI.

There is also a myfaces-shared-core.jar, which is the base of both
shared_XXX namespaces.
This JAR includes the "org.apache.myfaces.shared.*** namespace, but
there is no released version for it.

-Matthias

On 6/2/06, mraible <[EMAIL PROTECTED]> wrote:


mraible wrote:
>
> I've decided to try overriding panelGrid's renderer to get this
> functionality.  I'm assuming HtmlGridRendererBase.java
> (http://tinyurl.com/oqbxh) is the correct class to override?  Once I've
> done this, how do I override it in my faces-config.xml file?  I'm
> overriding outputLabel with the following:
>
>     <render-kit>
>       <description>Some replacements for the standard
> renderers</description>
>       <renderer>
>          <description>Replacement renderer for h:outputLabel</description>
>          <component-family>javax.faces.Output</component-family>
>          <renderer-type>javax.faces.Label</renderer-type>
>
> <renderer-class>org.appfuse.webapp.jsf.LabelRenderer</renderer-class>
>       </renderer>
>
> Which component-family is panelGrid in?  javax.faces.panel?  And it's
> render-type is javax.faces.Panel?
>
> Thanks,
>
> Matt
>

Here's the solution to this:

<renderer>
            <description>Replacement renderer for h:panelGrid that uses
lists instead of tables</description>
            <component-family>javax.faces.Panel</component-family>
            <renderer-type>javax.faces.Grid</renderer-type>

<renderer-class>org.appfuse.webapp.jsf.PanelGridRenderer</renderer-class>
        </renderer>

My PanelGridRenderer - that renders ul and li's - is as follows:

package org.appfuse.webapp.jsf;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.shared_impl.renderkit.JSFAttr;
import org.apache.myfaces.shared_impl.renderkit.RendererUtils;
import org.apache.myfaces.shared_impl.renderkit.html.HTML;
import org.apache.myfaces.shared_impl.renderkit.html.HtmlRenderer;
import org.apache.myfaces.shared_impl.renderkit.html.HtmlRendererUtils;
import org.apache.myfaces.shared_impl.util.StringUtils;

import javax.faces.component.UIComponent;
import javax.faces.component.UIPanel;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import java.io.IOException;
import java.util.Iterator;

/**
 * Override HtmlGridRendererBase (http://tinyurl.com/oqbxh) so <h:panelGrid>
spits out <ul> and <li>
 * instead of <table> and <tr><td>.
 *
 * @author Matt Raible
 */
public class PanelGridRenderer extends HtmlRenderer {
    private static final Log log =
LogFactory.getLog(PanelGridRenderer.class);

    public boolean getRendersChildren() {
        return true;
    }

    public void encodeBegin(FacesContext facesContext, UIComponent
component)
            throws IOException {
        // all work done in encodeEnd()
    }

    public void encodeChildren(FacesContext context, UIComponent component)
            throws IOException {
        // all work done in encodeEnd()
    }

    public void encodeEnd(FacesContext facesContext, UIComponent component)
            throws IOException {
        RendererUtils.checkParamValidity(facesContext, component,
UIPanel.class);

        int columns;
        if (component instanceof HtmlPanelGrid) {
            columns = ((HtmlPanelGrid) component).getColumns();
        } else {
            Integer i = (Integer)
component.getAttributes().get(org.apache.myfaces.shared_impl.renderkit.JSFAttr.COLUMNS_ATTR);
            columns = i != null ? i.intValue() : 0;
        }

        if (columns <= 0) {
            if (log.isErrorEnabled()) {
                log.error("Wrong columns attribute for PanelGrid " +
component.getClientId(facesContext) + ": " + columns);
            }
            columns = 1;
        }

        ResponseWriter writer = facesContext.getResponseWriter();
        writer.startElement(HTML.UL_ELEM, component);
        HtmlRendererUtils.writeIdIfNecessary(writer, component,
facesContext);
        HtmlRendererUtils.renderHTMLAttributes(writer, component,
HTML.UL_PASSTHROUGH_ATTRIBUTES);

        writer.flush();

        renderChildren(facesContext, writer, component, columns);

        writer.endElement(HTML.UL_ELEM);
    }

    protected void renderChildren(FacesContext context,
                                  ResponseWriter writer,
                                  UIComponent component,
                                  int columns)
            throws IOException {

        String rowClasses;
        if (component instanceof HtmlPanelGrid) {
            rowClasses = ((HtmlPanelGrid) component).getRowClasses();
        } else {
            rowClasses = (String)
component.getAttributes().get(JSFAttr.ROW_CLASSES_ATTR);
        }

        String[] rowClassesArray = (rowClasses == null)
                ?
org.apache.myfaces.shared_impl.util.ArrayUtils.EMPTY_STRING_ARRAY
                : StringUtils.trim(StringUtils.splitShortString(rowClasses,
','));
        int rowClassesCount = rowClassesArray.length;

        int childCount = getChildCount(component);
        if (childCount > 0) {
            int columnIndex = 0;
            int rowClassIndex = 0;
            boolean rowStarted = false;
            for (Iterator it = getChildren(component).iterator();
it.hasNext();) {
                UIComponent child = (UIComponent) it.next();
                if (child.isRendered()) {
                    if (columnIndex == 0) {
                        //start of new/next row
                        if (rowStarted) {
                            //do we have to close the last row?
                            writer.endElement(HTML.LI_ELEM);

HtmlRendererUtils.writePrettyLineSeparator(context);
                        }
                        writer.startElement(HTML.LI_ELEM, component);
                        if (rowClassIndex < rowClassesCount) {
                            writer.writeAttribute(HTML.CLASS_ATTR,
rowClassesArray[rowClassIndex], null);
                        }
                        rowStarted = true;
                        rowClassIndex++;
                        if (rowClassIndex == rowClassesCount) {
                            rowClassIndex = 0;
                        }
                    }

                    RendererUtils.renderChild(context, child);

                    columnIndex++;
                    if (columnIndex >= columns) {
                        columnIndex = 0;
                    }
                }
            }

            if (rowStarted) {
                writer.endElement(HTML.LI_ELEM);
                HtmlRendererUtils.writePrettyLineSeparator(context);
            }
        }
    }
}

The only issue I've found (so far) is that I need to put two <h:outputText/>
elements after a <h:panelGroup> when I have columns="3" on <h:panelGrid>.

Hope this helps anyone looking for a similar solution,

Matt

--
View this message in context: 
http://www.nabble.com/Component-like-panelGrid-with-ul-and-li-t1668669.html#a4675691
Sent from the MyFaces - Users forum at Nabble.com.




--
Matthias Wessendorf
Aechterhoek 18
48282 Emsdetten
blog: http://jroller.com/page/mwessendorf
mail: mwessendorf-at-gmail-dot-com

Reply via email to