rich:scrollableDataTable is not rerendering ok
josuemb Dec 2, 2008 2:15 PMWhen i change the table contents (using the "rerender" option from a commandButton) the table does not render well. The header is not showing its contents and the columns are bad formed.
The commandButton changes partially the information of one column and "refresh" the data.
The a4j:log component show:
debug[13:05:20,129]: Update part of page for Id: j_id24:tablaBienes:0:hcb_4 successful
debug[13:05:20,129]: Update page part from call parameter for ID j_id24:tablaBienes:0:hcb_5
debug[13:05:20,129]: call getElementById for id= j_id24:tablaBienes:0:hcb_5
debug[13:05:20,130]: Replace content of node by replaceChild()
debug[13:05:20,131]: search for elements by name 'script' in element div
debug[13:05:20,131]: Scripts in updated part count : 0
debug[13:05:20,132]: Update part of page for Id: j_id24:tablaBienes:0:hcb_5 successful
debug[13:05:20,132]: Update page part from call parameter for ID j_id24:tablaBienes:0:hcb_6
debug[13:05:20,132]: call getElementById for id= j_id24:tablaBienes:0:hcb_6
debug[13:05:20,133]: Replace content of node by replaceChild()
debug[13:05:20,134]: search for elements by name 'script' in element div
debug[13:05:20,134]: Scripts in updated part count : 0
debug[13:05:20,134]: Update part of page for Id: j_id24:tablaBienes:0:hcb_6 successful
debug[13:05:20,135]: Update page part from call parameter for ID j_id24:tablaBienes:0:hcb_7
debug[13:05:20,135]: call getElementById for id= j_id24:tablaBienes:0:hcb_7
debug[13:05:20,136]: Replace content of node by replaceChild()
debug[13:05:20,136]: search for elements by name 'script' in element div
debug[13:05:20,137]: Scripts in updated part count : 0
debug[13:05:20,137]: Update part of page for Id: j_id24:tablaBienes:0:hcb_7 successful
debug[13:05:20,137]: Update page part from call parameter for ID j_id24:tablaBienes:0:hcb_8
debug[13:05:20,138]: call getElementById for id= j_id24:tablaBienes:0:hcb_8
debug[13:05:20,139]: Replace content of node by replaceChild()
debug[13:05:20,139]: search for elements by name 'script' in element div
debug[13:05:20,140]: Scripts in updated part count : 0
debug[13:05:20,140]: Update part of page for Id: j_id24:tablaBienes:0:hcb_8 successful
debug[13:05:20,140]: Update page part from call parameter for ID j_id24:tablaBienes:0:hcb_9
debug[13:05:20,141]: call getElementById for id= j_id24:tablaBienes:0:hcb_9
debug[13:05:20,142]: Replace content of node by replaceChild()
debug[13:05:20,142]: search for elements by name 'script' in element div
debug[13:05:20,143]: Scripts in updated part count : 0
debug[13:05:20,143]: Update part of page for Id: j_id24:tablaBienes:0:hcb_9 successful
debug[13:05:20,143]: Update page part from call parameter for ID j_id24:tablaBienes:s
debug[13:05:20,143]: call getElementById for id= j_id24:tablaBienes:s
debug[13:05:20,144]: Replace content of node by replaceChild()
debug[13:05:20,145]: search for elements by name 'script' in element input
debug[13:05:20,145]: Scripts in updated part count : 0
debug[13:05:20,145]: call getElementById for id= org.ajax4jsf.oncomplete
debug[13:05:20,146]: Update part of page for Id: j_id24:tablaBienes:s successful
debug[13:05:20,146]: call getElementById for id= ajax-view-state
debug[13:05:20,146]: Hidden JSF state fields: [object HTMLSpanElement]
debug[13:05:20,147]: Namespace for hidden view-state input fields is undefined
debug[13:05:20,147]: search for elements by name 'input' in element span
debug[13:05:20,148]: Replace value for inputs: 19 by new values: 1
debug[13:05:20,149]: Input in response: javax.faces.ViewState
debug[13:05:20,150]: Found same input on page with type: hidden
debug[13:05:20,150]: Found same input on page with type: hidden
debug[13:05:20,151]: search for elements by name 'INPUT' in element span
debug[13:05:20,151]: Replace value for inputs: 19 by new values: 0
debug[13:05:20,151]: call getElementById for id= _ajax:data
debug[13:05:20,153]: call getElementById for id= _ajax:data
debug[13:05:20,153]: call getElementById for id= _A4J.AJAX.focus
debug[13:05:20,154]: No focus information in response
debug[13:05:20,387]: Evaluate script replaced area in document: //<![CDATA[ window.Richfaces_ScrollableGrid_j_id24_tablaBienes = new ClientUI.controls.grid.ScrollableGrid({'hideWhenScrolling':false,'rowsCount':0,'columnsCount':10,'ids':['valuador','lote','ubicación','comentarios','descripcion','unidad','candidad','fotos','mandato','numero'] ,'onSortAjaxUpdate':function(event){A4J.AJAX.Submit('_viewRoot','j_id24',event,{'oncomplete':function(request,event,data){window.Richfaces_ScrollableGrid_j_id24_tablaBienes.onSortComplete(request,event,data)},'similarityGroupingId':'j_id24:tablaBienes','parameters':{'j_id24:tablaBienes':'j_id24:tablaBienes','j_id24:tablaBienes:sortIndex':event.index,'j_id24:tablaBienes:sortOrder':event.order,'j_id24:tablaBienes:sortStartRow':event.startRow,'j_id24:tablaBienes:sortColumn':event.column} ,'actionUrl':'/carasa-lb-admin/richfaces/listarBienes.jsf'} ); return false;},'selectionInput':'j_id24:tablaBienes:s','selectedClass':'','normalizedId':'j_id24_tablaBienes','client_id':'j_id24:tablaBienes','activeClass':''} ); ; // ]]>
error[13:05:20,388]: . Error message: $(this.client_id + "_rows_input") is null
The code for my Facelet is:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
.alineacion-derecha {
text-align:right;
}
.alineacion-centrada {
text-align:center;
}
.scrolls{
width:300px;
height:200px;
overflow:auto;
}
<a4j:form name="frmListarBienes">
<h:inputHidden id="claveBienActual" value="#{consultarFotosBean.claveBienActual}" />
Seleccione la Subasta y presione el botón "Listar Bienes"
<h:outputLabel style="font-weight:bold;font-size:small">Subasta:</h:outputLabel>
<a4j:outputPanel id="subastaPanel" layout="block">
<h:selectOneMenu id="subasta" name="subasta"
value="#{listarBienesBean.cveSubastaSeleccionada}"
valueChangeListener="#{listarBienesBean.onChangeSubasta}">
<f:selectItems value="#{listarBienesBean.subastasAbiertas}" />
</h:selectOneMenu>
<rich:spacer width="20px"/>
<h:outputLabel style="font-weight:bold;font-size:small">Ubicación:</h:outputLabel>
<h:selectOneMenu id="localidad" name="localidad"
value="#{listarBienesBean.cveLocalidadSeleccionada}"
rendered="#{not empty listarBienesBean.cveSubastaSeleccionada}">
<f:selectItems value="#{listarBienesBean.localidadesPorSubasta}" />
</h:selectOneMenu>
<a4j:commandButton id="btnListarBienes" name="btnListarBienes"
action="#{listarBienesBean.listarBienes}"
value="Listar Bienes"
reRender="bienesPanel"
style="margin: 9px 0px 5px;" />
<rich:spacer width="20px"/>
<a4j:status>
<f:facet name="start">
<h:outputText style="font-weight:bold;font-size:small" value="Cargando..."/>
</f:facet>
</a4j:status>
</a4j:outputPanel>
<a4j:outputPanel id="bienesPanel">
Lista de Bienes
<a4j:outputPanel id="tablaBienesPanel">
<rich:scrollableDataTable id="tablaBienes"
rowKeyVar="rkv" frozenColCount="1" height="400px"
width="850px" columnClasses="col"
value="#{listarBienesBean.bienesPorSubasta}"
var="bien" sortMode="single"
binding="#{listarBienesBean.tabla}"
sortOrder="#{listarBienesBean.orden}"
selection="#{listarBienesBean.seleccion}"
first="0"
rows="0">
<rich:column id="numero" styleClass="alineacion-centrada" width="45px" >
<f:facet name="header"><h:outputText styleClass="headerText" value="Bien" /></f:facet>
<h:outputText value="#{bien[0]}" />
</rich:column>
<rich:column id="lote" styleClass="alineacion-centrada" width="35px" >
<f:facet name="header"><h:outputText styleClass="headerText" value="Lote" /></f:facet>
<h:outputText value="#{fn:length(fn:split(bien[1],'@'))>=3?fn:split(bien[1],'@')[2]:'No asignado'}" />
</rich:column>
<rich:column id="candidad" styleClass="alineacion-derecha" width="55px">
<f:facet name="header"><h:outputText styleClass="headerText" value="Cantidad" /></f:facet>
<h:outputText value="#{bien[2]}" />
</rich:column>
<rich:column id="descripcion" width="200px">
<f:facet name="header"><h:outputText styleClass="headerText" value="Descripción" /></f:facet>
<h:outputText value="#{bien[3]}" />
</rich:column>
<rich:column id="fotos" styleClass="alineacion-centrada" width="30px">
<f:facet name="header"><h:outputText styleClass="headerText" value="Fotos" /></f:facet>
<h:outputText value="#{bien[4]}" />
<a4j:commandLink action="#{consultarFotosBean.inicializarFotografias}" oncomplete="javascript:Richfaces.showModalPanel('mostrarFotos', {claveBienActual: #{empty bien[0]?'':bien[0]}});" reRender="mostrarFotos">
<a4j:actionparam name="claveBienActual" value="#{bien[0]}" assignTo="#{consultarFotosBean.claveBienActual}" />
<h:graphicImage height="16px" value="/images/ico_MostrarFotos.png"/>
</a4j:commandLink>
</rich:column>
<rich:column id="valuador" width="150px">
<f:facet name="header"><h:outputText styleClass="headerText" value="Valuador" /></f:facet>
<h:outputText value="#{(empty bien[5])?'No asignado':bien[5]}" />
</rich:column>
<rich:column id="mandato" width="70px">
<f:facet name="header"><h:outputText styleClass="headerText" value="Mandato" /></f:facet>
<h:outputText value="#{bien[6]}" />
</rich:column>
<rich:column id="ubicación" width="80px">
<f:facet name="header"><h:outputText styleClass="headerText" value="Ubicación" /></f:facet>
<h:outputText value="#{bien[7]}" />
</rich:column>
<rich:column id="unidad" width="50px">
<f:facet name="header"><h:outputText styleClass="headerText" value="Unidad" /></f:facet>
<h:outputText value="#{empty bien[8]?'No asignado':bien[8]}" />
</rich:column>
<rich:column id="comentarios" width="100px">
<f:facet name="header"><h:outputText styleClass="headerText" value="Comentarios" /></f:facet>
<h:outputText value="#{empty bien[9]?'No asignado':bien[9]}" />
</rich:column>
</rich:scrollableDataTable>
</a4j:outputPanel>
<h:outputLabel style="font-weight:bold;font-size:small">Seleccione el valuador:</h:outputLabel>
<rich:spacer width="20px"/>
<h:selectOneMenu id="valuador" value="#{listarBienesBean.idValuadorSeleccionado}">
<f:selectItems value="#{listarBienesBean.valuadores}" />
</h:selectOneMenu>
<rich:spacer width="20px"/>
<a4j:commandButton id="btnSeleccionarValuador"
action="#{listarBienesBean.asignarValuadorABienesSeleccionados}"
value="Asignar Valuador"
reRender="tablaBienesPanel"
style="margin: 9px 0px 5px;" />
</a4j:outputPanel>
</a4j:form>
<rich:modalPanel id="mostrarFotos" autosized="false" resizable="true"
keepVisualState="false" width="700" height="640">
<f:facet name="controls">
<h:panelGroup>
<h:graphicImage value="/images/close.png" style="cursor:pointer" id="hidelinkFotos"/>
<rich:componentControl for="mostrarFotos" attachTo="hidelinkFotos" operation="hide" event="onclick"/>
</h:panelGroup>
</f:facet>
<f:facet name="header">
<h:outputText value="FotografÃÂas para el bien: #{consultarFotosBean.claveBienActual}"/>
</f:facet>
<a4j:outputPanel id="fotosPanel" layout="block">
<a4j:form id="frmFotografiasSel">
<rich:dataGrid id="fotografiasBienSeleccionado" value="#{consultarFotosBean.fotosBienActual}" var="fotografia" first="0" columns="1" elements="1" width="200px">
<rich:panel bodyClass="pbody">
<f:facet name="header">
<h:outputText value="Archivo: #{fotografia[2]}"></h:outputText>
</f:facet>
<h:panelGrid columns="1">
<a4j:mediaOutput element="img" cacheable="false" session="true"
createContent="#{consultarFotosBean.crearFotografia}" value="#{fotografia[1]}" mimeType="image/jpeg" />
</h:panelGrid>
</rich:panel>
<f:facet name="footer">
<rich:datascroller boundaryControls="auto" fastControls="auto" />
</f:facet>
</rich:dataGrid>
<a4j:commandButton id="btnCerrarFotos"
onclick="javascript:Richfaces.hideModalPanel('mostrarFotos');"
value="Cerrar"
reRender="listaDeBienes"
style="margin: 9px 0px 5px;" />
</a4j:form>
</a4j:outputPanel>
</rich:modalPanel>
<a4j:log popup="false" level="ALL" style="width: 800px; height: 300px;"></a4j:log>
</ui:composition>
The code for my bean is:
@Controller(value = "listarBienesBean")
@Scope("session")
public class ListarBienesBean {
@Resource
private SubastaService subastaService;
@Resource
BienService bienService;
@Resource
UsuarioService usuarioService;
private String claveBienActual;
private Set llaves = new HashSet();
private Integer filaActual;
private SimpleSelection seleccion = new SimpleSelection();
private UIScrollableDataTable tabla;
private SortOrder orden = new SortOrder();
private int pagina;
private List subastasAbiertas = new ArrayList();
private List<Object[]> bienesSeleccionados = new ArrayList<Object[]>();
private List<Object[]> bienesPorSubasta = new ArrayList<Object[]>();
private String cveSubastaSeleccionada;
private List localidadesPorSubasta = new ArrayList();
private String cveLocalidadSeleccionada;
private List valuadores = new ArrayList();
private Integer idValuadorSeleccionado;
private List fotosBienActual = new ArrayList();
public ListarBienesBean() {
SortField[] fields = {new SortField("0", true)};
orden.setFields(fields);
}
/**
* @param subinfoService the subinfoService to set
*/
@Required
public void setSubastaService(SubastaService subinfoService) {
this.subastaService = subinfoService;
}
/**
* @param bienService the bienService to set
*/
@Required
public void setBienService(BienService bienService) {
this.bienService = bienService;
}
/**
* @param usuarioService the usuarioService to set
*/
@Required
public void setUsuarioService(UsuarioService usuarioService) {
this.usuarioService = usuarioService;
}
/**
* @return the cveSubastaSeleccionada
*/
public String getCveSubastaSeleccionada() {
return cveSubastaSeleccionada;
}
/**
* @param cveSubastaSeleccionada the cveSubastaSeleccionada to set
*/
public void setCveSubastaSeleccionada(String cveSubastaSeleccionada) {
this.cveSubastaSeleccionada = cveSubastaSeleccionada;
}
/**
* @return the cveLocalidadSeleccionada
*/
public String getCveLocalidadSeleccionada() {
return cveLocalidadSeleccionada;
}
/**
* @param cveLocalidadSeleccionada the cveLocalidadSeleccionada to set
*/
public void setCveLocalidadSeleccionada(String cveLocalidadSeleccionada) {
this.cveLocalidadSeleccionada = cveLocalidadSeleccionada;
}
/**
* @return the idValuadorSeleccionado
*/
public Integer getIdValuadorSeleccionado() {
return idValuadorSeleccionado;
}
/**
* @param idValuadorSeleccionado the idValuadorSeleccionado to set
*/
public void setIdValuadorSeleccionado(Integer idValuadorSeleccionado) {
this.idValuadorSeleccionado = idValuadorSeleccionado;
}
public List getSubastasAbiertas() {
synchronized (this) {
if (subastasAbiertas.isEmpty()) {
//Consulta las subastas no cerradas desde la base de datos.
final ArrayList<Object[]> subastasTemp =
ClassUtils.cast(subastaService.getSubastasNoCerradas());
//Agrega las subastas consultadas desde la base de datos al combo.
for (Object[] subastaTemp : subastasTemp) {
subastasAbiertas.add(
new SelectItem(subastaTemp[0],
(String)subastaTemp[1]));
}
if (!subastasAbiertas.isEmpty()) {
cveSubastaSeleccionada = (String) subastasAbiertas.get(0).getValue();
}
}
}
return subastasAbiertas;
}
public List getLocalidadesPorSubasta() {
synchronized (this) {
if (localidadesPorSubasta.isEmpty() &&
!cveSubastaSeleccionada.isEmpty()) {
//Consulta localidades de la subasta seleccionada.
final ArrayList localidadesTemp =
(ArrayList) subastaService.getLocalidadesPorSubasta(cveSubastaSeleccionada);
//Agrega las localidades consultadas desde la base de datos al combo.
for (String localidad : localidadesTemp) {
localidadesPorSubasta.add(
new SelectItem(localidad, localidad.trim()));
}
if (!localidadesPorSubasta.isEmpty()) {
cveLocalidadSeleccionada = (String) localidadesPorSubasta.get(0).getValue();
}
}
}
return localidadesPorSubasta;
}
public void onChangeSubasta(javax.faces.event.ValueChangeEvent event) {
localidadesPorSubasta.clear();
getLocalidadesPorSubasta();
}
public List<Object[]> getBienesPorSubasta() {
return bienesPorSubasta;
}
public List getValuadores() {
synchronized (this) {
if (valuadores.isEmpty()) {
//Consulta la lista de valuadores.
final List<Object[]> valuadoresTemp = ClassUtils.cast(usuarioService.getUsuariosByIdPerfil(Constantes.USUARIO_PERFIL_VALUADOR));
//Agrega los valuadores consultadas desde la base de datos a la lista.
for (Object[] valuador : valuadoresTemp) {
valuadores.add(
new SelectItem(valuador[0], (String)valuador[1]));
}
if (!valuadores.isEmpty()) {
idValuadorSeleccionado = (Integer) valuadores.get(0).getValue();
}
}
}
return valuadores;
}
/**
* Carga la subasta seleccionada.
* @return true en caso exitoso, false en caso contrario
* @throws HumanTechSolutionsWebException
*/
public String listarBienes() throws HumanTechSolutionsWebException {
synchronized (this) {
try {
bienesPorSubasta.clear();
//Consulta las subastas no cerradas desde la base de datos,
//tomando como parámetros la subasta y la localidad.
bienesPorSubasta = ClassUtils.cast(bienService.findBienesPorSubastayUbicacion(cveSubastaSeleccionada, cveLocalidadSeleccionada));
} catch (Exception e) {
throw new HumanTechSolutionsWebException("Error al ejecutar ListarBienesBean.listarBienes()", e);
}
}
return null;
}
public SimpleSelection getSeleccion() {
return seleccion;
}
public void setSeleccion(SimpleSelection seleccion) {
this.seleccion = seleccion;
}
public String consultarBienesSeleccionados() throws HumanTechSolutionsWebException {
try {
getBienesSeleccionados().clear();
if (getSeleccion().isSelectAll()) {
getBienesSeleccionados().addAll(bienesPorSubasta);
} else {
Iterator iterator = getSeleccion().getKeys();
while (iterator.hasNext()) {
Object key = iterator.next();
tabla.setRowKey(key);
if (tabla.isRowAvailable()) {
getBienesSeleccionados().add((Object[]) tabla.getRowData());
}
}
}
} catch (Exception e) {
throw new HumanTechSolutionsWebException("Error al ejecutar ListarBienesBean.consultarBienesSeleccionados()", e);
}
return null;
}
@Transactional(readOnly=false)
public String asignarValuadorABienesSeleccionados() throws HumanTechSolutionsWebException {
try {
Usuario valuador = (Usuario) usuarioService.findPersistentObjectByKey(Usuario.class, idValuadorSeleccionado);
EstadoBien estadoBienAsignado = (EstadoBien) usuarioService.findPersistentObjectByKey(EstadoBien.class, Constantes.ESTADO_BIEN__ASIGNADO);
//Consulta los bienes seleccionados.
consultarBienesSeleccionados();
//Recorre la lista de bienes seleccionados.
for( Object[] bienSel : getBienesSeleccionados() ) {
final Bien objBienSel = (Bien) bienService.findPersistentObjectByKey(Bien.class, (String)bienSel[0]);
objBienSel.setUsuario(valuador);
objBienSel.setEstadoBien(estadoBienAsignado);
objBienSel.setFechaUltMod(Calendar.getInstance().getTime());
bienService.updatePersistentObject(objBienSel);
}
listarBienes();
} catch (Exception e) {
throw new HumanTechSolutionsWebException("Error al ejecutar ListarBienesBean.asignarValuadorABienesSeleccionados()", e);
}
return null;
}
public List getFotosBienActual() {
return fotosBienActual;
}
public void setFotosBienActual(final List fotosBienActual) {
this.fotosBienActual = fotosBienActual;
}
public List<Object[]> getBienesSeleccionados() {
return bienesSeleccionados;
}
public void setBienesSeleccionados(final ArrayList<Object[]> bienesSeleccionados) {
this.bienesSeleccionados = bienesSeleccionados;
}
public boolean isHayBienesSeleccionados() {
return !bienesSeleccionados.isEmpty();
}
public UIScrollableDataTable getTabla() {
return tabla;
}
public void setTabla(UIScrollableDataTable tabla) {
this.tabla = tabla;
}
public int getPagina() {
return pagina;
}
public void setPagina(int pagina) {
this.pagina = pagina;
}
public SortOrder getOrden() {
return orden;
}
public void setOrden(SortOrder orden) {
this.orden = orden;
}
public String getClaveBienActual() {
return claveBienActual;
}
public void setClaveBienActual(String claveBienActual) {
this.claveBienActual = claveBienActual;
}
public Integer getFilaActual() {
return filaActual;
}
public void setFilaActual(Integer filaActual) {
this.filaActual = filaActual;
}
public Set getLlaves() {
return llaves;
}
public void setLlaves(Set llaves) {
this.llaves = llaves;
}
}