how to properly refresh p:dataView component after EntityManager saves data - jpa

So, I've encountered this situation several times when I have a component that displays records, for instance, a list of shipping addresses in a p:dataView component (but it could be any other similar component).
Each row displays a shipping address and within each row, I have an edit and delete command buttons, as shown in next snippet:
<p:dataView id="dvBillingAddresses"
...
<p:commandButton icon="pi pi-pencil"
oncomplete="PF('editBillingAddressDlg').show()"
...
The edit command button would show following dialog:
<p:dialog header="Billing Address Details" showEffect="fade" modal="true"
widgetVar="editBillingAddressDlg" responsive="true" width="450">
...
<f:facet name="footer">
<p:commandButton value="Save" icon="pi pi-check" actionListener="#{bean.saveBillingAddress}"
...
So record would be saved by calling bean method and at the end of said method, I would call PrimeFaces.current().ajax().update("...dvBillingAddresses") to refresh the p:dataView component.
However, what always happens is that the component is refreshed before the data has been completely commited to datasource, causing component to refresh with old data.
What I usually end up doing is to use an ajax close event on the edit dialog to allow extra time to update data.
<p:dialog header="Billing Address Details" showEffect="fade" modal="true"
widgetVar="editBillingAddressDlg" responsive="true" width="450">
<p:ajax event="close" update="...dvBillingAddresses" immediate="true" global="false" />
...
When I have to update components after a confirmation, and since p:confirmDialog doesn't support ajax close events; I catch the click event on the confirmation button and programmatically click a dummy command button that in turn updates the component.
I know these can't be the right approach, as they feel a bit hackish, but so far this has allowed me to continue development.
Ideally, the component should wait to refresh until the entity's #PostLoad event is fired, even if a spinning refresh icon has to show.
I'm using PrimeFaces v11, eclipselink, mysql, jakartaee v8.0 on payara server.
How is everybody else handling this?
Thanks !!!

Try adding an update= attribute to your <p:commandButton/>, so the dataView will be updated after the bean.saveBillingAddress() action is performed.
<p:dialog header="Billing Address Details" showEffect="fade" modal="true"
widgetVar="editBillingAddressDlg" responsive="true" width="450">
<h:form id="editBillingAddressForm">
....
<f:facet name="footer">
<p:commandButton value="Save" icon="pi pi-check"
action="#{bean.saveBillingAddress}"
update="#form ...dvBillingAddresses"
oncomplete="if (!args.validationFailed) PF('editBillingAddressDlg').hide()"/>

Related

fluid template and TYPO3: Form inside a form - submit doesn't work anymore

If i insert a form inside a form, the submit button in the "outer" form doesn't work anymore.
Short code example:
<f:form action="update" name="examples" object="{examples}" >
<f:for each="{examples}" as="example"
<f:form.textfield property="name" value="" />
<f:form.checkbox property="checked" value="1" checked="0" /><br />
<f:form action="delete" name="example" object="{example}" >
<f:form.submit value="delete" />
</f:form>
<f:form.submit value="update" />
</f:form>
So basically (this is an extremely simplified version of my real life project) i want to be able to change the values of the textfield and checkbox which are then passed to the updateAction. The for each loop just generates multiple entries and therefore multiple forms just containing the delete button for that specific object so to speak. I can address these objects by __identity and they can be deleted by the button next to them, that's not the problem.
But the submit button for update doesn't work anymore if i put other forms with their respective submit buttons into this form.
Is there any solution for that?
Forms inside forms do not work (and is not proper HTML either).
Longer version that answers the question you didn't ask: to achieve your goal here, use f:link.action to create a link to the delete controller action with your {example} object as parameter. Then style that link to look like a button if you wish.
Completely unrelated from TYPO3 or Fluid you should know that nesting forms is not allowed.
However, at least the editing part of your code can be made valid with a single form:
<f:form action="update" name="examples" object="{examples}" >
<f:for each="{examples}" as="example" iteration="i">
<f:form.textfield property="{i}.name"/>
<f:form.checkbox property="{i}.checked" value="1"/>
</f:for>
<f:form.submit value="update"/>
</f:form>
With this set up it is not possible to also have a delete action in place since you'd need a submit button which does two things:
Request the delete action:
<f:form.button type="submit" name="action" value="delete">Delete</f:form.button>
Point at the entity to address:
<f:form.button type="submit" name="example" value="{example}">Do something with {example.title}</f:form.button>
You should add a separate view for editing single example objects instead. The current view then becomes a list with links to that edit view. In that view your form object becomes a single example which allows you to add two submit buttons for each action.

