Hi Greg,
Many thanks for sharing your code.
I was also working on something similar but I did not get a working
solution with valueBindings and datatables.
Now I'm really curious about your version and added it to my project.
But I get the following error (see below) on a really simple page.
Do you have any ideas?
I am using MyFaces 1.1.1.
http-8080-Processor25 [ERROR]
org.apache.catalina.core.ApplicationDispatcher invoke: Servlet.service()
for servlet jsp threw exception
org.apache.jasper.JasperException: Unable to compile class for JSP
An error occurred at line: 18 in the jsp file: /pages/catWizard.jsp
Generated servlet error:
The method setPageContext(PageContext) is undefined for the type
TruncateConverter
An error occurred at line: 18 in the jsp file: /pages/catWizard.jsp
Generated servlet error:
The method setParent(Tag) is undefined for the type TruncateConverter
An error occurred at line: 18 in the jsp file: /pages/catWizard.jsp
Generated servlet error:
The method doStartTag() is undefined for the type TruncateConverter
Generated servlet error:
The method doEndTag() is undefined for the type TruncateConverter
Generated servlet error:
The method reuse(Tag) in the type TagHandlerPool is not applicable for
the arguments (TruncateConverter)
Generated servlet error:
The method reuse(Tag) in the type TagHandlerPool is not applicable for
the arguments (TruncateConverter)
at
org.apache.jasper.compiler.DefaultErrorHandler.javacError(DefaultErrorHa
ndler.java:84)
at
org.apache.jasper.compiler.ErrorDispatcher.javacError(ErrorDispatcher.ja
va:328)
at
org.apache.jasper.compiler.JDTCompiler.generateClass(JDTCompiler.java:40
9)
at
org.apache.jasper.compiler.Compiler.compile(Compiler.java:288)
at
org.apache.jasper.compiler.Compiler.compile(Compiler.java:267)
at
org.apache.jasper.compiler.Compiler.compile(Compiler.java:255)
-----Original Message-----
From: Lindholm, Greg [mailto:[EMAIL PROTECTED]
Sent: Dienstag, 11. April 2006 15:23
To: MyFaces Discussion
Subject: RE: tag to truncate outputText?
-----Original Message-----
From: Mike Kienenberger [mailto:[EMAIL PROTECTED]
Sent: Thursday, April 06, 2006 2:03 PM
> String converters aren't allowed in JSF 1.1, but they are in 1.2.
> Otherwise a converter would be a good choice.
Not sure what you meant by "String converters aren't allowed" I saw
several examples in books so I wrote one and it works great.
(It's not a true "converter" since it only handles output.)
I call it truncateOutput and it takes two attributes a truncateAt
position
and an optional continuationMark.
<h:outputText value="#{var.description}">
<xxx:truncateOutput truncateAt="35" continuationMark="..." />
</h:outputText>
Here are all the pieces, if anyone want to package them up
for contribution to tomahawk that would be great!
I don't have the time (or knowledge how) to do it right now.
TruncateConverter.java
----------------------
public class TruncateConverter implements Converter, StateHolder
{
private int truncateAt = 0;
private String continuationMark;
private boolean transientFlag;
public Object getAsObject(FacesContext context,
UIComponent component,
String value) throws ConverterException
{
// Should never happend - TruncateConverter is only usable for
output.
throw new AssertionError(getClass().getName()
+ " does not support Input conversion.");
}
public String getAsString(FacesContext context,
UIComponent component,
Object value) throws ConverterException
{
if (value == null)
{
return null;
}
StringBuffer buff = new StringBuffer();
buff.append(value);
if (getTruncateAt() > 0 && buff.length() > getTruncateAt())
{
buff.setLength(getTruncateAt());
if (getContinuationMark() != null)
{
buff.append(getContinuationMark());
}
}
return buff.toString();
}
/**
* @return Returns the continuationMark.
*/
public String getContinuationMark()
{
return continuationMark;
}
/**
* @param continuationMark The continuationMark to set.
*/
public void setContinuationMark(String continuationMark)
{
this.continuationMark = continuationMark;
}
/**
* @return Returns the truncateAt.
*/
public int getTruncateAt()
{
return truncateAt;
}
/**
* @param truncateAt The truncateAt to set.
*/
public void setTruncateAt(int truncateAt)
{
this.truncateAt = truncateAt;
}
// STATE SAVE/RESTORE
public void restoreState(FacesContext facesContext, Object state)
{
Object[] values = (Object[]) state;
this.truncateAt = ((Integer) values[0]).intValue();
this.continuationMark = (String) values[1];
}
public Object saveState(FacesContext facesContext)
{
Object[] values = new Object[2];
values[0] = new Integer(getTruncateAt());
values[1] = getContinuationMark();
return values;
}
public boolean isTransient()
{
return transientFlag;
}
public void setTransient(boolean aTransient)
{
transientFlag = aTransient;
}
}
TruncateConverterTag.java
--------------------------
public class TruncateConverterTag extends ConverterTag
{
private static final long serialVersionUID = -5486065206529786966L;
public TruncateConverterTag()
{
setConverterId("xxx.TruncateConverter");
}
private String truncateAt;
private String continuationMark;
protected Converter createConverter() throws JspException
{
TruncateConverter converter = (TruncateConverter)
super.createConverter();
FacesContext facesContext = FacesContext.getCurrentInstance();
setConverterTruncateAt(facesContext, converter, truncateAt);
setContinuationMark(facesContext, converter, continuationMark);
return converter;
}
public void release()
{
truncateAt = null;
continuationMark = null;
}
/**
* Set the continuation mark to be used if the value is truncated.
(E.g. "...")
* @param continuationMark expression that evaluates to a String.
*/
public void setContinuationMark(String continuationMark)
{
this.continuationMark = continuationMark;
}
/**
* Set the position to truncate the value.
* @param truncateAt expression that evaluates to an int.
*/
public void setTruncateAt(String truncateAt)
{
this.truncateAt = truncateAt;
}
private static void setConverterTruncateAt(FacesContext
facesContext,
TruncateConverter
converter,
String value)
{
if (value == null)
{
converter.setTruncateAt(0);
}
else if (UIComponentTag.isValueReference(value))
{
ValueBinding vb =
facesContext.getApplication().createValueBinding(
value);
Object o = vb.getValue(facesContext);
if (o instanceof Number)
{
converter.setTruncateAt(((Number) o).intValue());
}
else
{
converter.setTruncateAt(Integer.parseInt(o.toString()));
}
}
else
{
converter.setTruncateAt(Integer.parseInt(value));
}
}
private static void setContinuationMark(FacesContext facesContext,
TruncateConverter converter,
String value)
{
if (value == null)
{
converter.setContinuationMark(null);
}
else if (UIComponentTag.isValueReference(value))
{
ValueBinding vb =
facesContext.getApplication().createValueBinding(
value);
converter.setContinuationMark((String)
vb.getValue(facesContext));
}
else
{
converter.setContinuationMark(value);
}
}
}
>From the TLD
------------
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>xxx</short-name>
<tag>
<name>truncateOutput</name>
<tag-class>xxx.TruncateConverterTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>truncateAt</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
<description>position to truncate
at</description>
</attribute>
<attribute>
<name>continuationMark</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<description>String to append when trancated
(eg. "...")</description>
</attribute>
</tag>
</taglib>
>From the Faces Config file
--------------------------
<faces-config>
<converter>
<converter-id>xxx.TruncateConverter</converter-id>
<converter-class>xxx.TruncateConverter</converter-class>
</converter>
</faces-config>