Non-ajax method giving same result in ViewScoped managed bean - jsf

I have a dataTable like following
<p:dataTable value="#{userTable.tempLists}" var="user"
sortBy="#{user.userId}" sortOrder="descending"
paginator="true"
rows="10" paginatorPosition="bottom">
<p:column headerText="User ID" sortBy="#{user.userId}">
<p:commandLink ajax="false" value="#{user.userId}" action="#{userTable.showDetails(user.userId)}"/>
</p:column>
<p:column headerText="User Name" sortBy="#{user.userName}">
<h:outputText value="#{user.userName}">
</h:outputText>
</p:column>
</p:dataTable>
And I have a panel name as details like following
<p:panel>
<h:outputText value="#{userTable.userId}"/>
<h:outputText value="#{userTable.userName}"/>
</p:panel>
My UserTable managed bean is view scoped. Functionality is like when user will click on commandLink that it will my method will get details of user. After getting details dataTable will hide and panel will be shown. For user it almost seems like a different page.
Problem is here that when user will click any userId(commandLink) he will get details perfectly. Then he can use browser back button and try to get details by clicking another userId. But in this case user is getting same result as previous one. And nothing there in error log.
I found somewhere that in view scope managed bean this problem exist with non-ajax action method. But I need to keep it in viewscoped to maintain table state with sorting and pagination. So whenever user press back button I can show same screen before selection.
Please help. Thanks in advance.

The back button on a keyboard doens't really invoke a NEW HTTP request. Guessing this is what's going wrong. It's actually beter to use a list and details page. I've been struggling with the same error myself for some hours.
See: Difference between jsf actionListener(param) and propertyListener when using back button on keyboard

Related

Primefaces form is not updating from within dialog