Primefaces submit form on p:tabView tab change

I have a huge JSF application created using primefaces version 6.0 running on WebSphere Application Server, Version 8.5.5. I want to avoid nested forms so my p:tabView is not included in a form but each tab has its own form. Source for my tab view looks something like this:
<p:tabView activeIndex="#{tabViewBean.selectedTab}" id="tabView" dynamic="true" cache="false" widgetVar="tabViewWidget">
<p:ajax event="tabChange" listener="#{tabViewBean.handleTabChange}" update=":tabView" />
<p:tab id="tab1" title="First tab">
<h:form id="FirstTabForm">
<ui:include src="/views/test/firstTabTab.xhtml"/>
</h:form>
</p:tab>
<p:tab id="tab2" title="Drugi tab">
<h:form id="SecondTabForm">
<ui:include src="/views/test/secondTab.xhtml"/>
</h:form>
</p:tab>
... more tabs ...
</p:tabView>
Is there a way I can submit the form inside current tab without clicking commandButton inside it. I would like to achieve that on tab change event.
Each tab has 15-20 input fields and I don't want to use ajax on each value change because it is slowing down my application significantly.
I think you can use processattribute with a dynamic selector on tabChange event.
You can see it in action here: Ajax Framework - Partial Process

How to call a backing bean method without using h:commandButton or h:commandLink

I have a JSF form with only one input and no submit button. The form is submitted when the user presses Enter. I would like to trigger a backing bean method on submit of that form. How can I achieve this?
<h:form>
<h:inputText value="#{searchBean.propertyName}" />
</h:form>
I don't think that what you are trying to achieve could be done without a submit type input component in the form. If you just don't like a button to be displayed you can hide it in the resulting xhtml page with style="display: none". The form still will be submitted when Enter is pressed and you will get a desired behavior.
<h:form>
<h:inputText value="#{searchBean.propertyName}"/>
<h:commandButton actionListener="#{searchBean.method()}" style="display: none"/>
</h:form>
You can attach a handler to the submit event of the form. If you give your form an ID (eg: "myForm"):
document.getElementById('myForm').addEventListener('submit', function () {
// do stuff
});
You came submit with ajax call-
<h:form>
<div class="search">
<span class="searchIcon icon-magnifier"></span>
<h:inputText value="#{searchBean.propertyName}" id="propertyName"
a:placeholder="" readonly="false"></h:inputText>
<f:ajax event="change" listener="{searchBean.beanMethod}"/>
</div>

JSF 2.2 Form Submit, reloading page = resubmit?

So i have a JSF Application. If i submit a form, it gets resubmitted when i refresh the page. and of course i don't want that.
Index.xhtml:
[...]
<h:form >
<h:outputText value="Form"/><br/>
<h:inputText label="first" value="#{example.newExample.firstWord}" autocomplete="off"></h:inputText>
<h:commandButton value="click" actionListener="#{example.NewExample()}">
</h:commandButton>
</h:form>
[...]
The method that gets runned:
public void NewExample(){
pfDB.InsertNewExample(NewExample);
NewExample.setFirstWord(null);
NewExample.setSecondWord(null);
}
So everytime i refresh index.xhtml after i submitted the form, NewExample() get runned.
It was indeed the resubmitting off the form that was the problem. But the browser(opera) didn't showed an alert.
I fixed it by adding
FacesContext.getCurrentInstance().getExternalContext().redirect("index.xhtml");
in my function

Why is my <rich:popupPanel> not working?

I have the following code:
<a4j:commandButton value="Adicionar BOM"
onclick="#{rich:component('addBomModal')}.show()">
<a4j:ajax event="click" immediate="true"
oncomplete="Richfaces.showModalPanel('addBomModal')"
render="addBomModal" />
</a4j:commandButton>
and
<h:form>
<rich:popupPanel id="popup" modal="true" resizeable="true"
onmaskclick="#{rich:component('popup')}.hide()">
// rest of popupPanel
</rich:popupPanel>
</h:form>
The page is rendered but nothing happens when I click the button.
How can this be solved?
Thanks in advance,
gtludwig
You have too many things going on. You first open the pop-up in onclick (button) and then open it again in oncomplete via older API (I'm not sure it was migrated to RichFaces 4). All you need is what you have in onclick, you don't need a4j:ajax.