views:

1276

answers:

4

Hello everybody,

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 */
}
+1  A: 

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?

FRotthowe
If I put an element around the table I get an unknown id error
u2ix
u2ix show the code after you have added the wrapping element.
Bozho
+1  A: 

For some reason JSF is modifying the id in the <f:ajax> tag in the button. If I write this xhtml:

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

I get this 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>

Notice that the id in the second button is 'j_idt7:table:0' while I'm expecting to get 'j_idt7:table' as I do in the first one.

That doesn't solve the problem but may help to find a workaround.

Toni Penya
True, that j_idt7:table:0 actually refers to the first row in the dataTable. Not that it helps, just a note. I suppose you stripped the `h:form` element from your example code for this as the element is in the produced markup but not in your source code.
Tuukka Mustonen
Yes, the h:form tag got lost during the copy and paste. Fixed.
Toni Penya
A: 

You need to add prependId="false" to your h:form

that dosn't help sry
u2ix
+2  A: 

(Looks like I don't have enough reputation to comment on other's 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)?

Toni Penya
this works now thanks a lot
u2ix