Omit validation for p:selectOneMenu, for Ajax requests - jsf

I have a Jsf page with a fragment with <p:selectOneMenu/> (Prime faces) and an Ajax associated with it. It have the default select item "--- Select One ---" and others items that were created dynamically.
This field is required, so if users submit the form without select, the page show a error message.
The problem occurs when I select one of this others options and go back selecting "--- Select One ---" again. Then the page shows the required field message, even before I submit the form. I try different ways of immediate in <p:ajax> and <p:selectOneMenu> tags but none of them has the expected behavior.
The <p:messages> is declared as below:
-- list.xhtml
<p:messages id="messages" autoUpdate="true" closable="true" escape="false" />
<.... include fragment.xhtml ....>
And the fragment:
-- fragment.xhtml
<p:selectOneMenu id="selectTipoCarro"
value="#{carroBean.carro.tipoCarroEnum}"
required="true">
<f:selectItems value="#{carroBean.listaSelectItemTipoCarroInclusao}" />
<p:ajax update="outputInicioVigenciaWrapper outputLabelCalendarInicioVigenciaWrapper"
listener="#{carroBean.aoMudarTipoCarro}" />
</p:selectOneMenu>
<h:panelGroup id="outputLabelCalendarInicioVigenciaWrapper">
<h:outputLabel id="outputLabelCalendarInicioVigencia"
rendered="#{carroBean.edicaoDataInicioVigenciaDisponivel}"
for="calendarInicioVigencia">
<span>*
#{labels['carro.inicio.vigencia']}: </span>
<p:calendar id="calendarInicioVigencia"
value="#{carroBean.carro.dataInicioVigencia}"
showOn="button"
pattern="dd/MM/yyyy" mask="true"
required="true"/>
</h:outputLabel>
</h:panelGroup>
<h:panelGroup id="outputInicioVigenciaWrapper">
<h:outputLabel for="outputInicioVigencia"
rendered="#{not carroBean.edicaoDataInicioVigenciaDisponivel}">
<span aria-live="polite">
<h:outputText id="outputInicioVigencia"
value="#{carroBean.carro.dataInicioVigencia}"
styleClass="dataFormat"
</h:outputText>
</span>
</h:outputLabel>
</h:panelGroup>
private SelectItem obterSelectItemSelecione() {
SelectItem selectItem = new SelectItem("", "-- Select One --");
return selectItem;
}
private void preencherListaSelectItemTipoCarro(List<SelectItem> select, TipoCarroEnum[] tiposCarrosConsiderados) {
select.clear();
select.add(obterSelectItemSelecione());
for (TipoCarroEnum tipoCarro : tiposCarrosConsiderados) {
select.add(new SelectItem(tipoCarro, tipoCarro.getNome()));
}
}
public void aoMudarTipoCarro() {
getCarro().setDataInicioVigencia(carroService.obterProximaDataInicioVigenciaDisponivel(getCarro().getTipoCarroEnum()));
}

That's the expected behaviour. When adding a p:ajax tag to your p:selectOneMenu you make the value be processed everytime the user changes the input, so it will be validated and rejected if you mark it as required. My favourite workaround for this cases is to include a request param in the button to submit the whole form and check for it in the required attribute. That's it:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:comp="http://java.sun.com/jsf/composite/comp"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head />
<h:body>
<h:form>
<p:messages autoUpdate="true" />
<p:selectOneMenu value="#{val}"
required="#{param['validate']}">
<p:ajax event="change" />
<f:selectItem itemLabel="None" noSelectionOption="true" />
<f:selectItem itemLabel="val1" itemValue="val1" />
</p:selectOneMenu>
<p:commandButton value="Submit" ajax="false">
<f:param name="validate" value="true" />
</p:commandButton>
</h:form>
</h:body>
</html>
See also:
Conditionally skip JSF validation but perform model updates

Explanation
This happens because you have a p:messages component with autoUpdate set to true and you have attached p:ajax to your selectOneMenu so anytime your value changes, p:messages is updated. Therefore, due to the use of required="true" an error messages is shown as soon as you have selected "--- Select One ---".
Solution
Add ignoreAutoUpdate="true" to your p:ajax or
Remove autoUpdate="true" if not necessary

Related

pe:inputNumber value resetting to initial value inside p:tab

