Eduardo José
Eduardo José

Reputation: 25

Primefaces duplicating elements in the DOM

Every time i click on a button or enter a dialog my overlayPanel is duplicated in the DOM, making it impossible, for example, to send a simple field to the backend. I spent a lot of time trying to see if it was something related to the p:commandbutton process/update, or even if it was some wrong lifetime tied to the controller, or even watching the discussions about here.

This is a part of my VIEW with my three overlayPanel below

<ui:define name="formActionAppend">
        <p:commandButton
            value="#{nfesBundle.btnTransmitNFe}"
            styleClass="GreenButton RaisedButton"
            icon="fa fa-send"
            rendered="#{nfesController.btnTransmitEnabled}"
            action="#{nfesController.doNFeTransmission()}"
            update="formDialog"
            process="@this formDialog"
            onsuccess="crudController.markAsChanged()" />
        <p:commandButton
            id="btnCancelNFe"
            styleClass="RedButton"
            value="#{nfesBundle.btnCancelNFe}"
            icon="fa fa-ban"
            type="button"
            rendered="#{nfesCancellationController.btnCancelEnabled}"
            update="@(.onCancelRequest)"
            process="@this" />
        <p:overlayPanel
            for="btnCancelNFe"
            at="left top"
            my="left bottom"
            appendToBody="true">
            <p:panel
                header="#{nfesBundle.cancellationPanelTitle}"
                rendered="#{nfesCancellationController.btnCancelEnabled}"
                styleClass="onCancelRequest">
                <sm:row>
                    <sm:cell
                        container="100"
                        responsive="100"
                        styleClass="floatLabel">
                        <p:outputLabel
                            for="justification"
                            value="#{nfesBundle.cancelationInputJustification}" />
                        <p:inputTextarea
                            id="justification"
                            maxlength="255"
                            required="true"
                            value="#{nfesCancellationController.justification}" />
                    </sm:cell>
                </sm:row>
                <div class="clearfix" />
                <f:facet name="footer">
                    <p:commandButton
                        id="btnDoNFeCancellation"
                        action="#{nfesCancellationController.doCancellation()}"
                        process="@parent"
                        update="formDialog"
                        value="#{nfesBundle.btnDoNFeCancellation}"
                        icon="fa fa-check"
                        onsuccess="crudController.markAsChanged()" />
                </f:facet>
            </p:panel>
        </p:overlayPanel>
        <p:commandButton
            id="btnGenerateCCe"
            value="#{nfesBundle.btnGenerateCCe}"
            styleClass="OrangeButton"
            icon="fa fa-pencil-square-o"
            type="button"
            rendered="#{nfesCCeController.btnGenerateCCeEnabled}"
            update="@(.onCCeRequest)"
            process="@this" />
        <p:overlayPanel
            for="btnGenerateCCe"
            at="left top"
            my="left bottom"
            appendToBody="true">
            <p:panel
                header="#{nfesBundle.ccePanelTitle}"
                rendered="#{nfesCCeController.btnGenerateCCeEnabled}"
                styleClass="onCCeRequest">
                <sm:row>
                    <sm:cell
                        container="100"
                        responsive="100"
                        styleClass="floatLabel">
                        <p:outputLabel
                            for="correction"
                            value="#{nfesBundle.cceInputCorrection}" />
                        <p:inputTextarea
                            id="correction"
                            maxlength="1000"
                            required="true"
                            value="#{nfesCCeController.correction}" />
                    </sm:cell>
                </sm:row>
                <div class="clearfix" />
                <f:facet name="footer">
                    <p:commandButton
                        id="btnDoGenerateCCe"
                        action="#{nfesCCeController.doGenerateCCe()}"
                        process="@parent"
                        update="formDialog"
                        value="#{nfesBundle.btnDoGenerateCCe}"
                        icon="fa fa-check"
                        onsuccess="crudController.markAsChanged()" />
                </f:facet>
            </p:panel>
        </p:overlayPanel>
        <p:button
            target="_blank"
            styleClass="BlueTextButton RaisedButton"
            value="#{nfesBundle.btnDownloadDanfePDF}"
            href="#{nfesController.getLinkDownloadDanfePDF()}"
            rendered="#{nfesController.btnDownloadDanfeEnabled}"
            icon="fa fa-file-pdf-o" />
        <p:button
            target="_blank"
            styleClass="BlueTextButton RaisedButton"
            value="#{nfesBundle.btnDownloadNFeXML}"
            href="#{nfesController.getLinkDownloadNFeXML()}"
            rendered="#{nfesController.btnDownloadNFeEnabled}"
            icon="fa fa-download" />
        <p:commandButton
            id="btnEmailNFe"
            value="#{nfesBundle.btnEmailNFe}"
            styleClass="RaisedButton GreenButton"
            icon="fa fa-envelope-o"
            type="button"
            rendered="#{nfesEmailController.entity.authorized}"
            update="@(.onEmailRequest)"
            process="@this" />
        <p:overlayPanel
            for="btnEmailNFe"
            at="left top"
            my="left bottom"
            appendToBody="true">
            <p:panel
                header="#{nfesBundle.emailPanelTitle}"
                rendered="#{nfesEmailController.entity.authorized}"
                style="width:500px;"
                styleClass="onEmailRequest">
                <sm:row>
                    <sm:cell
                        container="100"
                        responsive="100"
                        styleClass="floatLabel">
                        <p:outputLabel
                            for="email"
                            value="#{nfesBundle.emailAddress}" />
                        <p:inputTextarea
                            id="email"
                            required="true"
                            value="#{nfesEmailController.email}" />
                    </sm:cell>
                </sm:row>
                <div class="clearfix" />
                <f:facet name="footer">
                    <p:commandButton
                        id="btnEmailSend"
                        styleClass="GreenButton RaisedButton"
                        action="#{nfesEmailController.sendMail()}"
                        process="@parent"
                        update="formDialog"
                        value="#{nfesBundle.btnEmailSend}"
                        icon="fa fa-check" />
                </f:facet>
            </p:panel>
        </p:overlayPanel>
        <p:button
            value="#{nfesBundle.btnSaleView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFCeFromSale.present or nfesController.NFeFromSale.present}"
            icon="fa fa-share"
            outcome="sale">
            <f:param
                name="saleId"
                value="#{nfesController.entity.sale.id}" />
        </p:button>
        <p:button
            value="#{nfesBundle.btnStockPurchaseView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFeFromStockPurchase.present}"
            icon="fa fa-share"
            outcome="stockPurchase">
            <f:param
                name="stockPurchaseId"
                value="#{nfesController.entity.stockPurchase.id}" />
        </p:button>
        <p:button
            value="#{nfesBundle.btnStockTransferView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFeFromStockTransfer.present}"
            icon="fa fa-share"
            outcome="stockTransfer">
            <f:param
                name="stockTransferId"
                value="#{nfesController.entity.stockTransfer.id}" />
        </p:button>
        <p:button
            value="#{nfesBundle.btnVaccineApplicationsView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFCeFromVaccineApplication.present or nfesController.NFeFromVaccineApplication.present}"
            icon="fa fa-share"
            outcome="vaccineApplication">
            <f:param
                name="vaccineApplicationId"
                value="#{nfesController.entity.vaccineApplication.id}" />
        </p:button>
        <p:button
            value="#{nfesBundle.btnDevolutionView}"
            styleClass="RaisedButton BlueTextButton"
            rendered="#{nfesController.NFeFromDevolution.present}"
            icon="fa fa-share"
            outcome="devolution">
            <f:param
                name="devolutionId"
                value="#{nfesController.entity.devolution.id}" />
        </p:button>
    </ui:define>

