Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax render attribute don't work in a h:dataTable in JSF2

I have some problem's with a simple application in JSF 2.0.

I try to build a ToDo List with ajax support. I have some todo strings which I display using a datatable. Inside this datatable I have a commandLink to delete a task. The problem is now that the datatable don't get re-rendered.

    <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>

Thanks for your help.

Edit (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 */
}
like image 675
u2ix Avatar asked Mar 11 '10 12:03

u2ix


4 Answers

(Looks like I don't have enough reputation to comment on others' answers)

I think FRotthowe suggests wrapping the table with another element and referencing it using absolute reference (ie. naming all the parent containers from the root of the document) from the <f:ajax> tag.

Something like this:

<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>

But, using absolute references is always a source of problems and increases exponentially the refactoring time as the view grows.

Isn't there a way to just render the table from a <f:ajax> tag (prevent jsf from adding those annoying ":number_of_row" in the ajax event)?

like image 73
Toni Penya-Alba Avatar answered Nov 14 '22 22:11

Toni Penya-Alba


I assume that the <h:dataTable> is enclosed by a form?

After struggling with this issue for a while, I googled an easy and clean solution: add @form to render attribute of <f:ajax> and voila!

Full example:

<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>

The full article which helped me is here: http://blogs.steeplesoft.com/2009/10/jsf-2-hdatatable-and-ajax-updates/

like image 40
zarazek Avatar answered Nov 14 '22 23:11

zarazek


use this code:

<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>

like image 42
shahab kondri Avatar answered Nov 14 '22 21:11

shahab kondri


I ran into the same problem and figured that if you put an element (e.g. ) around the table and rerender that, it will work. I am however not quite sure why it is that way. Anyone?

like image 37
FRotthowe Avatar answered Nov 14 '22 21:11

FRotthowe