You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by JSFSter Smith <js...@gmail.com> on 2006/05/11 04:44:34 UTC

[newbie] - simple custom tag problems

Firstly, kudos to the MyFaces team for the recent releases of myfaces
1.1.3and tomahawk
1.1.2!

I am just a few weeks old with JSF and am using it for a current project. So
far its been great but I am still getting to know the deatils. I attempted
to create a simple custom JSP tag and was able to get it together
surprisingly quickly. But I do have a problem now. My tag essentially
renders the string in an attribute "value". Here is a sample usage:

<my:testTag value="My message"> (or) <my:testTag value="#{
datapanel.description}">

But the ValueBinding does not seem to work when I try to access a member of
the DataPanel bean that is a collection or another class that has members.
Examples of these cases are below:

<t:dataTable value="#{datapanel.sentenceDisplayData}" var="each">
    <t:column>
        <my:testTag value="#{each.part0}" />
        <my:testTag value="#{each.part1}" />
        <my:testTag value="#{each.part2}" />
        <my:testTag value="#{each.part3}" />
    </t:column>
</t:dataTable>

(OR)
<my:testTag value="#{datapanel.summary.length">

I am including my setProperties method of the TagLib class. Would be great
if someone can point out what I am missing here.

    protected void setProperties(UIComponent component)
    {
        /* you have to call the super class */

        FacesContext context = FacesContext.getCurrentInstance();
        super.setProperties(component);

        if(value != null)
        {
            if (isValueReference(value))
             {
                ValueBinding vb = context.getApplication
().createValueBinding(value);
                component.setValueBinding("value", vb);

                // forcing the value from the ValueBinding to the component.

                if(vb != null)
                {
                    if(vb.getValue(context) != null)
                    ((UIInfactHTMLOutput)component).setValue(vb.getValue
(context).toString());
                }
              }
              else
                  ((UIInfactHTMLOutput)component).setValue(value);
        }
    }

thanks in advance!

-Rajiv

Re: [newbie] - simple custom tag problems

Posted by JSFSter Smith <js...@gmail.com>.
Hi Volker,

Thanks! yes that was the problem.
I am getting a better hang of the JSF rendering framework now and it is
pretty powerful!

Thanks again.

-Rajiv

