Primefaces Tabview resetting inputs - primefaces

I use primeface 3.5. I have a tabview and each tabview has got inputMasks with a form. I want to reset inputMask when i change the tab. I listen ontabchange event and reset value to="" but bean reset values but View doesn't reset.
<p:tabView id="tabViewOS" binding="#{docData.tabView}" dynamic="true" cache="true" rendered="#{userData.opRendered}">
<p:ajax event="tabChange" listener="#{docData.onTabChange}" immediate="true"/>
<p:tab id="tab1" title="AB">
<h:form id="ABForm">
<h:panelGrid id="abgrid" columns="3" cellpadding="5">
<h:outputText value="AB NO: " />
<p:inputMask value="#{docData.abNo}" mask="999-99999999"
id="ABinput" required="true"
</p:inputMask>
<p:message id="msgAB" for="ABinput" showDetail="true" autoUpdate="true" />
<h:outputText value="" />
<p:commandButton value="GETİR" style="float:right;" ajax="false"
action="#{docData.getDoc}" />
</h:panelGrid>
</h:form>
</p:tab>
public void onTabChange(TabChangeEvent event) {
this.activeTabIndex = tabView.getChildren().indexOf(event.getTab());
FacesContext.getCurrentInstance().renderResponse();
System.out.println(this.activeTabIndex);
this.abNo="";
documents.clear();
}

Try changing the way the event is called. Instead of immediate=true use process="#this".
Change this:
<p:ajax event="tabChange" listener="#{docData.onTabChange}" immediate="true"/>
To this:
<p:ajax event="tabChange" listener="#{docData.onTabChange}" process="#this" update="ABinput"/>

i guess as you said -dynamic="true" cache="false">- is solve my problem. Actually I tested program faulty, my problem has already solved. I think in my case cause of this situation cache=false as documentation said. Thank you.

Have a look at the primefaces documentation on p:tabView. On the one hand you have the property dynamic which specifies if the content of a tab is loaded with AJAX when you select some tag. On the other hand there is the property cache which specifies wheter or not the content of a tab is only dynamically loaded the first time you select a tab.
So regarding this informations setting dynamic="true" cache="false" on the p:tabView should do the trick for you.
Another interesting property for you would be activeIndex. As I see you are setting the index of the active tab manually on tab change. If you can submit tabview on tabchange and you have set activeIndex="#{docData.activeTabIndex}" the active tabindex is tracked automatically. Have a look at the documentation if this fits your requirements.

Related

Why JSF form maintain the validation styles even if has values on it?

