+1 here as well, we had that issue on a project just last week.
On 6/6/07, Jeanne Waldman <[EMAIL PROTECTED] > wrote:
>
> +1 also.
>
> Matt Cooper wrote:
> > +1 on supporting an iterator around form items, I feel that would be
> > quite a powerful enhancement
> >
> > On 6/5/07, *Adam Winer* < [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>>
> > wrote:
> >
> > On 6/4/07, * Matt Cooper* <[EMAIL PROTECTED]
> > <mailto:[EMAIL PROTECTED]>> wrote:
> >
> > I think decoupling of these renderers would be a good thing.
> > The trick will be to make sure the form item renders properly
> > when it is a direct child of the form layout component. Let's
>
> > say that you put a tr:panelGroupLayout (or some other non form
> > layout component) inbetween the form layout component and the
> > form item--I feel that that particular form item should render
>
> > the same as if there was no form layout involved (this would
> > be insulating the form item from the form layout).
> >
> >
> > One of the big questions to decide when decoupling is whether you
> > want the parent component to augment/enhance the rendering of the
> > children or for the child to be passed more information to render
> > itself differently. In this case, I wonder if both might be
> > desirable, and I could imagine:
> > - A generic mechanism whereby a parent renderer could say "on my
> > children, here's a CoreRendererDecorator that I'd like to have
> > called for any child CoreRenderer", akin to a servlet fil
> > - A generic mechanism whereby a parent could publish rendering
> > information and child could ask for it, decoupled from looking at
> > the renderer and component (so we don't have getParent() or
> > getParent().getRenderer() and "instanceof" calls), something like
> > Object RenderingContext.getDescriptor(UIComponent parent)? This'd
> > let us have classes like FormLayoutData in the public API,
> > decoupling the renderers, without forcing us to move the renderers
> > themselves into the public API.
> >
> >
> > When considering a decoupling approach, you will also want
> > consider cases where a developer wants to have one kind of a
> > form layout component inside of another form layout
> > component. There will need to be some sort of mechanism to
> > ensure the correct rendering path is taken for the each
> > particular component hierarchy so a simple "am I contained, at
>
> > any level, in a form layout" might not be sufficient but an
> > "am I a direct child of a form layout" might.
> >
> > Today, I believe if you have a tr:panelFormLayout inside of
> > another tr:panelFormLayout, the outer layout will have labels
> > on the side of the contents and the inner layout will have the
> > labels above the contents. This is determined by a request
> > attribute that is present only during the encodeAll of the
> > PanelFormLayout's encoding.
> >
> > One final tip... There is one particular case where a form
> > item isn't a direct child of the form layout but will still
> > render as a form item: when it is contained in a tr:group
> > component and that tr:group is a direct child of the form
> > layout. The tr:group component is used by the form layout
> > renderer to draw separator lines between groups of form items.
> >
> >
> > And, in addition, I think a lot of people really wish that if you
> > had a tr:iterator inside of
> > a tr:panelFormLayout, that children of that iterator would render
> > as a form item. I think
> > a CoreRendererDecorator approach might accomplish that...
> >
> > -- Adam
> >
> >
> >
> > Regards,
> > Matt
> >
> >
> > On 5/24/07, *Leonardo Uribe* <[EMAIL PROTECTED]
> > <mailto:[EMAIL PROTECTED]>> wrote:
> >
> > Hi everybody.
> >
> > I'm working on a trinidad component for do layout (as part
> > of a Google Summer of Code) more easy and with less code
> > than panelFormLayout component.
> >
> > Checking the code, I found a strong coupling between the
> > classes PanelFormLayoutRenderer and
> LabelAndMessageRenderer.
> >
> > I found the following points:
> >
> > 1. LabelAndMessageRenderer has about 3 behaviors,
> > depending what is his parent components. In the code it
> > checks in a method something like
> > that:
> >
> > private boolean _isFormRendererType(String rendererType)
> > {
> > return
> > "org.apache.myfaces.trinidad.Form".equals(rendererType) ||
>
> >
> > "org.apache.myfaces.trinidad.FormLayout
> ".equals(rendererType)
> > ||
> > "org.apache.myfaces.trinidad.rich.Form
> > ".equals(rendererType) ;
> > }
> >
> > Because my component is a new component, i have to add a
> > line like this
> >
> > return
> > "org.apache.myfaces.trinidad.Form ".equals(rendererType)
> ||
> > "org.apache.myfaces.trinidad.FormLayout
> > ".equals(rendererType) ||
> >
> > "org.apache.myfaces.trinidad.rich.Form".equals(rendererType)
> > ||
> > "org.apache.myfaces.
> > trinidad.TableLayout".equals(rendererType);
> >
> > But this is very hacky. I have to do this because i need
> > that the method in encodeAll of LabelAndMessageRenderer
> >
> > boolean needsPanelFormLayout =
> _isParentPanelForm(component);
> >
> > returns true, because my component layout a table like
> > panelFormLayout.
> >
> > 2. In other part of the code, LabelAndMessageRenderer call
> > this method (in encodeAll)
> >
> > if (needsPanelFormLayout)
> > {
> >
> > if(PanelFormLayoutRenderer.encodeBetweenLabelAndFieldCells
> (context,
> > arc, rw))
> > {
> > renderRootDomElementStyles(context, arc,
> > component, bean);
> > }
> > }
> >
> > What if my component has another behavior to this method?
> > PanelFormLayoutRenderer detects if this panelFormLayout is
>
> > inside
> > another panelFormLayout and because if it is the case, it
> > adds between Label and Field Cells something like this
> >
> > rw.endElement ("tr"); // label row
> > rw.startElement("tr", null); // field row
> >
> > So, the label is rendered on top of the field.
> >
> > 3. LabelAndMessageRenderer do this for render a Label an a
>
> > field (please look the parts in yellow)
> >
> > private void _renderLabelCell(
> > FacesContext context,
> > RenderingContext arc,
> > UIComponent component,
> > FacesBean bean,
> > boolean labelExists) throws IOException
> > {
> > ResponseWriter rw = context.getResponseWriter();
> > rw.startElement("td", null);
> >
> > // render labelStyleClass and defaultStyleClass.
> > renderStyleClasses(context, arc, new String[]{
> > getLabelStyleClass(bean),
> > _getDefaultLabelStyleClass(arc,
> >
> > SkinSelectors.AF_LABEL_TEXT_STYLE_CLASS )});
> >
> > String labelInlineStyle =
> getLabelInlineStyleKey(bean);
> > rw.writeAttribute("style", labelInlineStyle, null);
> >
> > String valign = getDefaultLabelValign(bean);
> >
> > rw.writeAttribute ("valign", valign, null);
> > if (isDesktop(arc))
> > rw.writeAttribute("nowrap", Boolean.TRUE, null);
> >
> > if (labelExists)
> > {
> > rw.writeAttribute("width",
> >
> > arc.getProperties().get(_LABEL_CELL_WIDTH_KEY),
> > null);
> > }
> >
> > delegateRenderer(context, arc, component, bean,
> _label);
> > rw.endElement ("td");
> > }
> >
> > private void _renderFieldCell(
> > FacesContext context,
> > RenderingContext arc,
> > UIComponent component,
> > FacesBean bean,
> > boolean labelExists,
> > boolean needsPanelFormLayout,
> > boolean isInline) throws IOException
> > {
> > ResponseWriter rw = context.getResponseWriter ();
> > rw.startElement("td", null);
> >
> > rw.writeAttribute("valign", "top", null);
> > rw.writeAttribute("nowrap", Boolean.TRUE, null);
> >
> > renderStyleClass(context, arc,
> > SkinSelectors.AF_CONTENT_CELL_STYLE_CLASS );
> >
> > if (labelExists)
> > rw.writeAttribute("width",
> >
> > arc.getProperties().get(_FIELD_CELL_WIDTH_KEY),
> > null);
> >
> > renderFieldCellContents(context, arc, component,
> bean);
> >
> > // The panelForm places messages below the fields, not
> > on a separate
> > // row:
> > if (needsPanelFormLayout)
> > {
> > // =-= mcc PPR PROBLEM!!! We should always be
> > rendering the "div",
> > // and always rendering an ID, if we ever want
> > it to be PPR
> > // replaceable:
> > if (isInline || hasMessage(context, arc, component,
> > bean))
> > {
> > rw.startElement ("div", null);
> > renderStyleClass(context, arc,
> >
> > SkinSelectors.AF_COMPONENT_MESSAGE_CELL_STYLE_CLASS);
> > _renderMessageCellContents(context, arc,
> > component, bean);
> > rw.endElement("div");
> > }
> > }
> >
> > // bug 2484841: PDA: TOO MUCH WHITESPACE BETWEEN
> > // INPUT ELEMENTS IN LABELEDFIELD
> > // This is a browser bug workaround, hopefully we can
> > remove it eventually
> > if (isPDA(arc) && isIE(arc))
> > {
> > rw.startElement("div", null);
> > renderSpacer(context, arc, "1", "0");
> > rw.endElement("div");
> > }
> >
> > rw.endElement("td");
> > }
> >
> > I need to add an attribute in the td tag like <td
> > colspan=2 rowspan=3 height=XXX width=XXX .........>, but
> > if i want this, i need to
> > modify LabelAndMessageRenderer to recognize if the parent
> > component is my component, check if it has an attribute
> > like this
> >
> > <mycomp:tableFormLayout
> > labelWidth="100" width="400" height="300"
> > fieldWidth="100" rows="100"
> > columns="1*;1*;1*" >
> > <tr:selectOneChoice
> > label="Salutation">
> > <f:selectItem itemLabel="1
> > Option" itemValue="1" />
> > <f:attribute name="spanXItem"
> > value="2"/>
> > <f:attribute name="spanYItem"
> > value="3"/>
> > </tr:selectOneChoice>
> > </mycomp:tableFormLayout>
> >
> > and finally add a colspan or rowspan (height and width are
>
> > optional).
> >
> > ---------
> > Conclusion?: It's necesary to decouple
> > PanelFormLayoutRenderer and other FormRenderers with
> > LabelAndMessageRenderer in order to avoid
> > those hacks. I propose to create an interface that
> > implements some affected methods or create new ones, and
> > delegate this rendering to the parent
> > classes.
> >
> > I want to you what should be better to do in that case. If
> > its necesary to refactor the classes, how it can be done.
> >
> > Thanks for your attention
> >
> > regards
> >
> > Att: Leonardo Uribe
> > Ingeniero de Sistemas
> > Pontificia Universidad Javeriana
> > Ingeniero Electronico
> > Universidad Nacional de Colombia
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
>