On 11/05/06, Volker Weber <us...@weber-oldenburg.de> wrote:
>
> Hi,
>
> see inline
>
> JSFSter Smith wrote:
> > Hi Volker,
> >
> > Thanks for your response!
> >
> > I attempted the forcing of the ValueBinding in the setProperties() since
> > setting value of the tag attribute was not passed on to the Component
> > Class.
> >
> > In a case like this: <my:testTag value="My message"> (or) <my:testTag>
> > value="#{datapanel.description}">
> >
> > where description is a String, the contents of the 'value' attribute in
> the
> > setProperty method of the Tag class are picked up ok.
> >
> > But in the case when the the  Bean member is not a string (like in the
> > dataTable case), the contents of the value attribute in  setProperty()
> > are :
> > #{datapanel.description}. In this case, the getValue() in my Custom
> > Component class is null and the EL does not seem to be processed.
> >
> > My setProperties() method :
> >    protected void setProperties(UIComponent component)
> >    {
> >        FacesContext context = FacesContext.getCurrentInstance();
> >        super.setProperties(component);
> >
> >        if(value != null)
> >        {
> >            if (isValueReference(value))
> >             {
> >                ValueBinding vb = context.getApplication
> > ().createValueBinding(value);
> >                component.setValueBinding("value", vb);
> >              }
> >              else
> >                  ((UICustomHTMLOutput)component).setValue(value);
> >        }
> >    }
> >
> >
> > And my state and encode methods from the UICustomHTMLOutput:
> >    @Override
> >    public Object saveState(FacesContext context)
> >    {
> >        Object values[] = new Object[2];
> >        values[0] = super.saveState(context);
> >        values[1] = value;
> >        return ((Object) (values));
> >    }
> >
> >    @Override
> >    public void restoreState(FacesContext context, Object state)
> >    {
> >        Object values[] = (Object[])state;
> >        super.restoreState(context, values[0]);
> >        value = (String)values[1];
> >    }
> >
> >    // component render
> >    public void encodeBegin(FacesContext context) throws IOException
> >    {
> >
> >        ResponseWriter writer = context.getResponseWriter();
> >
> >        writer.startElement("p", this);
>
>
> >                writer.write(value);
>
> This is the wrong part. In case of ValueBinding the value is of cause
> null. you need here the same if else as in setProperties():
>
>       if (value != null) {
>         writer.write(value);
>       } else {
>         ValueBinding vb = getValueBinding("value");
>         if (vb != null) {
>           writer.write(vb.getValue(context));
>         }
>       }
>
> Regards,
>   Volker
>
> >                writer.endElement("p");
> >                writer.flush();
> >    }
> >
> > Any help is greatly appreciated. Thanks!
> >
> > -Rajiv
> >
> > On 11/05/06, Volker Weber <us...@weber-oldenburg.de> wrote:
> >
> >>
> >> Hi Rajiv,
> >>
> >>
> >> JSFSter Smith wrote:
> >> >
> >> > Firstly, kudos to the MyFaces team for the recent releases of myfaces
> >> > 1.1.3 and tomahawk 1.1.2!
> >> >
> >> > I am just a few weeks old with JSF and am using it for a current
> >> > project. So far its been great but I am still getting to know the
> >> > deatils. I attempted to create a simple custom JSP tag and was able
> to
> >> > get it together surprisingly quickly. But I do have a problem now. My
> >> > tag essentially renders the string in an attribute "value". Here is a
> >> > sample usage:
> >> >
> >> > <my:testTag value="My message"> (or) <my:testTag
> >> > value="#{datapanel.description}">
> >> >
> >> > But the ValueBinding does not seem to work when I try to access a
> >> member
> >> > of the DataPanel bean that is a collection or another class that has
> >> > members. Examples of these cases are below:
> >> >
> >> > <t:dataTable value="#{datapanel.sentenceDisplayData}" var="each">
> >> >     <t:column>
> >> >         <my:testTag value="#{each.part0}" />
> >> >         <my:testTag value="#{each.part1}" />
> >> >         <my:testTag value="#{each.part2}" />
> >> >         <my:testTag value="#{each.part3}" />
> >> >     </t:column>
> >> > </t:dataTable>
> >> >
> >> > (OR)
> >> > <my:testTag value="#{datapanel.summary.length">
> >> >
> >> > I am including my setProperties method of the TagLib class. Would be
> >> > great if someone can point out what I am missing here.
> >> >
> >> >     protected void setProperties(UIComponent component)
> >> >     {
> >> >         /* you have to call the super class */
> >> >
> >> >         FacesContext context = FacesContext.getCurrentInstance();
> >> >         super.setProperties(component);
> >> >
> >> >         if(value != null)
> >> >         {
> >> >             if (isValueReference(value))
> >> >              {
> >> >                 ValueBinding vb =
> >> > context.getApplication().createValueBinding(value);
> >> >                 component.setValueBinding("value", vb);
> >> >
> >>
> >> ----- remove following ----------
> >> >                 // forcing the value from the ValueBinding to the
> >> > component.
> >> >                 if(vb != null)
> >> >                 {
> >> >                     if(vb.getValue(context) != null)
> >> >
> >> > ((UIInfactHTMLOutput)component).setValue(vb.getValue
> >> (context).toString());
> >> >                 }
> >> ----- / remove following ----------
> >>
> >> Why this? Thats the problem!
> >> Here are the valueBinding evaluated at component creation time, but
> >> datatable needs eavluation at rendering time!
> >>
> >> just remove this an it should do.
> >>
> >>
> >> >               }
> >> >               else
> >> >                   ((UIInfactHTMLOutput)component).setValue(value);
> >> >         }
> >> >     }
> >> >
> >>
> >>
> >> or better implement your set properties using UIComponentTagUtils like
> >> this:
> >>
> >>     protected void setProperties(UIComponent component)
> >>     {
> >>       super.setProperties(component);
> >>       UIComponentTagUtils.setValueProperty(getFacesContext(),
> component,
> >> value);
> >>     }
> >>
> >>
> >>
> >>
> >> Regards,
> >>   Volker
> >>
> >> > thanks in advance!
> >> >
> >> > -Rajiv
> >>
> >> --
> >> Don't answer to From: address!
> >> Mail to this account are droped if not recieved via mailinglist.
> >> To contact me direct create the mail address by
> >> concatenating my forename to my senders domain.
> >>
> >
>
> --
> Don't answer to From: address!
> Mail to this account are droped if not recieved via mailinglist.
> To contact me direct create the mail address by
> concatenating my forename to my senders domain.
>

Re: [newbie] - simple custom tag problems

Posted by Volker Weber <us...@weber-oldenburg.de>.
Hi,

see inline

