Question

I am using Primefaces 3.5 with Weblogic 11. I have a page where a dialog to edit a 'profile' entity ('perfil' in Portuguese) which is called from two places. First from a commandButton to insert a new profile. The second from a dataTable to edit a specific profile. Below, I show the code:

Snippet of XHTML page

<p:fieldset legend="Pesquisa de Perfil">
    <p:panelGrid columns="2">
        <f:facet name="footer">
            <p:commandButton id="btnPesquisar"
                actionListener="#{perfilAcessoMB.pesquisar}" value="Pesquisar"
                immediate="true" update="pnlPerfis" styleClass="ui-icon-search" />
            <p:spacer width="20"></p:spacer>
            <!-- OPEN DIALOG TO CREATE A NEW PROFILE -->
            <p:commandButton id="btnIncluir" value="Incluir"
                update="dlgPerfil" immediate="true"
                actionListener="#{perfilAcessoMB.abrirDialogoEdicao(null)}"
                oncomplete="dlgPerfil.show();">
            </p:commandButton>
        </f:facet>
    </p:panelGrid>
</p:fieldset>

<br />

<p:outputPanel id="pnlPerfis" layout="block">
    <p:fieldset id="resultadoPesquisa" legend="Resultado da Pesquisa"
        rendered="#{not empty perfilAcessoMB.perfis}">
        <p:dataTable id="tblPerfis" value="#{perfilAcessoMB.perfis}"
            var="perfil" emptyMessage="Nenhum perfil encontrado.">
            <p:column headerText="Nome do Perfil">
                <h:outputText value="#{perfil.nome}"></h:outputText>
            </p:column>
            <p:column headerText="Descrição do Perfil">
                <h:outputText value="#{perfil.descricao}"></h:outputText>
            </p:column>
            <p:column headerText="Situação do Perfil"
                style="text-align: center; width: 100px;">
                <h:outputText value="Ativo" rendered="#{perfil.situacao}" />
                <h:outputText value="Inativo" rendered="#{not perfil.situacao}" />
            </p:column>
            <p:column headerText="Editar"
                style="text-align: center; width: 50px;">
                <!-- OPEN DIALOG TO EDIT A NEW PROFILE -->
                <p:commandLink id="lnkEditar" immediate="true"
                    title="Editar Perfil" update=":formPrincipal:dlgPerfil :formPrincipal:pnlPerfilEdicao"
                    actionListener="#{perfilAcessoMB.abrirDialogoEdicao(perfil)}"
                    oncomplete="dlgPerfil.show();">
                    <h:outputText value="Editar" />
                </p:commandLink>
            </p:column>
            <p:column headerText="Excluir"
                style="text-align: center; width: 50px;">
            </p:column>
        </p:dataTable>
    </p:fieldset>

</p:outputPanel>

<p:dialog id="dlgPerfil" widgetVar="dlgPerfil" resizable="false"
    closable="true" modal="true" closeOnEscape="true"
    header="#{(empty perfilAcessoMB.perfil)? 'Incluir': 'Editar'} Perfil">
    <h:outputText value="#{perfilAcessoMB.perfil}"></h:outputText>
    <h:panelGroup id="pnlPerfilEdicao" layout="block">
        <p:fieldset legend="Dados do Perfil">
            <p:panelGrid columns="2">
                <h:outputLabel id="lblNomePerfilEdicao" value="Nome do Perfil"
                    for="txtNomePerfilEdicao" />
                <p:inputText id="txtNomePerfilEdicao" required="true"
                    requiredMessage="É obrigatório preencher o campo Nome do Perfil."
                    value="#{perfilAcessoMB.perfil.nome}" maxlength="20" size="20"></p:inputText>

                <h:outputLabel id="lblDescricaoPerfilEdicao"
                    value="Descrição do Perfil" for="txtDescricaoPerfilEdicao" />
                <p:inputText id="txtDescricaoPerfilEdicao" required="true"
                    requiredMessage="É obrigatório preencher o campo Descrição do Perfil."
                    value="#{perfilAcessoMB.perfil.descricao}" maxlength="20"
                    size="20"></p:inputText>

                <h:outputLabel id="lblSituacaoPerfilEdicao" value="Situação"
                    for="selSituacaoPerfilEdicao" />
                <p:selectOneMenu id="selSituacaoPerfilEdicao"
                    value="#{perfilAcessoMB.perfil.situacao}">
                    <f:selectItems value="#{perfilAcessoMB.situacoesEdicao}" />
                </p:selectOneMenu>
            </p:panelGrid>
        </p:fieldset>
        <br />
        <p:fieldset legend="Permissões">
            <p:pickList id="pickFuncoes" value="#{perfilAcessoMB.funcoes}"
                var="funcao" itemValue="#{funcao}"
                itemLabel="#{funcao.descricao}" required="true"
                requiredMessage="É obrigatório associar ao menos uma funcionalidade ao perfil."
                converter="funcaoConverter" />
            <p:column>#{funcao.descricao}</p:column>
        </p:fieldset>
        <p:panelGrid columns="2">
            <p:commandButton id="btnSalvarPerfil" value="Salvar"
                actionListener="#{perfilAcessoMB.salvar}"
                oncomplete="if(args &amp;&amp; !args.validationFailed) dlgPerfil.hide();" />
            <p:commandButton id="btnCancelarPerfil" value="Cancelar"
                immediate="true" onclick="dlgPerfil.hide();" />
        </p:panelGrid>
    </h:panelGroup>
