multilevel tree with struts2 - struts2

I am new in Struts2 and jQuery.
I am try to make a tree with TreeTag struts2-jquery.
But I try to make two levels.
This is my code.
In action.
public class TreeCategoriasAction extends ActionSupport {
private static final long serialVersionUID = 1421993767228006685L;
private FMCategorias fMCategorias;
public FMCategorias getCategorias() { return fMCategorias; }
private TreeNode nodes = new TreeNode();
public String execute() throws Exception {
SmpConsultaCategorias smpConsultaCategorias = new SmpConsultaCategorias();
smpConsultaCategorias.setCategoriaFilter(new SoCategoriaFilter());
smpConsultaCategorias.getCategoriaFilter().setCoIdioma(ActionContext.getContext().getLocale().getLanguage().toUpperCase());
SWGestionarCategoriasProxy proxy = new SWGestionarCategoriasProxy(TiendaWebProperties.getProperty(TiendaWebProperties.SERVICIO_CATEGORIAS_ENDPOINT));
SoCategoria[] soCategoriaArray = proxy.consultaCategorias(smpConsultaCategorias);
fMCategorias = Mapeador.mapear(soCategoriaArray);
ServletActionContext.getRequest().setAttribute("categorias", fMCategorias);
nodes.setId("Categorias");
nodes.setState(TreeNode.NODE_STATE_OPEN);
nodes.setTitle("Categorias");
TreeNode [] nodo = new TreeNode[soCategoriaArray.length];
Collection<TreeNode> children = new ArrayList<TreeNode>();
for (int i = 0; i < soCategoriaArray.length; i++) {
if (soCategoriaArray[i].getIdCategoriaPadre() == null) {
nodo[i]=new TreeNode();
nodo[i].setId(soCategoriaArray[i].getIdCategoria());
nodo[i].setState(TreeNode.NODE_STATE_OPEN);
nodo[i].setTitle(soCategoriaArray[i].getDeCategoria());
children.add(nodo[i]);
for (int j = 0; j < soCategoriaArray.length; j++){
if (soCategoriaArray[j].getIdCategoriaPadre() == soCategoriaArray[i].getIdCategoria()){
Collection<TreeNode> children2 = new ArrayList<TreeNode>();
nodo[j]=new TreeNode();
nodo[j].setId(soCategoriaArray[j].getIdCategoria());
nodo[j].setState(TreeNode.NODE_STATE_CLOSED);
nodo[j].setTitle(soCategoriaArray[j].getDeCategoria());
children2.add(nodo[j]);
nodo[i].setChildren(children2);
}
}
}
nodes.setChildren(children);
}
return SUCCESS;
}
public TreeNode getNodes() {
return nodes;
}
}
In jsp
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
<%# taglib prefix="sjt" uri="/struts-jquery-tree-tags"%>
<%#taglib prefix="s" uri="/struts-tags" %>
<sj:head jqueryui="true" customBasepath="css" jquerytheme="jquery_tree_ui"debug="true" />
<s:url var="treeCategoriasUrl" action="TreeCategorias.action"/>
<sjt:tree
id="treeDynamicAjax"
jstreetheme="apple"
rootNode="nodes"
nodeHref="%{echo}"
nodeTitleProperty="title"
nodeIdProperty="id"
nodeHrefParamName="echo"
childCollectionProperty="children"
/>
<s:iterator value=#nodo[i]>
<sjt:tree
id="treeDynamicAjax2"
jstreetheme="apple"
rootNode="#nodo[i]"
nodeHref="%{echo}"
nodeTitleProperty="title"
nodeIdProperty="id"
nodeHrefParamName="echo"
childCollectionProperty="children2"
/>
</s:iterator>
Only works the first for and the first tree.
Can anybody help me?

