I have two panels, an outer one "outer_lst_panel" and an inner one "inner_lst_panel". The inner one is embedded in the outer one. The problem is that I cannot remove an item from the inner panel. The button "Remove inner item" does not work. If I look in the generated code (see below) it seems to be a problem with the generation of a real id ("mojarra.ab(this,event,'action',0,'inner_lst_panel')"). If I hard code
<h:commandButton
value="Remove inner item"
action="#{bean.do_delete_inner_item(mas, mav)}">
<f:ajax render="aform:j_idt13:0:inner_lst_panel" /> <!-- Hard coded!!! -->
</h:commandButton>
it works. What's wrong?
JSF 2.3.2 from https://maven.java.net/content/repositories/releases/org/glassfish/javax.faces/2.3.2/javax.faces-2.3.2.jar
Bean:
@Named
@ViewScoped
public class Bean
...
<h:form id="aform">
<h:panelGroup id="outer_lst_panel">
<ui:repeat
var="mas"
value="#{bean.mas_lst}">Outer item
<h:panelGroup id="inner_lst_panel">
<ui:repeat
var="mav"
value="#{mas.mav_lst}">Inner item
<h:commandButton
value="Remove inner item"
action="#{bean.do_delete_inner_item(mas, mav)}">
<f:ajax render="inner_lst_panel" /> <!-- Not working!!! -->
</h:commandButton>
</ui:repeat>
<h:commandButton
value="Add inner item"
action="#{bean.do_add_inner_item(mas)}">
<f:ajax render="inner_lst_panel" />
</h:commandButton>
</h:panelGroup>
<h:commandButton
value="Remove outer item"
action="#{bean.do_delete_outer_item(mas)}">
<f:ajax render="aform:outer_lst_panel" />
</h:commandButton>
</ui:repeat>
</h:panelGroup>
<h:commandButton
value="Add outer item"
action="#{bean.do_add_outer_item()}">
<f:ajax render="aform:outer_lst_panel" />
</h:commandButton>
</h:form>
Generated code:
<form
id="aform"
name="aform"
method="post"
action="test.xhtml"
enctype="application/x-www-form-urlencoded">
<input
name="aform"
value="aform"
type="hidden"> <span id="aform:outer_lst_panel"> Outer item <span
id="aform:j_idt13:0:inner_lst_panel"> Inner item <input
id="aform:j_idt13:0:j_idt35:0:j_idt31"
name="aform:j_idt13:0:j_idt35:0:j_idt31"
value="Remove inner item"
onclick="mojarra.ab(this,event,'action',0,'inner_lst_panel');return false"
type="submit"><input
id="aform:j_idt13:0:j_idt42"
name="aform:j_idt13:0:j_idt42"
value="Add inner item"
onclick="mojarra.ab(this,event,'action',0,'aform:j_idt13:0:inner_lst_panel');return false"
type="submit"></span><input
id="aform:j_idt13:0:j_idt43"
name="aform:j_idt13:0:j_idt43"
value="Remove outer item"
onclick="mojarra.ab(this,event,'action',0,'aform:outer_lst_panel');return false"
type="submit"></span><input
id="aform:j_idt44"
name="aform:j_idt44"
value="Add outer item"
onclick="mojarra.ab(this,event,'action',0,'aform:outer_lst_panel');return false"
type="submit"><input
name="javax.faces.ViewState"
id="j_id1:javax.faces.ViewState:0"
value="-2796149469970124814:8174359678892564468"
autocomplete="off"
type="hidden">
</form>
Update: No, my question is not answered by How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
It's yet unclear for me why the render attribute from the ajax tag doesn't get a real reference for inner_lst_panel
with an continual counter. From my opinion it should be rendered to
onclick="mojarra.ab(this,event,'action',0,'aform:j_idt13:0:inner_lst_panel')
but it doesn't. It becomes
onclick="mojarra.ab(this,event,'action',0,'inner_lst_panel')
and that's wrong and doesn't work.
As a workaround (no, I cannot use render="@form"
for other reasons) I can use the following:
<h:form id="aform">
<h:panelGroup id="outer_lst_panel">
<h:panelGroup id="inner_lst_panel" binding="#{foo}">
...
<f:ajax render="#{foo.clientId}" />
...