I have a view like so:
<h:form id="productForm">
<p:messages
id="productFormMessages"
autoUpdate="true"
redisplay="true"
globalOnly="true" />
<p:panelGrid
id="detailsGrid">
<p:row>
...
<p:column>
...
<p:outputLabel
id="fieldToUpdateId"
value="XYZ" />
<p:commandButton
action="#{bean.prepareDialog}"
update="dialogFormId"
oncomplete="PF('dialogModal').show();" />
</p:column>
</p:row>
</p:panelGrid>
</h:form>
<ui:include src="/../.../dialog.xhtml" />
And this is what dialog.xhtml looks like:
<p:dialog
id="dialogId"
widgetvar="dialogModal"
appendTo="#(body)"
modal="true"
dynamic="true">
<h:form
id="dialogFormId">
...a selectOneMenu...
<p:commandButton
id="saveButtonId"
value="Save"
actionListener="#{bean.save}"
oncomplete="PF('dialogModal').hide();"
process="#form"
update=":productForm" />
</h:form>
But the save button just refuses to update the productForm. It does update productFormMessages (which I'm guessing is because of the autoUpdate) but the form just doesn't update. I need to do a page reload from the browser in order for it to reflect the latest data. I have tried many different ways of doing this.
1. Using p:component to directly refer to the outputLabel in the update attribute.
2. (1) also using the form ID and the panelGrid ID.
3. Using the full client ID (with and without the preceeding ':') in the update attribute. Similarly using the form ID and the panelGrid ID.
4. Adding the client ID to the render IDs in the bean and then calling the partialViewContext#update method on that.
4. Setting partialViewContext#setRenderAll to true.
4. And as a last ditch attempt, as demonstrated by the code, updating the entire productForm. Which isn't so bad, because fieldToUpdateId is just one of the fields that I need to update in the form. But either way, it's not working.
Clearly, the data is being saved on the back end, because a page reload gives me the latest data. But I just can't get the dialog to update the form where it's being called from. I'm out of ideas. What am I doing wrong?
Theoretically this should work, But please inspect the button in the Html source, to make sure which part of the html it refresh. it should have something like this.
onclick="PrimeFaces.ab({s:'dialogFormId:saveButtonId1',u:'productForm',onco:function(xhr,status,args){PF('dialogModal').hide();;}});return false;"

unselect the selected rows in a datatable

I'm working on a datatable with a single selection mode.My problem is that when I refesh the page , the same selected rows before refreshing stay refreshed.
Any idea on how unselecting all datatable rows in this case.
I appreciate helping me with this issue.
This is my datatable code:
<p:dataTable id="cars1" var="car" widgetVar="carsTable" value="#{typePrimeManager.tprimes}" editable="false" style="margin-bottom:20px" paginator="false" selectionMode="single" selection="#{typePrimeManager.selectedtype}" rowKey="#{car.idPrime}">
<p:ajax event="rowSelect" update=":form:cars2" />
<p:ajax event="rowUnselect" listener="#{typePrimeManager.setSelectedtype(null)}" update=":form:cars2"/>
<p:ajax event="rowUnselect" listener="#{typePrimeManager.setSelectedtype(null)}" update=":form:cars2"/>
<p:column headerText="intitule des types">
<h:outputText value="#{car.intitulePrime}" />
</p:column>
</p:dataTable>
You use a managed bean with SessionScoped ? This keep the value unchange. I Recommand to you to read this : How to choose the right bean scope?
If you want to keep using SessionScope and reset the selected rows you have to clean the selectedtype inside your bean
If you have to have a session scoped bean, you need to clear the value that DataTable holds to reference the selected item which in your case is typePrimeManager.selectedtype.
So if you set this value to null or any object of the same type that is not in the DataTable dataSource than your problem will resolved, but you have to do this before page is reloaded. To get that event you can use pre-defined JSF events ,like PreRenderView, to execute a method in which you should clear the selected value, or you can define a remoteCommand that will call the appropriate bean method and execute that remoteCommand with javascript when the page is loaded.

primefaces panelgrid update from datatable

I am getting "Cannot find component with identifier "contentForm:tabView:form:addressDialogPanel" referenced from "contentForm:tabView:form:addressBookTable" " error. How can I update my panelGrid inside the widget?
<h:form id="form">
<p:dataTable id="addressBookTable">
<p:ajax event="rowSelect" listener="#{addressBookController.onRowSelect}"
update="contentForm:tabView:form:addressDialogPanel" oncomplete="addressDialog.show()" />
</p:dataTable>
<p:dialog id="addressDialogId" widgetVar="addressDialog">
<h:panelGrid id="addressDialogPanel" columns="2" cellpadding="4">
</h:panelGrid>
</p:dialog>
</h:form>
The main problem is that you are giving the wrong client ID of component's. Also p:tabView is a component it is not a form. When you define a h:form, it generates a standart HTML form element. And when you submit the page JSF uses POST to submit your data into backing bean. So nesting them is going to occur lot's of issues that you don't expect. You should seperate forms into sections like sideForm or searchForm or etc.
You should detect the correct client ID of your component when you try to update it. You can do this with your browser's developer settings(press f12 for chrome). Then select component with the magnifier button and give that ID into update property. Just like here:
You should read to learn basics of JSF for example from here

p:commandButton with p:fileDownload and no ajax only works in second click

I'm using JSF 2.0, Primefaces 3.4.2, Spring 3.1.2.
I'm facing a similar problem of the guy of this link: h:commandButton works from the second click.
Like him I'm not using ajax in the <p:commandButton> but I'm using a <p:fileDownload /> inside the button tag.
I have two views: "list.xhtml" and "downloadView.xhtml". In myBean.java I send a DataModel from view "list.xhtml" to view "downloadView.xhtml" as a request attribute as shown in the code below:
FacesUtil.getServletContext().setAttribute("myDataModelFromRequest", this.myDataModel);
The bean is anotted with #Scope("view")
In view "downloadView.xhtml" I populated succesfully a dataTable with the DataModel sent from request. But the problem happens when I click in the button to download the file. It only works on second try.
I already tried to change the return of my method from null to "downloadView" but the problem was not solved.
In debug mode I noticed that only enter in the "downloadMethod()" on second click.
Anyone have an idea to solve it?
myBean.java
public String viewListMethod() {
//some work here...
FacesUtil.getServletContext().setAttribute("myDataModelFromRequest", this.myDataModel);
return "downloadView";
}
downloadView.xhtml
<h:form id="formId" prependId="false">
<p:dataTable
id="dataTableId" var="myVar" value="#{myDataModelFromRequest}"
selection="#{cargaProcessoControlador.myArray}"
paginator="true" rows="10" paginatorPosition="bottom" paginatorAlwaysVisible="false">
<f:facet name="header">
bla bla bla
</f:facet>
<p:column selectionMode="multiple" style="width:18px" />
//collumns here...
</p:dataTable>
<p:commandButton id="btDownload" ajax="false" value="Download" icon="ui-icon-document" >
<p:fileDownload value="#{myBean.downloadMethod()}" />
</p:commandButton>
</h:form>
The scope "view" on spring doesn´t exist... So you created your own, right? Just to check...
I had that kind of problem once, and I think it was something to do with validation... the
immediate=true attribute solved my problem.
This is something to do with the scope of the page. Your problem is due to partial rendering of page. Initially when you load the page it is not getting loaded fully and because of that the button is not part of that particular view when you try to click on the button for the first time. Try to make you view proper or explicitly render the page from the backing bean before displaying the page

Setting bean property before opening Primefaces dialog

I would like to achieve this functionality.
<p:column>
<p:commandLink value="prihlasit" oncomplete="dlg.show();"
action="#{signForProjectBean.setProjectForDetail(item)}" />
</p:column>
I think is pretty clear what I am trying to do, I would like to display detail of the row in dataTable on which user have clicked. So my approach is to set property of current row to bean and then show the detail in dialog. But it is not working and I am feeling that I am doing something really wrong:-)
If the dialog component is supposed to display the selected item, then you need to ajax-udpate the dialog's content before opening it. Otherwise it will still display the old content as it was when the page is rendered for the first time.
<p:commandLink value="prihlasit" update=":dlg" oncomplete="dlg.show();"
action="#{signForProjectBean.setProjectForDetail(item)}" />
...
<p:dialog id="dlg" ...>

Resources