JSFSter Smith wrote:
> Hi Volker,
> 
> Thanks for your response!
> 
> I attempted the forcing of the ValueBinding in the setProperties() since
> setting value of the tag attribute was not passed on to the Component
> Class.
> 
> In a case like this: <my:testTag value="My message"> (or) <my:testTag>
> value="#{datapanel.description}">
> 
> where description is a String, the contents of the 'value' attribute in the
> setProperty method of the Tag class are picked up ok.
> 
> But in the case when the the  Bean member is not a string (like in the
> dataTable case), the contents of the value attribute in  setProperty()
> are :
> #{datapanel.description}. In this case, the getValue() in my Custom
> Component class is null and the EL does not seem to be processed.
> 
> My setProperties() method :
>    protected void setProperties(UIComponent component)
>    {
>        FacesContext context = FacesContext.getCurrentInstance();
>        super.setProperties(component);
> 
>        if(value != null)
>        {
>            if (isValueReference(value))
>             {
>                ValueBinding vb = context.getApplication
> ().createValueBinding(value);
>                component.setValueBinding("value", vb);
>              }
>              else
>                  ((UICustomHTMLOutput)component).setValue(value);
>        }
>    }
> 
> 
> And my state and encode methods from the UICustomHTMLOutput:
>    @Override
>    public Object saveState(FacesContext context)
>    {
>        Object values[] = new Object[2];
>        values[0] = super.saveState(context);
>        values[1] = value;
>        return ((Object) (values));
>    }
> 
>    @Override
>    public void restoreState(FacesContext context, Object state)
>    {
>        Object values[] = (Object[])state;
>        super.restoreState(context, values[0]);
>        value = (String)values[1];
>    }
> 
>    // component render
>    public void encodeBegin(FacesContext context) throws IOException
>    {
> 
>        ResponseWriter writer = context.getResponseWriter();
> 
>        writer.startElement("p", this);


>                writer.write(value);

This is the wrong part. In case of ValueBinding the value is of cause
null. you need here the same if else as in setProperties():

      if (value != null) {
        writer.write(value);
      } else {
        ValueBinding vb = getValueBinding("value");
        if (vb != null) {
          writer.write(vb.getValue(context));
        }
      }

Regards,
  Volker

>                writer.endElement("p");
>                writer.flush();
>    }
> 
> Any help is greatly appreciated. Thanks!
> 
> -Rajiv
> 
> On 11/05/06, Volker Weber <us...@weber-oldenburg.de> wrote:
> 
>>
>> Hi Rajiv,
>>
>>
>> JSFSter Smith wrote:
>> >
>> > Firstly, kudos to the MyFaces team for the recent releases of myfaces
>> > 1.1.3 and tomahawk 1.1.2!
>> >
>> > I am just a few weeks old with JSF and am using it for a current
>> > project. So far its been great but I am still getting to know the
>> > deatils. I attempted to create a simple custom JSP tag and was able to
>> > get it together surprisingly quickly. But I do have a problem now. My
>> > tag essentially renders the string in an attribute "value". Here is a
>> > sample usage:
>> >
>> > <my:testTag value="My message"> (or) <my:testTag
>> > value="#{datapanel.description}">
>> >
>> > But the ValueBinding does not seem to work when I try to access a
>> member
>> > of the DataPanel bean that is a collection or another class that has
>> > members. Examples of these cases are below:
>> >
>> > <t:dataTable value="#{datapanel.sentenceDisplayData}" var="each">
>> >     <t:column>
>> >         <my:testTag value="#{each.part0}" />
>> >         <my:testTag value="#{each.part1}" />
>> >         <my:testTag value="#{each.part2}" />
>> >         <my:testTag value="#{each.part3}" />
>> >     </t:column>
>> > </t:dataTable>
>> >
>> > (OR)
>> > <my:testTag value="#{datapanel.summary.length">
>> >
>> > I am including my setProperties method of the TagLib class. Would be
>> > great if someone can point out what I am missing here.
>> >
>> >     protected void setProperties(UIComponent component)
>> >     {
>> >         /* you have to call the super class */
>> >
>> >         FacesContext context = FacesContext.getCurrentInstance();
>> >         super.setProperties(component);
>> >
>> >         if(value != null)
>> >         {
>> >             if (isValueReference(value))
>> >              {
>> >                 ValueBinding vb =
>> > context.getApplication().createValueBinding(value);
>> >                 component.setValueBinding("value", vb);
>> >
>>
>> ----- remove following ----------
>> >                 // forcing the value from the ValueBinding to the
>> > component.
>> >                 if(vb != null)
>> >                 {
>> >                     if(vb.getValue(context) != null)
>> >
>> > ((UIInfactHTMLOutput)component).setValue(vb.getValue
>> (context).toString());
>> >                 }
>> ----- / remove following ----------
>>
>> Why this? Thats the problem!
>> Here are the valueBinding evaluated at component creation time, but
>> datatable needs eavluation at rendering time!
>>
>> just remove this an it should do.
>>
>>
>> >               }
>> >               else
>> >                   ((UIInfactHTMLOutput)component).setValue(value);
>> >         }
>> >     }
>> >
>>
>>
>> or better implement your set properties using UIComponentTagUtils like
>> this:
>>
>>     protected void setProperties(UIComponent component)
>>     {
>>       super.setProperties(component);
>>       UIComponentTagUtils.setValueProperty(getFacesContext(), component,
>> value);
>>     }
>>
>>
>>
>>
>> Regards,
>>   Volker
>>
>> > thanks in advance!
>> >
>> > -Rajiv
>>
>> -- 
>> Don't answer to From: address!
>> Mail to this account are droped if not recieved via mailinglist.
>> To contact me direct create the mail address by
>> concatenating my forename to my senders domain.
>>
> 