I have a <p:tabView> on my screen where one of the tabs(<p:tab>) has several <pe:inputNumber> with minValue attribute set to -9999999999.99. When I enter any value be it positive or negative and switch between the tabs, the input value resets to its initial value whereas for the inputs with no minValue set, it retains the entered value after switching between the tabs.
Is there attribute i am missing to set ? Or is there a workaround for the same?
Edit : I'm using primefaces 5.3 and primefaces-extensions 4.0.0. My code for tabs is as shown below :
<p:tabView id="sections" style="width:inherit;background-color: #F0F0F0;">
<p:ajax event="tabChange" listener="#{tabbedViewManagedBean.onTabChange}" />
<p:ajax event="tabClose" listener="#{tabbedViewManagedBean.onTabClose}" />
<p:tab title="First Tab" id="firsttab">
<ui:include src="firsttab.xhtml" />
</p:tab>
<p:tab title="Second Tab" id="secondtab">
<ui:include src="secondtab.xhtml" />
</p:tab>
</p:tabView>
The tabbed view managed bean gets data for that tab when switching between the tabs. Each tab has its own session scoped managed beans.
The code for secondtab.xhtml is :
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:p="http://primefaces.org/ui"
xmlns:pe="http://primefaces.org/ui/extensions">
<h:outputText value="Net Loss :" />
<pe:inputNumber value="#{secondTabMB.netLoss}"
symbol="$ " minValue="-99999999999999.99" />
</ui:composition>
Here's how my screen looks
This may be helps:
<pe:inputNumber value="#{secondTabMB.netLoss}"
symbol="$ " minValue="-99999999999999.99">
<p:ajax event="blur" global="false" />
</pe:inputNumber>
I tried to recreate your problem with this code, but the code below works as expected. I can switch tabs without losing values:
bean
#ManagedBean
#ViewScoped
public class Test {
private Double input1;
private Double input2;
//Getters & Setters
}
html
<h:form>
<p:tabView>
<p:tab title="Input1">
<h:outputText value="Net Loss :" />
<div class="form-element-wrapper">
<pe:inputNumber value="#{test.input1}" symbol="$ " >
<p:ajax process="#this"/>
</pe:inputNumber>
</div>
</p:tab>
<p:tab title="Input2">
<h:outputText value="Net Loss :" />
<div class="form-element-wrapper">
<pe:inputNumber value="#{test.input2}" symbol="$ " minValue="-99999999999999.99" >
<p:ajax process="#this"/>
</pe:inputNumber>
</div>
</p:tab>
</p:tabView>
</h:form>
I added process="#this" just for doing an ajax submit on losing focus.
Can u provide the following code from your ajax request?:
<p:ajax event="tabChange" listener="#{tabbedViewManagedBean.onTabChange}" />

Validator is called but error message is not displayed

when i click on the command button. validate method is getting called but the error message is not getting displayed..
here is my code..
<h:form id="form">
<h:body>
<p:panel style="width:500px">
<h:outputLabel for="year" value="Select Year: *" style="font-weight:bold" />
<p:selectOneMenu id="year" value="#{leaveBean.year}">
<f:selectItem itemLabel="Select One" itemValue="null" />
<f:selectItems value="#{leaveBean.yearDTO}" var="currentUser" itemValue="#{currentUser.name}" itemLabel="#{currentUser.name}" />
<f:validator validatorId="LeaveCardValidator" />
</p:selectOneMenu>
</p:panel>
<p:commandButton value="Submit" action="#{leaveController.leaveCard}" update="updateList,updateDetails" id="button"/>
<h:message for="year" style="color:red"/>
You seem to expect that JSF auto-updates the <h:message> on every ajax request. This is untrue. Perhaps you're confusing with PrimeFaces <p:messages> or <p:growl> which have each an autoUpdate attribute which enables you to tell them to auto-update themselves on every ajax request.
You really need to make sure that the <h:message> is covered by the ajax update. Just give it an ID
<h:message id="yearMessage" ... />
and include it in the client ID collection of the ajax update
<p:commandButton ... update="updateList updateDetails yearMessage" />
An alternative would be to replace <h:message> by <p:messages autoUpdate="true">.
Not sure where are the updateList and updateDetails are located but in the example give above you should use update="#form" instead or in addtion like this:
update="updateList updateDetails #form"
so that the form will be rendered again...
just use one of these :
update the whole form in order to update the content of
<h:message />
<p:commandButton value="Submit" action="#{leaveController.leaveCard}" update="#form" id="button"/>
or give the <h:message /> an id and id this id to the <p:commandButton/>
<h:message id="msg" for="year" style="color:red"/>
<p:commandButton value="Submit" action="#{leaveController.leaveCard}" update="updateList,updateDetails,msg" id="button"/>