In action
nodes.setId("Bricor");
nodes.setState(TreeNode.NODE_STATE_OPEN);
nodes.setTitle("Bricor");
getTreeNode (soCategoriaArray, nodes, null);
private void getTreeNode(SoCategoria[] soCategoriaArray, TreeNode nodoPadre, String idCategoriaPadre) {
List<TreeNode> nodos = new ArrayList<TreeNode>();
for (int i = 0; i < soCategoriaArray.length; i++){
if ((idCategoriaPadre == null && soCategoriaArray[i].getIdCategoriaPadre() == null) || (soCategoriaArray[i].getIdCategoriaPadre() != null && soCategoriaArray[i].getIdCategoriaPadre().equals(idCategoriaPadre))){
TreeNode nodo = new TreeNode();
nodo.setId(soCategoriaArray[i].getIdCategoria());
nodo.setState(TreeNode.NODE_STATE_OPEN);
nodo.setTitle(soCategoriaArray[i].getDeCategoria());
nodos.add(nodo);
getTreeNode(soCategoriaArray, nodo, soCategoriaArray[i].getIdCategoria());
}
}
nodoPadre.setChildren(nodos);
}
In jsp
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
<%# taglib prefix="sjt" uri="/struts-jquery-tree-tags"%>
%#taglib prefix="s" uri="/struts-tags" %>
<sj:head jqueryui="true" customBasepath="css" jquerytheme="jquery_tree_ui" debug="true" />
<s:url var="treeCategoriasUrl" action="TreeCategorias.action"/>
<sjt:tree
id="treeDynamicAjax"
jstreetheme="apple"
rootNode="nodes"
nodeHref="%{echo}"
nodeTitleProperty="title"
nodeIdProperty="id"
nodeHrefParamName="echo"
childCollectionProperty="children"
/>

Related

Struts2 jQuery Plugin issue with Double Select