I have a form (frmAddPax) to add some users data. This data could be submited manual or vía a barcode reader. When the button "Escanear" is pressed this one calls a dialog with another form (frmScan).
This form read some data from a barcode reader and this data is processed in the managed bean. The data creates an object that is used in the original form (frmAddPax).
The problem is all the form has the styling as there wasn't any data on it, all the mandatory fields have the required="true" attribute.
If I press the "Escanear" button again and scan the same data it shows the form just fine.
I think this could be because before the data is ready updated in the form the validation process happend, but as I have seen in some questions the action and actionListener events happend before the update process so I have no clue.
This is the code of the form:
<h:form id="frmAddPax"
rendered="#{MB.renderStatus.isRenderFormAddPax()}">
<p:panelGrid styleClass="no-border">
<p:row>
<p:column>
<h:outputText
value="#{label['manageVipLoungeEntrance.addPassenger.firstName']} />
</p:column>
<p:column>
<p:inputText required="true"
value="#{manageVipLoungeEntranceExtMB.passenger.firstName}"
style="text-transform: uppercase;" converter="upperCaseConverter">
<f:ajax event="blur" update="#this" render="#this" />
</p:inputText>
</p:column>
...
...
<!-- BOTON ESCANEAR AGREGAR PASAJERO -->
<p:column>
<p:commandButton inmediate="true"
value="#{label['manageVipLoungeEntrance.addPassenger.button.scan']}"
onclick="showLocalDate()" update=":frmScan"
actionListener="#{manageVipLoungeEntranceExtMB.clear}"
oncomplete="{wgvScan.show()}" />
</p:column>
<!-- BOTON ESCANEAR AGREGAR PASAJERO -->
</p:row>
</p:panelGrid>
This is the code for the call that made the "Escanear" button:
<p:commandButton inmediate="true"
value="#{label['manageVipLoungeEntrance.addPassenger.button.scan']}"
onclick="showLocalDate()" update=":frmScan"
actionListener="#{manageVipLoungeEntranceExtMB.clear}"
oncomplete="{wgvScan.show()}" />
And this is the code for the widtget that process the barcode read and updates the original form with the data processed.
<p:dialog widgetVar="wgvScan" modal="true" showEffect="fade"
closeOnEscape="true" resizable="false">
<h:form id="frmScan">
<p:graphicImage value="../resources/images/barCode.png"
rendered="#{manageVipLoungeEntranceExtMB.showTablePassenger!=true}" />
<p:inputText id="itbarcode"
rendered="#{manageVipLoungeEntranceExtMB.showTablePassenger!=true}"
value="#{manageVipLoungeEntranceExtMB.barCode}" onfocus="true"
autocomplete="off" styleClass="insertData"
style="background:#ffffff; position:absolute;left:-7000;" />
<p:commandButton id="cmdReadBarcode" style="display:none"
onclick="showLocalDate()"
actionListener="#{manageVipLoungeEntranceExtMB.readBarCode}"
update=":frmAddPax :growl">
</p:commandButton>
<p:defaultCommand target="cmdReadBarcode" />
...
</h:form>
[EDIT]
#alibttb answer get me to the solution.
I added a remoteCommand before the button that calls the dialog to listen the scanner.
<p:remoteCommand name="refreshForm" process=":frmAddPax" update=":frmAddPax" />
<p:commandButton
value="#{label['manageVipLoungeEntrance.addPassenger.button.scan']}"
onclick="showLocalDate()" process="#this" update=":frmScan"
actionListener="#{manageVipLoungeEntranceExtMB.clear}"
oncomplete="{wgvScan.show()}" />
</p:column>
And in the dialog with the form that process the barcode I added a onHide attribute calling the remoteCommand.
I change the enclouse of the dialog-form to form-dialog as was sugested.
<h:form id="frmScan">
<p:dialog widgetVar="wgvScan" modal="true" showEffect="fade"
closeOnEscape="true" resizable="false" onHide="refreshForm()">
What happens when you click the Escanear button is that you are processing the whole form, thus submitting all the fields with empty values, this will cause validation errors, your button is immediate so what happens is the following:
actionListener is immediate so it's called first and the managed bean is filled with data from a barcode scanner.
the form data is being validated and it's not valid so the inValid flag is set on all the inputs.
the response is created on the server containing an update for the form, showing the new values from the managed bean and the inValid state of the inputs from the validation process.
notice that the submitted data (empty values) is not applied to the model as it's not valid.
to fix this, just use partial processing feature on your button, and remove the immediate="true", it's just a bad design.
just replace immediate="true" with process="#this" in the Escanear button.
If you're not familiar with partial processing feature of JSF and primefaces you should give it a look.
if you really need to submit the form for validation after the scan is complete then you need to use a p:remoteCommand that submits the form after the actionListener is complete:
<p:remoteCommand name="validateForm" process="#form"/>
<p:commandButton value="#{label['manageVipLoungeEntrance.addPassenger.button.scan']}"
onclick="showLocalDate()" update=":frmScan" process="#this"
actionListener="#{manageVipLoungeEntranceExtMB.clear}"
oncomplete="{wgvScan.show()}" />
and in the other form frmScan do:
<h:form id="frmScan">
<p:dialog widgetVar="wgvScan" modal="true" showEffect="fade"
closeOnEscape="true" resizable="false" onHide="validateForm()">
....
....complete your code
the name of the p:remoteCommand becomes a javascript function that can be called back once the scan dialog is hidden.
Note bring up the dev console in your browser and watch the two requests one for updating the form and closing the dialog and the other one caused by p:remoteCommand to validate the form.
Note 1 (not related to your question) that I used the frmScan to enclose p:dialog this is the right way to do it, the form should surround the dialog not the other way around.

I try to show a dialog with an action from a menuitem but doesn't work

I try to show a dialog with an action from a menuitem but doesn't work
I have the follow menuitem:
<p:menuitem value="About" action="#{loginManagedBean.showAbout}" icon="icon-info-circled"/>
and in my managed bean I have:
public void showAbout(){
RequestContext.getCurrentInstance().execute("PF('dgAbout').show()");
}
but doesnt work
I use PrimeFaces 5
the dialog to show is:
<h:panelGrid>
<p:dialog widgetVar="dgAbout" header="About us"
hideEffect="fade"
showEffect="fade"
resizable="true"
modal="true">
<h:panelGrid>
<h:outputText value="INFO"/>
</h:panelGrid>
</p:dialog>
</h:panelGrid>
The code was right, the problem was a navigation rule established by a
colleague without inform to me.
Thanks for help
Sorry for the disadvantages

updating a dialog from TabView