</p:dialog>

MangedBean (perfilAcessoMB)

@ManagedBean
@ViewScoped
public class PerfilAcessoMB extends BaseMB {

    private PerfilAcessoORM perfil;

    private List<PerfilAcessoORM> perfis;

    private String nomePerfil;

    private Boolean situacao;

    private DualListModel<FuncaoORM> funcoes;

    private SelectItem[] situacoesPesquisa = new SelectItem[] {
            new SelectItem(null, "Todos"), SELECT_ITEM_ATIVO,
            SELECT_ITEM_INATIVO };

    private SelectItem[] situacoesEdicao = new SelectItem[] {
            SELECT_ITEM_ATIVO, SELECT_ITEM_INATIVO };

    private FuncaoORM funcaoA = new FuncaoORM(1L, "FUNÇÃO A"), //
            funcaoB = new FuncaoORM(2L, "B Function"), //
            funcaoC = new FuncaoORM(10L, "Se Funssaum");

    public void abrirDialogoEdicao(PerfilAcessoORM p) {
        this.perfil = (p == null)? new PerfilAcessoORM(): p;
        System.out.println("PerfilAcessoMB.onAbrirDialogoEdicao(): "
                + this.perfil);

        List<FuncaoORM> funcoesDisponiveis = new ArrayList<FuncaoORM>(
                Arrays.asList(funcaoA, funcaoB, funcaoC));
        // Remove from funcoesDisponiveis those whose are present in perfil.
        if (this.perfil.getFuncoes() == null) {
            this.funcoes = new DualListModel<FuncaoORM>(funcoesDisponiveis,
                    Lists.<FuncaoORM> newArrayList());
        } else {
            funcoesDisponiveis.removeAll(this.perfil.getFuncoes());
            this.funcoes = new DualListModel<FuncaoORM>(funcoesDisponiveis,
                    this.perfil.getFuncoes());
        }
    }

    // Getters & Setters

}

PerfilAcessoORM (Profile) Entity

public class PerfilAcessoORM  {

    private Long id;

    private String nome;

    private String descricao;

    private Boolean situacao = null;

    private List<FuncaoORM> funcoes;

    // Getters & Setters

}

FuncaoORM Entity:

public class FuncaoORM {

    private Long id;

    public String descricao;

    // Getters & Setters

}

What is my problem? Apparently, when I want insert a new Profile, all seems OK. However, when I click to edit an existent profile to open the dialog, although the outputText and pickList are correctly filled, the inputText's and selectOneMenu are not.

Looking for solutions, I found here a suggestion to use appendToBody="true" in dialog. When I tried, the inputText's and selectOneMenu are correctly filled. However, the validation is not working as waited. When I click to save it is showed a message indicating that pickList is not filled, even if it is really filled. Actually, even if inputText's are not filled, there is no message about these inputTexts although they are required.

Another alternative would be use <f:setPropertyActionListener> inside commandLink:

<!-- OPEN DIALOG TO CREATE A NEW PROFILE -->
<p:commandButton id="btnIncluir" value="Incluir"
    update="dlgPerfil" immediate="true"
    actionListener="#{perfilAcessoMB.abrirDialogoEdicao}"
    oncomplete="dlgPerfil.show();">
    <f:setPropertyActionListener target="#{perfilAcessoMB.perfil}" value="#{null}"/>
</p:commandButton>


<!-- OPEN DIALOG TO EDIT A NEW PROFILE -->
<p:commandLink id="lnkEditar" immediate="true"
    title="Editar Perfil" update=":formPrincipal:dlgPerfil :formPrincipal:pnlPerfilEdicao"
    actionListener="#{perfilAcessoMB.abrirDialogoEdicao}"
    oncomplete="dlgPerfil.show();">
    <f:setPropertyActionListener target="#{perfilAcessoMB.perfil}" value="#{perfil}"/>
    <h:outputText value="Editar" />
</p:commandLink>

The actionListener method would changed to:

public void abrirDialogoEdicao() {
    if(this.perfil == null) {
        this.perfil = new PerfilAcessoORM();
    }
    System.out.println("PerfilAcessoMB.onAbrirDialogoEdicao(): "
            + this.perfil);
    // The rest remains the same ...
}

Now, when I click to create a new perfil, although in actionListener method the perfil attribute is filled, I got a NullPointerException when the dialog is renderized. It is like first is called perfilAcessoMB.setPerfil(), after the dialog is opened and finally actionListener method. On the other hand, if I click to edit an existent profile, I return to initial situation.

Therefore, I am lost, without idea how to solve this issue.

Thanks,

Rafael Afonso

Was it helpful?

Solution

The solution was incredible simple: just added process="@this" to both commandButtons.

<!-- OPEN DIALOG TO EDIT A NEW PROFILE -->
<p:commandLink id="lnkEditar" immediate="true"
    title="#{msg['titulo.edicao']}" process="@this"
    update=":formPrincipal:dlgPerfil"
    actionListener="#{perfilAcessoMB.abrirDialogoEdicao(perfil)}"
    oncomplete="dlgPerfil.show();">
    <h:outputText value="#{msg['titulo.edicao']}" />
</p:commandLink>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top