I have a little (I hope) issue trying to use Doubleselect element from Struts2 jQuery plugin and after searching the internet I found nothing about it so I come here to get your help.
I have a jsp with two struts2 jQuery Plugin selects to get the second select (Modelo) loaded based of the item selected from the first one (Fabricante). When the jsp is loaded, the first select is loaded; but when I select an item from this first select, the value of this selected item does not arrive (is value is null) to the action so there is no way to query the values for the second select from database; consequently, second select is never loaded.
I have followed the sample from the struts2-jquery-showcase.
Some info about my app:
struts2 2.3
tiles
Spring 3.1 (I have struts2-spring integration)
Following the code snippets from some files
JSP code for the tiles layout
<%# page contentType="text/html;charset=UTF-8" language="java"%>
<%# taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
<tiles:importAttribute/>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript">
var GB_ROOT_DIR = "res/greybox/";
</script>
<script type="text/javascript" src="res/greybox/AJS.js"></script>
<script type="text/javascript" src="res/greybox/AJS_fx.js"></script>
<script type="text/javascript" src="res/greybox/gb_scripts.js"></script>
<...>
<sj:head jqueryui="true" />
</head>
<body leftmargin="0" topmargin="0" marginheight="0" marginwidth="0">
<tiles:insertAttribute name="header" />
<tiles:insertAttribute name="menu" />
<...>
<tiles:insertAttribute name="content" />
</body>
</html>
JSP code
<%# page contentType="text/html;charset=UTF-8" language="java"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<%# taglib prefix="display" uri="http://displaytag.sf.net"%>
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
<...>
<s:form action="nuevaReparacion2" validate="true" onsubmit="return checkSubmit();" name="formulario" method="post">
<...>
<table cellpadding="0" cellspacing="0" width="900">
<tr>
<td height="2"> Fabricante:
<s:url id="remoteurl" action="nuevaReparacionCargaModelo"/>
<sj:select
href="%{remoteurl}"
id="selectFab"
onChangeTopics="reloadModelos"
name="idFabricante"
list="listFabricantes"
listKey="id"
listValue="nombre"
emptyOption="false"
headerKey="-1"
headerValue="Seleccione un fabricante"
indicator="indicator"
/>
<img id="indicator"
src="res/images/ajax-loader.gif"
alt="cargando..."
style="display:none"
/>
</td>
<td height="2">Modelo:
<sj:select
href="%{remoteurl}"
id="selectMod"
formIds="formulario"
reloadTopics="reloadModelos"
name="idModelo"
list="listModelos"
listKey="id"
listValue="nombre"
emptyOption="false"
headerKey="-1"
headerValue="Seleccione un modelo"
indicator="indicator2"
/>
<img id="indicator2"
src="res/images/ajax-loader.gif"
alt="cargando..."
style="display:none"
/>
</td>
</tr>
</table>
<...>
web.xml
<...>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/spring-context.xml</param-value>
</context-param>
<context-param>
<param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
<param-value>/WEB-INF/classes/tiles.xml</param-value>
</context-param>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/struts/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
</listener>
<...>
struts.xml
<...>
<interceptor-stack name="authenticationMinimalStack">
<interceptor-ref name="exception" />
<interceptor-ref name="servletConfig" />
<interceptor-ref name="securityInterceptor" />
<interceptor-ref name="prepare" />
<interceptor-ref name="checkbox" />
<interceptor-ref name="multiselect" />
<interceptor-ref name="chain" />
<interceptor-ref name="fileUpload">
<!-- <param name="maximumSize">50000000</param> -->
<param name="maximumSize">80000000</param>
</interceptor-ref>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="staticParams" />
<interceptor-ref name="params"/>
<interceptor-ref name="workflow" />
</interceptor-stack>
<...>
<...>
<action name="nuevaReparacionCargaModelo" method="cargaModeloFabricante" class="nuevaReparacionAction">
<interceptor-ref name="authenticationMinimalStack" />
<result name="pajax" type="json"></result>
</action>
<...>
Action class code
public class NuevaReparacionAction extends AbstractAction<NuevaReparacionForm> {
<...>
public String init() throws Exception {
if (model.getListFabricantes() == null) {
List<Fabricante> listFabricantes = referenceDataService.getAllFabricantes();
model.setListFabricantes(listFabricantes);
}
<...>
}
<...>
public String cargaModeloFabricante() throws Exception {
if(StringUtils.isNotEmpty(idFabricante)){
List<Modelo> listModelos = referenceDataService.getAllModelosPorFab(idFabricante);
model.setListModelos(listModelos);
}
String res = "pajax";
return res;
}
<...>
}
Form class code
public class NuevaReparacionForm extends AbstractActionForm {
<...>
private List<Fabricante> listFabricantes;
private String idFabricante;
private List<Modelo> listModelos;
private String idModelo;
<...>
public List<Fabricante> getListFabricantes() {
return listFabricantes;
}
public void setListFabricantes(List<Fabricante> listFabricantes) {
this.listFabricantes = listFabricantes;
}
public String getIdFabricante() {
return idFabricante;
}
public void setIdFabricante(String idFabricante) {
this.idFabricante = idFabricante;
}
public List<Modelo> getListModelos() {
return listModelos;
}
public void setListModelos(List<Modelo> listModelos) {
this.listModelos = listModelos;
}
public String getIdModelo() {
return idModelo;
}
public void setIdModelo(String idModelo) {
this.idModelo = idModelo;
}
<...>
The Fabricante bean
public class Fabricante extends AbstractObject<Long> {
private static final long serialVersionUID = -3767216824782509270L;
private boolean indRepara;
public boolean isIndRepara() {
return indRepara;
}
public void setIndRepara(boolean indRepara) {
this.indRepara = indRepara;
}
#Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (!obj.getClass().equals(getClass())) {
return false;
}
Fabricante castedObj = (Fabricante) obj;
return ObjectUtils.equals(getId(), castedObj.getId());
}
#Override
public String toString() {
return new ToStringBuilder(this)
.append("id", getId())
.append("nombre", getNombre())
.toString();
}
}
The Modelo bean
public class Modelo extends AbstractObject<Long> {
private static final long serialVersionUID = -5167217040308921281L;
private Fabricante fabricante;
public Fabricante getFabricante() {
return fabricante;
}
public void setFabricante(Fabricante fabricante) {
this.fabricante = fabricante;
}
#Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (!obj.getClass().equals(getClass())) {
return false;
}
Modelo castedObj = (Modelo) obj;
return ObjectUtils.equals(getId(), castedObj.getId());
}
#Override
public String toString() {
return new ToStringBuilder(this)
.append("id", getId())
.append("nombre", getNombre())
.toString();
}
}
The superclass for the beans
public class AbstractObject<T> {
/**
*
*/
private static final long serialVersionUID = 7717102673045778131L;
/**
* The object id
*/
private T id;
private String nombre;
/**
* Setter for attribute "id"
* #param id the object id
*
public void setId(T id) {
this.id = id;
}
/**
* Getter for attribute "id"
* #return the object id
*
public T getId() {
return id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
Thanks in advance.

GridView Remove Item C# 2.0

What I need to do is to have the ability to remove an item from a Grid View and then update the recordset that it was removed.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" BackColor="White" Font-Size="X-Small">
<Columns>
<asp:BoundField DataField="File" HeaderText="File" />
<asp:BoundField DataField="Remove" HeaderText="Remove" />
</Columns>
</asp:GridView>
// Backend...
private void BindGridview(ArrayList list)
{
DataTable dt = new DataTable();
dt.Columns.Add("File");
dt.Columns.Add("Remove");
int c = list.Count;
for (int i = 0; i < c; i++)
{
dt.Rows.Add();
dt.Rows[i]["file"] = list[i].ToString();
dt.Rows[i]["Remove"] = ""; // <--- Have a remove action here????
}
GridView1.DataSource = dt;
GridView1.DataBind();
}

<h:commandButton> does not initiate a postback

I am using JSF 2.1.7 and Myfaces CODI 1.0.5 on JBoss AS 7.1.1. My <h:commandButton> is not working. I have read the requirements and have through examples in many blogs all to no avail. My facelets code is as follows
<ui:define name="pagecontent">
<h1 class="title ui-widget-header ui-corner-all">Upload Bulk Contact File</h1>
<div class="entry">
<h:form enctype="multipart/form-data" id="upload">
<p:panel closable="false" collapsed="false" header="Excel Contact Uploader"
id="pnlupload" rendered="true" toggleable="false" visible="true" widgetVar="pnlupload">
<p:growl id="msg" showDetail="true" life="3000" showSummary="true"/>
<p:fileUpload auto="true"
allowTypes="/(\.|\/)(xls)$/"
sizeLimit="1024000"
mode="advanced"
multiple="true" invalidFileMessage="Invalid file type" invalidSizeMessage="File too
large" dragDropSupport="true"
fileUploadListener="#{excelFileController.handleFileUpload}" showButtons="true"
update="msg, tblcontacts" required="false"/>
<p:scrollPanel rendered="true" style="height:200px;">
<p:dataTable draggableColumns="false" editable="false" emptyMessage="No
Contacts Uploaded" id="tblcontacts" rendered="true" rows="8"
selection="#{excelFileController.contactsSelected}"
value="#{excelFileController.contactDataModel}" var="contact" style="width:50pc;">
<p:column selectionMode="multiple" style="width:18px" />
<p:column headerText="File Name">
#{contact.groupName}
</p:column>
<p:column headerText="Number of Contacts">
#{contact.numberofentries}
</p:column>
<p:column>
<h:button outcome="blkedit?faces-redirect=true" rendered="true" value="Edit">
<f:param name="contact" value="#{contact.contactId}"/>
</h:button>
</p:column>
</p:dataTable>
</p:scrollPanel>
<br />
</p:panel>
<h:commandButton value="Delete" id="btndelete"
action="#{excelFileController.removeContact}" type="button" immediate="true"
disabled="false" rendered="true"/>
<h:message for="btndelete" />
</h:form>
</div>
</ui:define>
The code for ExcelFileController is as follows:
#Named
#ViewAccessScoped
public class ExcelFileController implements Serializable, IFileController {
/**
*
*/
private static final long serialVersionUID = -8117258104485487921L;
#Inject
PhoneNumberFormatter formatter;
#Inject
#Authenticated
UserProfile profile;
public PhoneNumberFormatter getFormatter() {
return formatter;
}
public void setFormatter(PhoneNumberFormatter formatter) {
this.formatter = formatter;
}
#EJB
BulkContactDeleter deleter;
#Inject
Logger logger;
#Inject
#CurrentContext
FacesContext context;
#Inject
BulkSMSContactListProducer listProducer;
#Inject
ConfigurationListProducer producer;
private BulkSMSContacts[] contactsSelected;
private BulkContactDataModel contactDataModel;
public BulkSMSContacts[] getContactsSelected() {
return contactsSelected;
}
public void setContactsSelected(BulkSMSContacts[] contactsSelected) {
this.contactsSelected = contactsSelected;
}
public BulkContactDataModel getContactDataModel() {
return contactDataModel;
}
#PostConstruct
public void init() {
logger.log(Level.INFO, "Entering excel file controller");
contactDataModel = new BulkContactDataModel(
listProducer.getBulkSMSContacts());
}
/*
* (non-Javadoc)
*
* #see
* org.jboss.tools.examples.controller.IFileController#handleFileUpload(
* org.primefaces.event.FileUploadEvent)
*/
#Override
public void handleFileUpload(FileUploadEvent event) {
StringBuffer buffer = new StringBuffer();
// create a new file input stream with the input file specified
// at the command line
InputStream fin = null;
try {
fin = event.getFile().getInputstream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// create a new org.apache.poi.poifs.filesystem.Filesystem
POIFSFileSystem poifs = null;
try {
poifs = new POIFSFileSystem(fin);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HSSFWorkbook wb = null;
try {
wb = new HSSFWorkbook(poifs);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int numberofsheets = wb.getNumberOfSheets();
for (int i = 0; i < numberofsheets; i++) {
HSSFSheet sheet = wb.getSheetAt(i);
for (Row row : sheet) {
for (Cell cell : row) {
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING :
if (!cell.getStringCellValue().isEmpty())
buffer.append(formatter.formatPhoneNumber(cell
.getStringCellValue()));
buffer.append(producer.getConfiguration(
SettingsName.SMS_PHONENUMBERDELIMITER
.toString()).getValue());
break;
case Cell.CELL_TYPE_NUMERIC :
if (cell.getNumericCellValue() != 0) {
buffer.append(formatter
.formatPhoneNumber(String.valueOf(cell
.getNumericCellValue())));
buffer.append(producer.getConfiguration(
SettingsName.SMS_PHONENUMBERDELIMITER
.toString()).getValue());
break;
}
default :
break;
}
}
}
}
BulkSMSContacts contacts = new BulkSMSContacts();
contacts.setAccount(profile.getSmsAccount());
int number = formatter.splitPhoneNumbers(buffer.toString()).length;
contacts.setContacts(buffer.toString());
String filenameString = event.getFile().getFileName();
int index = filenameString.indexOf(".");
filenameString = filenameString.substring(0, index);
contacts.setGroupName(filenameString);
contacts.setNumberofentries(number);
try {
deleter.addContact(contacts);
List<BulkSMSContacts> temp = listProducer.getBulkSMSContacts();
contactDataModel.setWrappedData(temp);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,
"Success", number
+ " entries processed. Please refresh page to view"));
}
/*
* (non-Javadoc)
*
* #see org.jboss.tools.examples.controller.IFileController#removeContact()
*/
#Override
public String removeContact() {
int contactsdeleted = 0;
if (contactsSelected != null) {
for (BulkSMSContacts contacts : contactsSelected) {
if (contacts != null) {
deleter.deleteContact(contacts);
contactsdeleted += 1;
}
}
List<BulkSMSContacts> temp = listProducer.getBulkSMSContacts();
contactDataModel.setWrappedData(temp);
logger.log(Level.INFO, "Deleted " + contactsdeleted + " Contacts");
context.addMessage(null, new FacesMessage(
FacesMessage.SEVERITY_INFO, "Success", contactsdeleted
+ " entries where deleted successfully"));
} else {
context.addMessage(null, new FacesMessage(
FacesMessage.SEVERITY_ERROR, "Error",
"No contact file was selected!"));
}
return null;
}
}
All the methods work fine except for the last one "removeContact" where the CommandButton concerned does not even initiate a postback.
How is this caused and how can I solve it?
You need to remove type="button" from the <h:commandButton>. It should have been type="submit", which is the default already.
The type="button" makes it an <input type="button"> instead of <input type="submit"> which is only useful for client side handlers which you usually attach using onclick and so on.

jsf2 template component with parameter

I have a jsf template page. In this template i would like to use component with parameter. Actually i would like to iterate over collection. This collection should be determined by parameters from particular page. Parameter name is selectedMenu. How can i use this in my bean?
<div id="notes">
selectedMenu: #{selectedMenu}
<h:form>
<h:inputHidden value="#{notatkaController.searchForm.kategoria}">
<f:param value="#{selectedMenu}" />
</h:inputHidden>
<ui:repeat value="#{notatkaController.items}" var="item" varStatus="iter">
<f:param value="#{selectedMenu}" />
<p class="q-title"><strong><h:outputText value="#{item.ntaData}" /></strong></p>
<p class="answer"><h:outputText value="#{item.ntaDane}" escape="false" /></p>
</ui:repeat>
<span>Moje notatki</span>
<textarea>Tu wpisz treść swojej notatki</textarea>
<span>[+] dodaj notatkę</span>
</h:form>
</div>
My bean:
#ManagedBean(name = "notatkaController")
#ViewScoped
public class NotatkaController extends AbstractController<Notatka> implements Serializable {
#EJB
private pl.alfaprojekt.model.session.NotatkaFacade ejbFacade;
private NotatkaSearchForm searchForm;
public DataModel getItems() {
if (items == null)
items = getPagination().createPageDataModel();
return items;
}
public PaginationHelper getPagination() {
if (pagination == null) {
if (paginationSize == null)
paginationSize = 10;
pagination = new PaginationHelper(paginationSize) {
#Override
public int getItemsCount() {
return getFacade().countByParam(getSearchForm());
}
#Override
public DataModel createPageDataModel() {
if (rapId == null)
return new ListDataModel(getFacade().findRangeByParam(getSearchForm(), new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
else {
Long uzyId = SessionUtil.getUser().getUzyId();
return new ListDataModel(convertToRaportWierszList(getFacade().findRangeByParam(getSearchForm(), new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}), uzyId));
}
}
};
}
return pagination;
}
}
I am not sure I understood the question but the question I answer is this:
I want to dynamically display something. I want to tell it what to display when the page gets accessed.
View:
You could then use the following:
<f:event listener="#{myBean.myMethod}" type="preRenderView" />
Bean:
public void myMethod(ComponentSystemEvent event){
//your logic here
}
With parameter:
<f:metadata>
<f:event listener="#{myBean.myMethod}" type="preRenderView" id="fevent"/>
<f:attribute name="myParam" value="#{mySecondBean.param)" />
</f:metadata>
And
public void myMethod(ComponentSystemEvent event){
String id = (String) event.getComponent().getAttributes().get("myParam");
}

JSF 2 FacesConverter doesn't work with composite component

I've got simple composite component which has to render h:selectManyListbox with h:messages associated with it. The problem is with using faces converter class. It seems to be not working with it (only if used in component code).
Composite component code :
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<composite:interface>
<composite:attribute name="description" required="true" />
<composite:attribute name="fieldValue" required="true" />
<composite:attribute name="idc" required="true" />
<composite:attribute name="size" required="true" />
</composite:interface>
<!-- IMPLEMENTATION -->
<composite:implementation>
<tr>
<td nowrap="nowrap">
<h:outputText value="#{cc.attrs.description}" />
</td>
<td>
<h:selectManyListbox
id="#{cc.attrs.idc}"
size="#{cc.attrs.size}"
value="#{cc.attrs.fieldValue}">
<composite:insertChildren />
</h:selectManyListbox>
</td>
<td>
<h:message for="#{cc.attrs.idc}" />
</td>
</tr>
</composite:implementation>
</html>
When I use it on sample.xhtml page (as shown below), I get 'Validation Error: Value is not valid'.
.....
But when on the same page I put code like:
<tr>
<td><h:outputText value="Plugins" /></td>
<td>
<h:selectManyListbox
id="plugins"
value="#{bean.currentPlugins}"
size="6">
<f:selectItems value="#{bean.availablePlugins}" />
</h:selectManyListbox>
</td>
<td><h:message for="plugins" /></td>
</tr>
everything goes fine.
The managed bean 'bean' class is
#ManagedBean
#SessionScoped
public class Bean extends GenericManagedBean
implements Serializable {
ElementClass[] currentPlugins;
// getter & setter for currentPlugins
// ...
public List<ElementClass> getAvailablePlugins() {
// .. some code
return list;
}
}
and ElementClass is
public class ElementClass extends GenericEntity implements Serializable {
private static final long serialVersionUID = 9159873495276902436L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "ID")
private Integer id;
// other fields
// ...
// getters & setters
// ...
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
if (!(object instanceof ElementClass)) {
return false;
}
ElementClass other = (ElementClass) object;
if ((this.id == null && other.id != null)
|| (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
}
For the ElementClass I've got converter class
#FacesConverter(forClass = ElementClass.class)
public class ElementClassConverter implements Converter {
#Override
public Object getAsObject(FacesContext fc, UIComponent uiComponent,
String elemId) {
if (!StringUtils.isEmpty(elemId)) {
// this code gets ElementClass object entity from database
ApplicationBean applicationBean = JSFHelper
.findBean("applicationBean");
return applicationBean.getService()
.findElementClassById(
Integer.parseInt(elemId));
} else {
return null;
}
}
#Override
public String getAsString(FacesContext fc, UIComponent uiComponent,
Object elem) {
return elem != null ? ((ElementClass ) elem).getId()
.toString() : "";
}
}
And standard question: what am I doing wrong? I assume this is my lack of knowledge rather than jsf implemenation bug. I use JBoss 7.1.1 AS and everything, what is bundled with it + RichFaces 4.

Resources