I have encountered a problem with updating a dialog in a tabview ui:include page:
I have my page:
<p:tabView id="tabView" widgetVar="tabViewMain" >
<p:tab title="P1" >
<ui:include src="page1.xhtml"/>
</p:tab>
<p:tab title="p2">
<ui:include src="page2.xhtml"/>
</p:tab>
</p:tabView>
In page 2 I have a dataTable with:
the onDbClickByElement method try to do instruction and then show a dialog
<p:dialog closeOnEscape="true" id="editEtudeInListIdByElement"
header="Traitement de Lot #{infoGeneralesManagedBean.selectedElemetRadio.lot} selectionné" widgetVar="editEtudeInListByElement"
width="700" height="100%">
<h:form id="editEtudeInListformByElement">
</h:form>
</p:dialog>
The problem comes when i tried to update the dialog as follows:
<p:ajax event="rowDblselect" listener="#{infoGeneralesManagedBean.onDbClickByElement}"
update=":tabView:t:editEtudeInListIdByElement" />
Where i got this error :Cannot find component with expression
":tabView:t:editEtudeInListIdByElement" referenced from
"tabView:t:listInjection".
I always update my dialog like this and it's okay but now I don''t know what happens with the code!
Can I have any help how to correctly do the update of the dialog from a tabView
try
<p:ajax event="rowDblselect" listener="#{infoGeneralesManagedBean.onDbClickByElement}"
update=":tabView:editEtudeInListIdByElement" />
If it still fails, try to open your browser developer's tool and locate your "editEtudeInListIdByElement" element. You could try to use the id of that element. (:tabView:xxxx)

PrimeFaces: selectOneButton is cleared on validation error

I have a wizard tab and a few fields in it. Some of them are required.
There is also a selectOneButton. The problem is when I have some required fields empty and some value selected in selectOneButton - when the validation fails on form submit, it gets "unclicked", i.e. nothing is selected. I suspect that the whole form gets updated but other components still hold the visible value.
What am I doing wrong or maybe someone have had the same problem?
I use PrimeFaces-5.0.RC2
Here is the code:
<p:tab title="Service params" id="firstTab">
<h:panelGrid columns="2">
Name *
<p:inputText value="#{serviceMB.service.name}" label="Name" required="true" maxlength="150"/>
Unit
<p:selectOneButton value="#{serviceMB.service.unit}" converter="serviceUnitConverter"
filter="true" filterMatchMode="contains" label="Unit"
id="unitMenu"
required="true">
<f:selectItems value="#{serviceMB.allServiceUnits}" var="unit"
itemLabel="#{unit.name}"
itemValue="#{unit.code}"/>
<p:ajax event="change"
update=":addServiceForm:priceListPanel"
process="#this"/>
</p:selectOneButton>
</h:panelGrid>
<p:commandButton value="Next" icon="ui-icon-triangle-1-e" iconPos="right" type="button" onclick="PF('serviceWizard').next();"/>
So Unit is the component which value is cleared. I really have no idea why, so I moved to selectOneMenu instead which is less preferable in my case.

overlaypanel primefaces doesnt work fine inside dialog inside tabview

I use the dynamic overlayPanel of primefaces inside one p:tab inside one p:dialog like this :
<p:dialog id="dialog" modal="true" header="Nouveau Article"
widgetVar="dlg">
<h:form prependId="false" enctype="multipart/form-data">
<p:tabView id="monpanel">
<p:tab id="tab1" title="Informations">
....
</p:tab>
<p:tab id="tab2" title="Prix">
....
</p:tab>
<p:tab id="tab3" title="Stock et fournisseurs">
<h:outputLabel value="" /><h:outputLabel value="" /><h:outputLabel value="" />
<p:commandButton id="carBtn" value="Selectionner Fournisseurs" type="button" />
<p:overlayPanel appendToBody="true" my="left top" id="carPanel" for="carBtn" hideEffect="fade"
dynamic="true">
<p:dataTable id="table" var="car" rowKey="#{car.fournisseurId}"
value="#{articlesMB.listfournisseurs}" selection="#{articlesMB.selectedFournisseurs}"
rows="10" paginator="true" >
<p:column selectionMode="multiple" style="width:20px" />
<p:column headerText="Id">
<h:outputText value="#{car.fournisseurId}" />
</p:column>
<p:column headerText="Nom">
<h:outputText value="#{car.personne.nom}" />
</p:column>
</p:dataTable>
</p:overlayPanel>
</p:tab>
</p:tabView>
<p:commandButton id="article-ajouter"
update=":messages monpanel :articlesdata"
action="#{articlesMB.ajouter}" value="add" />
</h:form>
</p:dialog>
in the first time it works fine, but when I click on the add button and the validation failed (for any cause) and I click on dynamic button of overlaypanel, it appears but when I check or uncheck one of rows of datatable it disappear, I don't know the cause
do you have any idea how to resolve this problem
You cammandButton should use 'process' attribute, you specify component to submit info(not specify overlay).
For ex:
<p:inputText id="txttest" required="true" value="" />
<p:commandButton process="txttest" id="article-ajouter"
update=":messages monpanel :articlesdata"
action="#{articlesMB.ajouter}" value="add" />
The reason your overlay panel only works once is because you update the panel that holds the command button that overlayPanel is attached to.
It is a bug in overlayPanel emerged after PF 5. You can fix this without resorting process attribute, I think solutions like this reduces the readability of the code.
If you define a widgetVar to overlayPanel, say 'carPanelWDG', and call PF('carPanelWDG').loadContents() function in the onComplete event of the command button everything just works. And even if there is no comment explaining the reason why you did such a thing, anyone can interpret this easily.