Primefaces valueChangeListener or <p:ajax listener not firing for p:selectOneMenu [duplicate]

This question already has answers here:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
(12 answers)
Closed 7 years ago.
I am using Primefaces 3.4.2.
I have the following in my JSF page
<p:selectOneMenu id="emp" value="#{mymb.emp.employeeName}"
valueChangeListener="#{mymb.handleChange}"
required="true"
style="width: 150px;">
<f:selectItem noSelectionOption="true"
itemLabel="Please Select"/>
<f:selectItems value="#{mymb.employeeList}" var="emp"
itemLabel="#{emp.employeeName}"
itemValue="#{emp.employeeNumber}"/>
<p:ajax update="sublist"/>
</p:selectOneMenu>
and in ManagedBean
public void handleChange(ValueChangeEvent event){
System.out.println("here "+event.getNewValue());
}
The problem is valueChangeListener is not firing, i.e. handleChange method is not getting invoked. I tried with the following, but it is not working either.
<p:ajax update="sublist" listener="#{mymb.handleChange}" />
Separate JSF page:
<ui:composition template="/templates/layout.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="content">
<h:head>
</h:head>
<h:body>
<h:form id="form">
<p:panelGrid columns="6">
<h:outputLabel value="Employees" for="employees" />
<p:selectOneMenu id="employees"
value="#{mymb.employeesList}"
required="true">
<f:selectItems value="#{mymb.employeesList}" var="emp"
itemLabel="#{emp.employeeName}" />
<p:ajax listener="#{mymb.handleChange}" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</h:body>
</ui:define>
</ui:composition>
If you want to use valueChangeListener, you need to submit the form every time a new option is chosen. Something like this:
<p:selectOneMenu value="#{mymb.employee}" onchange="submit()"
valueChangeListener="#{mymb.handleChange}" >
<f:selectItems value="#{mymb.employeesList}" var="emp"
itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeID}" />
</p:selectOneMenu>
public void handleChange(ValueChangeEvent event){
System.out.println("New value: " + event.getNewValue());
}
Or else, if you want to use <p:ajax>, it should look like this:
<p:selectOneMenu value="#{mymb.employee}" >
<p:ajax listener="#{mymb.handleChange}" />
<f:selectItems value="#{mymb.employeesList}" var="emp"
itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeID}" />
</p:selectOneMenu>
private String employeeID;
public void handleChange(){
System.out.println("New value: " + employee);
}
One thing to note is that in your example code, I saw that the value attribute of your <p:selectOneMenu> is #{mymb.employeesList} which is the same as the value of <f:selectItems>. The value of your <p:selectOneMenu> should be similar to my examples above which point to a single employee, not a list of employees.
The valueChangeListener is only necessary, if you are interested in both the old and the new value.
If you are only interested in the new value, the use of <p:ajax> or <f:ajax> is the better choice.
There are several possible reasons, why the ajax call won't work. First you should change the method signature of the handler method: drop the parameter. Then you can access your managed bean variable directly:
public void handleChange(){
System.out.println("here "+ getEmp().getEmployeeName());
}
At the time, the listener is called, the new value is already set. (Note that I implicitly assume that the el expression mymb.emp.employeeName is correctly backed by the corresponding getter/setter methods.)
Another solution is to mix valueChangeListener, ajax and process:
<p:selectManyCheckbox id="employees" value="#{employees}" columns="1" layout="grid" valueChangeListener="#{mybean.fireSelection}" >
<f:selectItems var="employee" value="#{employeesSI}" />
<p:ajax event="valueChange" immediate="true" process="#this"/>
</p:selectManyCheckbox>
Method in mybean is just :
public void fireSelection(ValueChangeEvent event) {
log.debug("New: "+event.getNewValue()+", Old: "+event.getOldValue());
}
Like this, valueChangeEvent is very light !
PS: Works fine with PrimeFaces 5.0
<p:ajax listener="#{my.handleChange}" update="id of component that need to be rerender after change" process="#this" />
import javax.faces.component.UIOutput;
import javax.faces.event.AjaxBehaviorEvent;
public void handleChange(AjaxBehaviorEvent vce){
String name= (String) ((UIOutput) vce.getSource()).getValue();
}
All can be defined as in f:ajax attiributes.
i.e.
<p:selectOneMenu id="employees" value="#{mymb.employeesList}" required="true">
<f:selectItems value="#{mymb.employeesList}" var="emp" itemLabel="#{emp.employeeName}" />
<f:ajax event="valueChange" listener="#{mymb.handleChange}" execute="#this" render="#all" />
</p:selectOneMenu>
event: it can be normal DOM Events like click, or valueChange
execute: This is a space separated list of client ids of components that will participate in the "execute" portion of the Request Processing Lifecycle.
render: The clientIds of components that will participate in the "render" portion of the Request Processing Lifecycle. After action done, you can define which components should be refresh. Id, IdList or these keywords can be added: #this, #form, #all, #none.
You can reache the whole attribute list by following link:
http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/ajax.html
Try using p:ajax with event attribute,
My problem were that we were using spring securyty, and the previous page doesn't call the page using faces-redirect=true, then the page show a java warning, and the control doesn't fire the change event.
Solution:
The previous page must call the page using, faces-redirect=true
this works for me:
It can be used inside the dialog, but the dialog can´t be inside any componet such as panels, accordion, etc.