-- 
Don't answer to From: address!
Mail to this account are droped if not recieved via mailinglist.
To contact me direct create the mail address by
concatenating my forename to my senders domain.

Re: [newbie] - simple custom tag problems

Posted by JSFSter Smith <js...@gmail.com>.
Hi Volker,

Thanks for your response!

I attempted the forcing of the ValueBinding in the setProperties() since
setting value of the tag attribute was not passed on to the Component Class.

In a case like this: <my:testTag value="My message"> (or) <my:testTag>
value="#{datapanel.description}">

where description is a String, the contents of the 'value' attribute in the
setProperty method of the Tag class are picked up ok.

But in the case when the the  Bean member is not a string (like in the
dataTable case), the contents of the value attribute in  setProperty() are :
#{datapanel.description}. In this case, the getValue() in my Custom
Component class is null and the EL does not seem to be processed.

My setProperties() method :
    protected void setProperties(UIComponent component)
    {
        FacesContext context = FacesContext.getCurrentInstance();
        super.setProperties(component);

        if(value != null)
        {
            if (isValueReference(value))
             {
                ValueBinding vb = context.getApplication
().createValueBinding(value);
                component.setValueBinding("value", vb);
              }
              else
                  ((UICustomHTMLOutput)component).setValue(value);
        }
    }


And my state and encode methods from the UICustomHTMLOutput:
    @Override
    public Object saveState(FacesContext context)
    {
        Object values[] = new Object[2];
        values[0] = super.saveState(context);
        values[1] = value;
        return ((Object) (values));
    }

    @Override
    public void restoreState(FacesContext context, Object state)
    {
        Object values[] = (Object[])state;
        super.restoreState(context, values[0]);
        value = (String)values[1];
    }

    // component render
    public void encodeBegin(FacesContext context) throws IOException
    {

        ResponseWriter writer = context.getResponseWriter();

        writer.startElement("p", this);
                writer.write(value);
                writer.endElement("p");
                writer.flush();
    }

Any help is greatly appreciated. Thanks!

-Rajiv

