El atributo de renderizado Ajax no funciona en h:dataTable en JSF2
Pregunta
Tengo algunos problemas con una aplicación sencilla en JSF 2.0.
Intento crear una lista de tareas pendientes con soporte ajax.Tengo algunas cadenas de tareas pendientes que muestro usando una tabla de datos.Dentro de esta tabla de datos tengo un enlace de comando para eliminar una tarea.El problema ahora es que la tabla de datos no se vuelve a representar.
<h:dataTable id="todoList" value="#{todoController.todos}" var="todo">
<h:column>
<h:commandLink value="X" action="#{todoController.removeTodo(todo)}">
<f:ajax execute="@this" render="todoList" />
</h:commandLink>
</h:column>
<h:column>
<h:outputText value="#{todo}"/>
</h:column>
</h:dataTable>
Gracias por tu ayuda.
Editar (TodoController):
@ManagedBean
@SessionScoped
public class TodoController {
private String todoStr;
private ArrayList<String> todos;
public TodoController() {
todoStr="";
todos = new ArrayList<String>();
}
public void addTodo() {
todos.add(todoStr);
}
public void removeTodo(String deleteTodo) {
todos.remove(deleteTodo);
}
/* getter / setter */
}
Solución
(Parece que no tengo suficiente reputación para comentar las respuestas de otros)
Creo que FRotthowe sugiere envolver la tabla con otro elemento y hacer referencia a ella usando una referencia absoluta (es decir,nombrando todos los contenedores principales desde la raíz del documento) de la etiqueta <f:ajax>.
Algo como esto:
<h:form id="form">
<h:panelGroup id ="wrapper">
<h:dataTable value="#{backingBean.data}" var="list">
<h:column>
<h:commandButton value="-" action="#{backingBean.data}">
<f:ajax render=":form:wrapper"/>
</h:commandButton>
</h:column>
</h:dataTable>
</h:panelGroup>
</h:form>
Pero el uso de referencias absolutas siempre es una fuente de problemas y aumenta exponencialmente el tiempo de refactorización a medida que crece la vista.
¿No hay alguna manera de representar la tabla desde una etiqueta <f:ajax> (evitar que jsf agregue esos molestos ":number_of_row" en el evento ajax)?
Otros consejos
Asumo que el
Después de luchar con este problema por un tiempo, busqué en Google una solución fácil y limpia: añadir @form render atributo de la
Ejemplo completo:
<h:form id="theForm">
<h:dataTable id="table" value="#{tasksMgr.allTasks}" var="task">
<h:column>
#{task.name}
</h:column>
<h:column>
<h:commandButton id="removeTaskButton" value="X" action="#{tasksMgr.removeTask(task)}">
<f:ajax render="@form" />
</h:commandButton>
</h:column>
</h:dataTable>
</h:form>
El artículo completo lo que me ayudó está aquí: http://blogs.steeplesoft.com/2009/10/jsf-2-hdatatable-and-ajax-updates/
utilizar este código:
<h:form id="form">
<h:panelGroup id="panel">
<h:dataTable id="todoList" value="#{todoController.todos}" var="todo">
<h:column>
<h:commandLink value="X" action="#{todoController.removeTodo(todo)}">
<f:ajax render=":form:panel" />
</h:commandLink>
</h:column>
<h:column>
<h:outputText value="#{todo}"/>
</h:column>
</h:dataTable>
</h:panelGroup>
</h:form>
Me encontré con el mismo problema y pensé que si se pone un elemento (por ejemplo) en torno a la mesa y reRender que, para que funcione. Yo sin embargo, no estoy muy seguro de por qué es así. Cualquier persona?
Por alguna razón JSF está modificando el id en el
<h:form id="form">
<h:commandButton value="Button">
<f:ajax render="table"/>
</h:commandButton>
<h:dataTable id="table" value="#{tableData.data}">
<h:column>
<h:commandButton value="Button">
<f:ajax render="tocoto"/>
</h:commandButton>
</h:column>
</h:dataTable>
</h:form>
Me sale este html:
<form id="j_idt7" name="j_idt7" method="post" action="/WebApplication1/faces/index.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_idt7" value="j_idt7" />
<input id="j_idt7:j_idt8" type="submit" name="j_idt7:j_idt8" value="Button" onclick="mojarra.ab(this,event,'action',0,'j_idt7:table');return false" />
<table id="j_idt7:table"><tbody>
<tr>
<td><input id="j_idt7:table:0:j_idt10" type="submit" name="j_idt7:table:0:j_idt10" value="Button" onclick="mojarra.ab(this,event,'action',0,'j_idt7:table:0');return false" /></td>
</tr>
</tbody></table>
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="-7634557012794378167:1020265910811114103" autocomplete="off" />
</form>
Tenga en cuenta que el id en el segundo botón es 'j_idt7: tabla: 0' mientras estoy esperando recibir. 'J_idt7: mesa' como lo hago en el primero
Esto no resuelve el problema, pero puede ayudar a encontrar una solución.
Es necesario añadir prependId = "false" a su h: form
Tuve el mismo problema.
Una cosa que "funciona" es agregar caras ricas a su proyecto y reemplazando el
h:datatable
por un
rich:datatable.
Lo que generará las identificaciones correctas.