Creating a RichFaces popup panel as a Facelets subview/composition not hidable

Popup panels in RichFaces are pretty ugly to work with to be honest. There are several calls to some JavaScripts involved which makes it not easy to derive something that works in general. Anyway, I was trying the following:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<h:commandLink>
<h:graphicImage library="images/icons" name="#{buttonImageFileName}" />
<rich:tooltip value="#{buttonTooltipText}" direction="bottomRight" />
<rich:componentControl target="#{popupId}" operation="show" />
</h:commandLink>
<rich:popupPanel modal="true"
height="#{popupHeight}"
resizeable="#{popupResizable}"
onmaskclick="#{componentCallToId}.hide(); return false;"
id="#{popupId}">
<f:facet name="header">
<h:outputText value="#{popupHeaderText}" />
</f:facet>
<f:facet name="controls">
<h:outputLink value="#" onclick="#{componentCallToId}.hide(); return false;">
<h:outputText value="X" />
</h:outputLink>
</f:facet>
<p>#{popupSubject}</p>
<p>
<h:inputText value="#{inputTextBean[inputTextProperty]}" styleClass="full-width" id="#{inputTextId}" />
</p>
<h:panelGrid columns="2" style="margin: 0 auto;">
<h:commandButton value="OK"
action="#{acceptButtonBean[acceptButtonMethod](acceptButtonMethodArg)}"
onclick="#{componentCallToId}.hide(); return true;">
<a4j:ajax execute="#this #{inputTextId}" render="#form" />
</h:commandButton>
<h:commandButton value="Cancel" onclick="#{componentCallToId}.hide(); return false;" immediate="true" />
</h:panelGrid>
</rich:popupPanel>
</ui:composition>
This displays an image button which pops up a simple input dialog, which is supposed to be hidden by clicking outside the popup (onmaskclick="..."), by X'ing the popup in the top right corner (<f:facet> with onclick="..."), or by pressing the Cancel <h:commandButton onclick="...">. On OK the AJAX form is supposed to be submitted and the popup is hidden, too. But nothing happens (can't close):
The EL expression #{componentCallToId}.hide(); return false; is the "problem child" in the above. It is not working that way.
In its original, non-Facelets variant here (http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=popup&sample=modalPopup&skin=classic) the call to control the component looks like this:
<h:commandButton value="Cancel" onclick="#{rich:component('add-root-chapter-popup')}.hide(); return false;" immediate="true" />
I pass the following parameters to <ui:include>:
<ui:include src="/subviews/add-node-clink-input-popup.xhtml">
<ui:param name="buttonImageFileName" value="add.png" />
...
<ui:param name="popupId" value="add-root-chapter-popup" />
<ui:param name="componentControlCallToId" value="rich:component('add-root-chapter-popup')" />
...
</ui:include>
Notice the long entry (the rest seems to be working - even the strange syntax for the bean + method + arg, but this is not the focus here).
Q:
Why isn't <ui:param name="componentControlCallToId" value="rich:component('add-root-chapter-popup')" /> working? Currently nothing happens when clicking outside the popup, X'ing, or pressing OK or Cancel (popup staying).
Firebug only shows:
syntax error
.hide(); return false;
Looks like the expression is evaluated to null/empty string.
What's wrong? Can it be fixed? What are my alternatives?
PS: Note, that I've previously tried to use the "popupId" in the Facelets expression like
<h:commandButton value="Cancel" onclick="#{rich:component('popupId')}.hide(); return false;" immediate="true" />
but this has the same result.
Omitting the single quotes did the trick:
<h:commandButton value="Cancel" onclick="#{rich:component(popupId)}.hide(); return false;" immediate="true" />
I thought they were part of JS, but they seem to be EL here.
Also you could try this:-
onmaskclick="#{rich:component('cc.attrs.popupId')}.hide()"
If the quotes cause you any problem use " instead of them.
I believe here you are trying to parse the id to the popup panel dynamically through your custom components exposed variables.
Where in you might be parsing the value for id as
popupId="xyz"
If this being the situation the above solution would work just fine.