This is one of the three controllers of the overlayPanels

package eprecise.sgv.server.fiscal.nfes;

import java.io.IOException;
import java.io.Serializable;
import java.util.Optional;

import javax.ejb.ConcurrentAccessTimeoutException;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.net.ssl.SSLHandshakeException;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import eprecise.sgv.server.core.infra.CacheOnRenderResponse;
import eprecise.sgv.server.core.util.FacesMessageUtil;
import eprecise.sgv.server.core.validation.HandleConstraintViolations;
import eprecise.sgv.server.fiscal.nfes.events.NFeCancelSyncUnauthorized;
import eprecise.sgv.server.fiscal.nfes.events.NFeCancellationEvent;
import eprecise.sgv.server.fiscal.nfes.transmission.NFeTransmissionChannel;


@Named
@RequestScoped
@HandleConstraintViolations
@CacheOnRenderResponse
public class NfesCancellationController implements Serializable {

    private static final long serialVersionUID = 1L;

    private @NotNull @Size(min = 15, max = 255) String justification;

    private final NfesController controller;

    private final NFeTransmissionChannel transmissionChannel;

    private final NFesRepository repository;

    public NfesCancellationController() {
        this.controller = null;
        this.transmissionChannel = null;
        this.repository = null;
    }

    @Inject
    public NfesCancellationController(final NfesController controller, final NFeTransmissionChannel transmissionChannel, final NFesRepository repository) {
        this.controller = controller;
        this.transmissionChannel = transmissionChannel;
        this.repository = repository;
    }

