Partial Rendering will only work with @form?
I have a strange situation where using @parent, or even explicit id-s dont work in the update attribute. But @form works fine.
I've made a very simple test case, that includes a simple grid whose behaviour is like this :
- Every record inside the grid has a modify button
- After the modify button is clicked, it'll modify the server data, and the button will be gone, since it'll be only rendered if the record has NOT been modified.
The modify button is like this :
<!-- this works, since it's using @form in the update attribute -->
<p:column>
<p:commandLink
value="modify record"
process="@this"
action="#{testUserBean.modifyRecord(user)}"
update="@form"
rendered="#{not testUserBean.isRecordModified开发者_Python百科(user)}" />
</p:column>
Notice that the update attribute makes use of @form which makes it work: when the modify button is clicked, it rerenders and disappears.
Substitute it with @this or @parent or the id of the grid, then it will NOT work. For me it's very logical to use the id of the grid in the update attribute, since i would like to refresh the grid after clicking on the buttton.
I tried making use of rowIndexVar="rowIndex"
and myGridId:#{rowIndex}:link
, but still aint working.
<!-- this does not work -->
<p:column>
<p:commandLink id="link"
value="modify record"
process="@this"
action="#{testUserBean.modifyRecord(user)}"
update="tblUser"
rendered="#{not testUserBean.isRecordModified(user)}" />
</p:column>
Here are the resources for this simple example :
- The xhtml file
- The JSF Bean file
- The user POJO bean
Im using tomcat 7, and these are my dependencies :
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.0.4-b09</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.0.4-b09</version>
<scope>compile</scope>
</dependency>
Tried out primefaces 3.0.M1 also, but it got the same behavior also.
Please share your ideas. Is this a bug or i did something wrong ?
UPDATE
Hello,
I've just finished some testing, but all still fails.
Test 1 (making use of update=":gridRPBDetails"
) :
The JSF File :
<p:commandLink id="undoLink" value="Undo" process="@this"
action="#{tInputBean.actionUndoRemoveRecord(rpbDetail)}"
update=":gridRPBDetails"
rendered="#{tInputBean.isRemoveRecord(rpbDetail)}"
title="Batalkan buang data" />
The generated xhtml :
<a title="Batalkan buang data" onclick="PrimeFaces.ajax.AjaxRequest('/cashbank/faces/TInput.xhtml',
{formId:'j_idt38',async:false,global:true,source:'gridRPBDetails:0:undoLink',
process:'gridRPBDetails:0:undoLink',update:':gridRPBDetails'});"
href="javascript:void(0);" id="gridRPBDetails:0:undoLink">Undo</a>
Test 2 (making use of update=":gridRPBDetails:#{rowIndex}:undoLink"
) :
The JSF File :
<p:commandLink id="undoLink" value="Undo" process="@this"
action="#{tInputBean.actionUndoRemoveRecord(rpbDetail)}"
update=":gridRPBDetails:#{rowIndex}:undoLink"
rendered="#{tInputBean.isRemoveRecord(rpbDetail)}"
title="Batalkan buang data" />
The generated xhtml :
<a title="Batalkan buang data" onclick="PrimeFaces.ajax.AjaxRequest('/cashbank/faces/TInput.xhtml',
{formId:'j_idt38',async:false,global:true,source:'gridRPBDetails:0:undoLink',
process:'gridRPBDetails:0:undoLink',update:':gridRPBDetails:0:undoLink'});"
href="javascript:void(0);" id="gridRPBDetails:0:undoLink">Undo</a>
Both tests still fail in terms of clicking the undo button cannot refresh the record of the grid, or even the grid itself.
UPDATE
I've just updated my test using :
<p:commandLink
value="modify record"
process="@this"
action="#{testUserBean.modifyRecord(user)}"
update=":mainForm:tblUser"
rendered="#{not testUserBean.isRecordModified(user)}" />
Notice i used the :mainForm:tblUser
, and i've tried the other options and still failed :
- :mainForm:tblUser:
- :tblUser (when i dont define the form name)
- :mainForm:tblUser:#{rowIndex}:linkId
But 1 thing i notice is,nNo matter what i choosed for the update, the update always ends up as tblUser:0
<a onclick="PrimeFaces.ajax.AjaxRequest('/cashbank/faces/test.xhtml',
{formId:'mainForm',async:false,global:true,source:'tblUser:0:j_idt33',
process:'tblUser:0:j_idt33',
update:'tblUser:0'
});" href="javascript:void(0);" id="tblUser:0:j_idt33">modify record</a>
I tried modifying tblUser:0 on the fly using firebug to just tblUser, the partial rendering on the grid works fine.
Im beginning to think that this is a bug when trying to update a grid from inside a grid record.
This has been answered in here.
Here is the quote from the answer :
This is more like a mojarra issue, it should work fine with myfaces without a wrapper. Workaround is to put a wrapper.
Code:
<h:form id="frm">
<p:outputPanel id="wrapper">
<p:dataTable id="tbl">
//...
<p:commandButton update=":frm:wrapper" />
//...
<p:dataTable>
<p:outputPanel>
</h:form>
Sorry for the late update !
Look at the generated HTML. Since the <p:commandLink>
is placed in a <p:dataTable>
, its generated client ID is something like this
<a id="someformid:tblUser:0:link">
The 0
is the table row index.
So when you use the relative identifier update="tblUser"
on <p:commandLink>
, then it will basically search for someformid:tblUser:0:tblUser
to update. But this does not exist. You'd like to use an absolute identifier instead, starting with :
.
<p:commandLink update=":someformid:tblUser">
<p:dataTable id="mytable"
value="#{dataTableWithLinkBean.list}" var="item">
<p:column>
<f:facet name="header">
Code
</f:facet>
<p:commandLink actionListener="#{dataTableWithLinkBean.viewDetail}"
oncomplete="dlg.show()" process="@this"
update=":mainform:dialog_content">
<h:outputText value="#{item.code}"/>
<f:param name="code" value="#{item.code}"/>
</p:commandLink>
</p:column>
</p:dataTable>
<p:dialog widgetVar="dlg" modal="true" id="dialog"
width="300" height="300">
<h:panelGrid id="dialog_content">
<h:outputText value="#{dataTableWithLinkBean.selectedCode}"/>
</h:panelGrid>
</p:dialog>
Above is the example of link in the datatable that render the dialog. may be you can try to change
update=":mainform:dialog_content"
to
update=":mainform:mytable"
in this case my tag form is using id mainform, shown as below:
Please note that I've not been trying this. I just have used in my example above to rendering the dialog panel partially. Good luck
Update: Well I give it a try like this, combine with your updated post
<p:dataTable id="mytable"
value="#{dataTableWithLinkBean.list}" var="item">
<p:column>
<f:facet name="header">
Code
</f:facet>
<h:outputText value="#{item.code}"/>
</p:column>
<p:column>
<p:commandLink value="Modify"
action="#{dataTableWithLinkBean.removeDetail(item)}"
process="@this"
update="mytable"
rendered="#{not dataTableWithLinkBean.isModifier(item)}">
</p:commandLink>
</p:column>
</p:dataTable>
And in the backing bean
public String removeDetail(ClassForTest item){
for(ClassForTest o: list){
if(o.equals(item)){
//do something update to database
item.setModified(true);
break;
}
}
return "";
}
public boolean isModifier(ClassForTest item){
return item.isModified();
}
And it's worked! after I click on the modify button, call the removeDetail method, do some actions, update the modified status. then do update="mytable", and the link modify is gone.
I'm using Mojarra 2.0.4 and primefaces 3.0.M2
FYI, I'm using DataModel in the backing bean, just a simple List so no rowIndexVar. Maybe when using the DataModel, can produce this problem.
精彩评论