rich:columns howto add onclick for certain columns?
mail.micke Jul 8, 2008 9:31 AMHi
I have a tricky use-case to which I'm trying to find a nice solution and need some help.
My problem is that for some columns I want to call some java script functions for popping up new browser windows. The different functions will require one or more parameter, typically the value displayed in the cell. The values needed as parameters will come from the current row item being rendered.
How can I do this?
If it wasn't for the fact that I needed the cell value as a parameter I could have just defined a new String in the ColumnDescriptor class with the JS function to call, but it has to be dynamic with one or more parameter.
The only thing I've thought of this far is to create a Facelets source tag and have loads of outputs where only one would be rendered by looking at the ColumnDescriptor.valueProperty but this doesn't feel nice.
Any suggestion would be very welcome.
Something like this is what I don't want to end up with:
SoureTag.xhtml I wish to avoid :
<a4j:outputPanel rendered="#{col.valueProperty eq 'getSomething1'}" style="margin: 0px 0px 0px 0px;padding: 0px 0px 0px 0px;width:100%;height:100%" onclick="javascript:myOnClick1('hello there', #{item[col.valueProperty]})"> #{item[col.valueProperty]} </a4j:outputPanel> <a4j:outputPanel rendered="#{col.valueProperty eq 'getSomething2'}" style="margin: 0px 0px 0px 0px;padding: 0px 0px 0px 0px;width:100%;height:100%" onclick="javascript:myOnClick2'hello there')"> #{item[col.valueProperty]} </a4j:outputPanel> <a4j:outputPanel rendered="#{col.valueProperty eq 'getSomething3'}" style="margin: 0px 0px 0px 0px;padding: 0px 0px 0px 0px;width:100%;height:100%"> #{item[col.valueProperty]} </a4j:outputPanel> // and so on
The code:
XHTML, with dummy onclick:
<rich:dataTable id="listingTable" value="#{sdb2.allPositionWrappers}" var="item" rows="25" style="width:95%;"> <f:facet name="header"> <rich:columnGroup> <rich:column colspan="#{sdb2.visibleColumnCount}"> <rich:datascroller for="listingTable" ajaxSingle="false" renderIfSinglePage="false"/> </rich:column> </rich:columnGroup> </f:facet> <rich:columns value="#{sdb2.columns}" sortBy="#{item[col.valueProperty]}" var="col"> <f:facet name="header"> <a4j:outputPanel layout="inline"> #{col.header} </a4j:outputPanel> </f:facet> <a4j:outputPanel style="margin: 0px 0px 0px 0px;padding: 0px 0px 0px 0px;width:100%;height:100%" onclick="javascript:myOnClick('hello there')"> #{item[col.valueProperty]} </a4j:outputPanel> </rich:columns> </rich:dataTable>
Backing bean.
Simply returns a list of ObjectWrappers (which are initialized via @Create)
public void setAllPositionWrappers(List<ObjectWrapper> aAllPositionWrappers) { allPositionWrappers = aAllPositionWrappers; }
ObjectWrapper.java. This class just wraps another object and access its properties via the Map interface.
public class ObjectWrapper implements Map<String,Object>{ private Object realObject; public ObjectWrapper(Object realObject){ this.realObject = realObject; } public Object get(Object methodName) { Object retVal = invokeGetter(realObject, (String)methodName); return retVal; } @SuppressWarnings("unchecked") public Object invokeGetter(Object obj, String methodName){ String getMethodName = null; if(!methodName.startsWith("get")){ getMethodName = methodName.substring(0,1).toUpperCase(); getMethodName = "get"+getMethodName+methodName.substring(1); } else{ getMethodName = methodName; } Class c = obj.getClass(); try { Method m = c.getMethod(getMethodName, new Class[]{}); return m.invoke(obj,(Object[]) null); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } //cut
ColumnDescriptor.java , describes one column.
public class ColumnDescriptor { private String header;//column header private String footer;// column footer private String valueProperty;// How to get the value via reflections, ex: "getStartDate" private boolean visible; // Is column visible public ColumnDescriptor(String header, String footer, String valueProperty) { super(); this.header = header; this.footer = footer; this.valueProperty = valueProperty; this.visible = true; } public boolean isVisible() { return visible; } public void setVisible(boolean visible) { this.visible = visible; } public String getHeader() { return header; } public void setHeader(String header) { this.header = header; } public String getFooter() { return footer; } public void setFooter(String footer) { this.footer = footer; } public String getValueProperty() { return valueProperty; } public void setValueProperty(String valueProperty) { this.valueProperty = valueProperty; } }
Cheers,
Micke