    public String getJustification() {
        return this.justification;
    }

    public void setJustification(final String justification) {
        this.justification = justification;
    }

    public void doCancellation() {
        this.controller.setEntity(this.repository.find(this.controller.getEntity()));
        if (this.isBtnCancelEnabled()) {
            try {
                this.controller.getEntity().cancel(this.transmissionChannel, this.justification);
                this.controller.getEntity().getLastEvent().ifPresent(e -> {
                    if (e instanceof NFeCancellationEvent) {
                        FacesMessageUtil.addInfoMessage("Cancelada com sucesso");
                    } else if (e instanceof NFeCancelSyncUnauthorized) {
                        final NFeCancelSyncUnauthorized unauthorized = (NFeCancelSyncUnauthorized) e;
                        FacesMessageUtil.addWarnMessage(String.format("Não cancelada por: %s", unauthorized.getDetails()));
                    } else {
                        FacesMessageUtil.addInfoMessage("Transmissão efetuada, veja mais detalhes no histórico");
                    }
                });
                this.repository.update(this.controller.getEntity());
            } catch (final ConcurrentAccessTimeoutException e) {
                FacesMessageUtil.addWarnMessage("Não foi possível transmitir, tente novamente em alguns instantes");
            } catch (final RuntimeException e) {
                if ((e.getCause() instanceof SSLHandshakeException) || (e.getCause() instanceof IOException)) {
                    FacesMessageUtil.addWarnMessage("Houve um erro de comunicação com a sefaz. Tente novamente em alguns instantes");
                } else {
                    throw e;
                }
            }
        } else {
            FacesMessageUtil.addErrorMessage("Não é possível cancelar a NFe");
        }
    }

    public boolean isBtnCancelEnabled() {
        return this.controller.isInViewMode() && Optional.ofNullable(this.controller.getEntity()).map(BaseNFe::isAllowedToCancel).orElse(false);
    }
}

Note: I tried to use dynamic = true in the overlayPanel, and the error is gone, however my css broke entirely.

Note²: I've been doing other tests and discovering that on some machines this code works, on others it doesn't. I tried to switch browsers and make the same requests, but nothing. I really don't know what else to do

I'm using Java 8 with Primefaces 7

Upvotes: 1

Views: 340

Answers (1)

Borja
Borja

Reputation: 3610

I don't see that I use it inside a form, please put the elements inside a form. The 'h' letter is because it is a jsf element.

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
    ...

    <h:form id="idForm">
    
     ...
    
    </h:form>

Also note this:

Version changes 6.2 -> 7.0

OverlayPanel: appendToBody has been removed. Use appendTo="@(body)" instead.

You can check more information here

Upvotes: 2

Related Questions