On 11/05/06, Volker Weber <us...@weber-oldenburg.de> wrote:
>
> Hi Rajiv,
>
>
> JSFSter Smith wrote:
> >
> > Firstly, kudos to the MyFaces team for the recent releases of myfaces
> > 1.1.3 and tomahawk 1.1.2!
> >
> > I am just a few weeks old with JSF and am using it for a current
> > project. So far its been great but I am still getting to know the
> > deatils. I attempted to create a simple custom JSP tag and was able to
> > get it together surprisingly quickly. But I do have a problem now. My
> > tag essentially renders the string in an attribute "value". Here is a
> > sample usage:
> >
> > <my:testTag value="My message"> (or) <my:testTag
> > value="#{datapanel.description}">
> >
> > But the ValueBinding does not seem to work when I try to access a member
> > of the DataPanel bean that is a collection or another class that has
> > members. Examples of these cases are below:
> >
> > <t:dataTable value="#{datapanel.sentenceDisplayData}" var="each">
> >     <t:column>
> >         <my:testTag value="#{each.part0}" />
> >         <my:testTag value="#{each.part1}" />
> >         <my:testTag value="#{each.part2}" />
> >         <my:testTag value="#{each.part3}" />
> >     </t:column>
> > </t:dataTable>
> >
> > (OR)
> > <my:testTag value="#{datapanel.summary.length">
> >
> > I am including my setProperties method of the TagLib class. Would be
> > great if someone can point out what I am missing here.
> >
> >     protected void setProperties(UIComponent component)
> >     {
> >         /* you have to call the super class */
> >
> >         FacesContext context = FacesContext.getCurrentInstance();
> >         super.setProperties(component);
> >
> >         if(value != null)
> >         {
> >             if (isValueReference(value))
> >              {
> >                 ValueBinding vb =
> > context.getApplication().createValueBinding(value);
> >                 component.setValueBinding("value", vb);
> >
>
> ----- remove following ----------
> >                 // forcing the value from the ValueBinding to the
> > component.
> >                 if(vb != null)
> >                 {
> >                     if(vb.getValue(context) != null)
> >
> > ((UIInfactHTMLOutput)component).setValue(vb.getValue
> (context).toString());
> >                 }
> ----- / remove following ----------
>
> Why this? Thats the problem!
> Here are the valueBinding evaluated at component creation time, but
> datatable needs eavluation at rendering time!
>
> just remove this an it should do.
>
>
> >               }
> >               else
> >                   ((UIInfactHTMLOutput)component).setValue(value);
> >         }
> >     }
> >
>
>
> or better implement your set properties using UIComponentTagUtils like
> this:
>
>     protected void setProperties(UIComponent component)
>     {
>       super.setProperties(component);
>       UIComponentTagUtils.setValueProperty(getFacesContext(), component,
> value);
>     }
>
>
>
>
> Regards,
>   Volker
>
> > thanks in advance!
> >
> > -Rajiv
>
> --
> Don't answer to From: address!
> Mail to this account are droped if not recieved via mailinglist.
> To contact me direct create the mail address by
> concatenating my forename to my senders domain.
>

Re: [newbie] - simple custom tag problems

Posted by Volker Weber <us...@weber-oldenburg.de>.
Hi Rajiv,


JSFSter Smith wrote:
> 
> Firstly, kudos to the MyFaces team for the recent releases of myfaces
> 1.1.3 and tomahawk 1.1.2!
> 
> I am just a few weeks old with JSF and am using it for a current
> project. So far its been great but I am still getting to know the
> deatils. I attempted to create a simple custom JSP tag and was able to
> get it together surprisingly quickly. But I do have a problem now. My
> tag essentially renders the string in an attribute "value". Here is a
> sample usage:
> 
> <my:testTag value="My message"> (or) <my:testTag
> value="#{datapanel.description}">
> 
> But the ValueBinding does not seem to work when I try to access a member
> of the DataPanel bean that is a collection or another class that has
> members. Examples of these cases are below:
> 
> <t:dataTable value="#{datapanel.sentenceDisplayData}" var="each">
>     <t:column>
>         <my:testTag value="#{each.part0}" />
>         <my:testTag value="#{each.part1}" />
>         <my:testTag value="#{each.part2}" />
>         <my:testTag value="#{each.part3}" />
>     </t:column>
> </t:dataTable>
> 
> (OR)
> <my:testTag value="#{datapanel.summary.length">
> 
> I am including my setProperties method of the TagLib class. Would be
> great if someone can point out what I am missing here.
> 
>     protected void setProperties(UIComponent component)
>     {
>         /* you have to call the super class */
> 
>         FacesContext context = FacesContext.getCurrentInstance();
>         super.setProperties(component);
>        
>         if(value != null)
>         {
>             if (isValueReference(value))
>              {
>                 ValueBinding vb =
> context.getApplication().createValueBinding(value);
>                 component.setValueBinding("value", vb);
> 

----- remove following ----------
>                 // forcing the value from the ValueBinding to the
> component.
>                 if(vb != null)
>                 {
>                     if(vb.getValue(context) != null)
>                    
> ((UIInfactHTMLOutput)component).setValue(vb.getValue(context).toString());
>                 }
----- / remove following ----------

Why this? Thats the problem!
Here are the valueBinding evaluated at component creation time, but
datatable needs eavluation at rendering time!

just remove this an it should do.


>               }
>               else
>                   ((UIInfactHTMLOutput)component).setValue(value);
>         }
>     }
> 


or better implement your set properties using UIComponentTagUtils like this:

    protected void setProperties(UIComponent component)
    {
      super.setProperties(component);
      UIComponentTagUtils.setValueProperty(getFacesContext(), component,
value);
    }




Regards,
  Volker

> thanks in advance!
> 
> -Rajiv

-- 
Don't answer to From: address!
Mail to this account are droped if not recieved via mailinglist.
To contact me direct create the mail address by
concatenating my forename to my senders domain.