+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
>
>
>
>
>
>
>
>
>
>

Reply via email to