Partial rendering will only work with @form?

I have a strange situation where using the @parent attribute or even explicit id-s does not work in the update attribute. But @form works fine.

I made a very simple test case that includes a simple grid, whose behavior is as follows:

  • Each entry inside the grid has a change button.
  • After clicking the β€œChange” button, it will change the server data, and the button will disappear, because it will only be displayed if the record has NOT been changed.

The change button looks like this:

<!-- this works, since it 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(user)}" /> </p:column> 

Note that the update attribute uses @form, which makes it work: when you click the change button, it is restored and disappears.

Substitute it with @this or @parent or the grid id, then it will NOT work. It is very logical for me to use the grid identifier in the update attribute, since I would like to update the grid after clicking on the button. I tried using rowIndexVar="rowIndex" and myGridId:#{rowIndex}:link , but still not 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:

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> 

I also tried the 3.0.M1 formats, but it also got the same behavior.

Share your ideas. Is this a mistake, or did I do something wrong?


UPDATE


Hello,

I just finished testing, but still fail.

Test 1 (using update=":gridRPBDetails" ):

JSF file:

 <p:commandLink id="undoLink" value="Undo" process="@this" action="#{tInputBean.actionUndoRemoveRecord(rpbDetail)}" update=":gridRPBDetails" rendered="#{tInputBean.isRemoveRecord(rpbDetail)}" title="Batalkan buang data" /> 

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 (using update=":gridRPBDetails:#{rowIndex}:undoLink" ):

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

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 do not work with the cancel button, cannot update the grid record or even the grid itself.


UPDATE


I 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 that I used :mainForm:tblUser , and I tried other options and still failed:

  • : MainForm: tblUser:
  • : tblUser (when I don't define the form name)
  • : MainForm: tblUser: # {RowIndex}: LinkId

But one thing that I notice is that I chose to update, the update always ends 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 only for tblUser , partial rendering on the grid works fine.

Im starting to think that this is a mistake when trying to update the grid from inside the grid record.


+4
source share
3 answers

This was answered in here .

Here is a quote from the answer:

This is more like a mojarra question, it should work fine with myface without a wrapper. A workaround is 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 latest update!

+4
source

Look at the generated HTML. Since <p:commandLink> is placed in <p:dataTable> , its generated client identifier looks something like this:

 <a id="someformid:tblUser:0:link"> 

0 is the index of the table row.

Therefore, when you use the relative identifier update="tblUser" on <p:commandLink> , it will basically look for someformid:tblUser:0:tblUser to update. But this does not exist. Instead, you want to use an absolute identifier starting with :

 <p:commandLink update=":someformid:tblUser"> 
0
source
 <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 an example of a link in a datatable displaying a dialog. maybe you can try changing

update = " : MainForm: dialog_content "

to

update = " : MainForm: main "

in this case, my tag form uses the main id form, as shown below:

Please note that I have not tried this. I just used in my example above to partially display the dialog box. Good luck.

Update: Well, I give it a try like this, combined with your updated message

  <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 background 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 worked! after I click the "Change" button, call the removeDetail method, follow some steps, update the changed status. then update = "mytable" and the link change will disappear.

I am using Mojarra 2.0.4 and primefaces 3.0.M2

FYI, I use a DataModel in a bean base, just a simple list so there is no rowIndexVar. Perhaps using a DataModel may cause a problem.

0
source

All Articles