Primefaces dialog is rendering twice

I've created an ui:component to use like a popup, so I can create a lot of popups using the standard of this template.
The component is just a popup with two buttons (cancel and submit) and a content that can be overriden, like you can see here:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<ui:component>
<p:dialog widgetVar="#{idPopup}" id="#{idPopup}" modal="#{popup.modal}"
draggable="#{popup.modal}"
rendered="#{popup.visivel}" visible="#{popup.visivel}"
closeOnEscape="false" closable="false" header="#{titulo}"
resizable="false" styleClass="autoWidthDialog" showEffect="fade"
hideEffect="fade">
<h:panelGroup style="width:100%">
<p:focus />
<ui:insert name="conteudo">Nenhum conteúdo definido!</ui:insert>
<h:panelGrid id="#{idPopup}PainelMensagens" style="width:100%">
<p:messages />
</h:panelGrid>
<ui:insert name="barraDeBotoes">
<h:panelGroup layout="block" style="width:100%">
<p:commandButton value="CANCELAR" immediate="true" update="#form"
style="float:right" action="#{controladorPopup.fechar}"
onclick="#{idPopup}.hide();" />
<p:commandButton value="OK" style="float:right"
update="#form formAlerta"
action="#{controladorPopup.submit}"
process="#form" />
</h:panelGroup>
</ui:insert>
</h:panelGroup>
</p:dialog>
</ui:component>
</html>
The problem happen when I try to submit the form without filling the required fields. The correct behavior is just show again the popup with messages, but the dialog is rendered twice, one with the messages and one without the messages.
You can see this behavior here:
this is one use of this template:
<ui:composition template="../templates/popupSubmit.xhtml">
<ui:param name="titulo" value="Buscar pessoa" />
<ui:param name="popup" value="#{modeloPopupBuscaPessoa}" />
<ui:param name="controladorPopup"
value="#{controladorPopupBuscaPessoa}" />
<ui:define name="conteudo">
<h:panelGroup>
<h:panelGrid columns="2">
<h:outputLabel value="Tipo de cadastro:" style="float:none" />
<h:selectOneMenu value="#{controladorSugestaoPessoa.tipoCadastro}"
immediate="true">
<f:selectItems value="#{carregadorTipoCadastro.itens}" />
<f:ajax event="change" immediate="true" />
</h:selectOneMenu>
</h:panelGrid>
<h:outputText value="Buscar por:" />
<h:selectOneRadio value="#{controladorSugestaoPessoa.tipoBusca}"
immediate="true">
<f:selectItems value="#{carregadorTipoBuscaPessoa.itens}" />
<f:ajax event="change" immediate="true" />
</h:selectOneRadio>
<p:autoComplete value="#{modeloPopupBuscaPessoa.itemSelecionado}"
forceSelection="true" maxResults="10" queryDelay="500"
completeMethod="#{controladorSugestaoPessoa.atualizarSugestoes}"
var="pessoa" itemLabel="#{pessoa.label}" itemValue="#{pessoa}"
converter="#{conversorSelectItem}" />
</h:panelGroup>
</ui:define>
</ui:composition>
And these are some use:
<h:form id="cadastroPessoa">
<ui:include
src="resources/components/popups/modulo_cadastro/popupNovoCadastroPessoa.xhtml">
<ui:param name="idPopup" value="popupNovoCadastroPessoa" />
</ui:include>
<ui:include
src="resources/components/popups/modulo_cadastro/popupCadastroPessoa.xhtml">
<ui:param name="idPopup" value="popupEdicaoCadastroPessoa" />
</ui:include>
<ui:include
src="resources/components/popups/modulo_cadastro/popupBuscaPessoa.xhtml">
<ui:param name="idPopup" value="popupBuscaCadastroPessoa" />
</ui:include>
</h:form>
<h:form id="cadastroProduto">
<ui:include
src="resources/components/popups/modulo_cadastro/popupCadastroProduto.xhtml">
<ui:param name="idPopup" value="popupNovoCadastroProduto" />
</ui:include>
</h:form>
Could someone tell me why this is happening??
I've posted the same question in primefaces forum (like Tommy Chan told), and someone answered this:
You are probably placing your dialog in the form you are updating which is a nono. Never update the dialog only the stuff in the dialog
I've tried to do this until I saw all my dialogs have "rendered" attribute coming from server (just see the first xml), I have a lot of dialogs in this application and some of them have relation with others (on server), these last are on the same form.
I did something different, I only created this javascript code:
function removerDialogo(id) {
setTimeout(function() {
removerDialogoAposIntervalo(id);
}, 100);
}
function removerDialogoAposIntervalo(id) {
id = id.replace(':', '\\:');
jQuery('div.ui-dialog')
.find('#' + id)
.parent().eq(1)
.remove();
}
and called this on dialog "onShow" attribute:
<p:dialog widgetVar="#{idPopup}" id="#{idPopup}" modal="#{popup.modal}"
draggable="#{popup.modal}" rendered="#{popup.visivel}"
visible="#{popup.visivel}" closeOnEscape="false" closable="false"
header="#{titulo}" resizable="false" styleClass="autoWidthDialog"
showEffect="fade" hideEffect="fade" onShow="removerDialogo(this.id)">
I don't like to do things like this, but I can't find a better way to solve this...
If someone give me a better solution, I will be grateful
In my case I cannot user oncompleteI) method to hide the dialog because it has to be closed to some business logic.
I my case I have use primefaces tabs on UI. Every time I navigate the tabs and then click on button on which dialog appears then my dialogs number are increasing proportionality
So I have used simple jquery script to remove all the duplication dialog from the UI
e UI.
function removeDuplicateDialogs(dialogId) {
\\ generally all our components have : character we have to
\\ replace ':' with '\\:'(applying escape character)
dialogId = dialogId.replace(/\:/g, '\\:');
var dialogs = jQuery("div[id=" + dialogId + "]");
var numOfDialogs = dialogs.length;
numOfDialogs = numOfDialogs - 1;
for (var i = 0; i < numOfDialogs; i++) {
jQuery(dialogs[i]).remove();
}
}
As i said on the primefaces forum, you are updating your forms with the dialog in it... you need to place your dialogs out of your form and update them seperatly. If you need to use a form in your dialog then place it in you dialog:
<p:dialog><p:form> </p:form> </p:dialog>
I had the same problem with a dialog, the solution was place in the update of the commandButton that show the dialog component the specific id of the Dialog Component not the form id, the solution looks like this:
<p:dialog id="dialogId">
<p:commandButton value="OK" style="float:right"
update="#form dialogId"
action="#{controladorPopup.submit}"
process="#form"/>
</p:dialog>
I would check that your widgetVar="#{idPopup}" id="#{idPopup}" is the same before you submit and after you submit the form. Maybe it has changed and primefaces thinks it doesn't exist anymore and creates a new one.
Add the oncomplete attribute to your submit button and let it hide the dialog:
<p:commandButton value="OK" style="float:right"
update="#form formAlerta"
action="#{controladorPopup.submit}"
process="#form"
oncomplete="#{idPopup}.hide();"/>
putting the forms inside dialog isnt the best way to solve it, if you access your application with IExplorer, dialogs wont work with this approach
This is an awful bug with no official answer...
I'm using a dialog to render a Google map. The way I handle the bug (using JQuery) is by counting the number of ".map" elements in the DOM on primefaces:dialog.onShow... I then select the :last .map instance rendered (or in your case, whatever content class you're working with), and .remove() the dialog which contains it:
Markup (approx):
<pri:dialog onShow="popupOpen();" etc...>
<div id="map" class"map"></div>
</pri:dialog>
JavaScript:
function onShowDialog(){
if($(".map").length > 1){
$cull = $(".map:last");
$cull.closest(".ui-dialog").remove();
}
}
If you're a sadist you could, quite comfortably, make that a one liner... I see this as a Primefaces bug. The close button should outright destroy the dialog.

Resources