0

I've got the following issue. I have a XHTML:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    template="../layout.xhtml">

    <ui:define name="header">
        <div id="header">
            Abfragen
        </div>
    </ui:define>

    <ui:define name="main">
        <p:toolbar>
            <p:toolbarGroup>
                <p:commandButton value="Neu" icon="pi pi-plus" actionListener="#{abfrageHandler.newAbfrage}"
                                 update="manage-queries-content" oncomplete="PF('manageQueriesDialog').show()"
                                 styleClass="ui-button-success" style="margin-right: .5rem">
                    <p:resetInput target=":ucmdbform:ucmdbtab:manage-ucmdb-queries-content"/>
                </p:commandButton>
            </p:toolbarGroup>
        </p:toolbar>
        
        <p:dataTable id="dt-queries" widgetVar="dtQueries" reflow="true" showGridlines="true" size="small"
                var="querie" value="#{abfrageHandler.abfragen}">
            <p:column headerText="Abfrage">
                <h:outputText value="#{querie.name}" />
            </p:column>
            <p:column headerText="TQL">
                <h:outputText value="#{querie.tql}" />
            </p:column>
            <p:column headerText="Zyklus">
                <h:outputText value="#{querie.zyklus}" />
            </p:column>
            <p:column headerText="Typ">
                <h:outputText value="#{querie.typ}" />
            </p:column>
            <p:column exportable="false">
                <p:commandButton icon="pi pi-pencil" update="manage-queries-content"
                        oncomplete="PF('manageQueriesDialog').show()"
                        styleClass="edit-button rounded-button ui-button-success" process="@this">
                    <f:setPropertyActionListener value="#{querie}" target="#{abfrageHandler.selected}"/>
                    <p:resetInput target="manage-queries-content"/>
                </p:commandButton>
                <p:commandButton icon="pi pi-search" actionListener="#{abfrageHandler.startAbfrage(querie)}"
                        styleClass="edit-button rounded-button ui-button-success" process="@this">
                </p:commandButton>
                <p:commandButton class="ui-button-warning rounded-button" icon="pi pi-trash" process="@this"
                        oncomplete="PF('deleteQuerieDialog').show()">
                    <f:setPropertyActionListener value="#{querie}" target="#{abfrageHandler.selected}"/>
                </p:commandButton>
            </p:column>
        </p:dataTable>
    
        <p:dialog header="Abfrage" showEffect="fade" modal="true" width="600px"
                    widgetVar="manageQueriesDialog" responsive="true">
            <p:outputPanel id="manage-queries-content" class="ui-fluid">
                <p:outputPanel rendered="#{not empty abfrageHandler.selected}">
                    <div class="p-field">
                        <p:outputLabel for="abfName">Name</p:outputLabel>
                        <p:inputText id="abfName" value="#{abfrageHandler.selected.name}" required="true"/>
                    </div>
                    <div class="p-field">
                        <p:outputLabel for="abfTql">TQL</p:outputLabel>
                        <p:inputText id="abfTql" value="#{abfrageHandler.selected.tql}" required="true"/>
                    </div>
                    <div class="p-field">
                        <p:outputLabel for="abfZyklus">Zyklus</p:outputLabel>
                        <p:inputText id="abfZyklus" value="#{abfrageHandler.selected.zyklus}" required="true"/>
                    </div>
                    <div class="p-field">
                        <p:outputLabel for="@next">Abfrageart</p:outputLabel>
                        <p:selectOneMenu id="abfTyp" value="#{abfrageHandler.selected.typ}" required="false">
                            <f:selectItem itemLabel="Eins wählen" itemValue=""/>
                            <f:selectItems value="#{abfrageHandler.requestResolutions}" var="reso"
                                itemLabel="#{reso.toString()}" itemValue="#{reso}"/>
                        </p:selectOneMenu>
                    </div>
                </p:outputPanel>
            </p:outputPanel>
    
            <f:facet name="footer">
                <p:commandButton value="Speichern" icon="pi pi-check" actionListener="#{abfrageHandler.saveAbfrage}"
                                update="manage-queries-content" process="manage-queries-content @this"/>
                <p:commandButton value="Abbruch" icon="pi pi-times" onclick="PF('manageQueriesDialog').hide()"
                                class="ui-button-secondary"/>
            </f:facet>
        </p:dialog>
    
        <p:confirmDialog widgetVar="deleteQuerieDialog" showEffect="fade" width="300"
                         message="TQL wirklich löschen?" header="Bestätigen" severity="warn">
            <p:commandButton value="Ja" icon="pi pi-check" actionListener="#{abfrageHandler.deleteParameter}"
                             process="@this" oncomplete="PF('deleteQuerieDialog').hide()"/>
            <p:commandButton value="Nein" type="button" styleClass="ui-button-secondary" icon="pi pi-times"
                             onclick="PF('deleteQuerieDialog').hide()"/>
        </p:confirmDialog>          
    
    </ui:define>
</ui:composition>

And the following bean in the backend:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.primefaces.PrimeFaces;

import main.java.ucmdbtool.RequestResolutions;
import main.java.ucmdbtool.UcmdbAbfrageInteface;
import main.java.ucmdbtool.table.Abfrage;
import main.java.ucmdbtool.table.UcmdbAbfTableHandler;

@SuppressWarnings("serial")
@Named("abfrageHandler")
@ViewScoped
public class AbfrageHandler implements Serializable {

    private List<Abfrage> abfragen = new ArrayList<>();
    private Abfrage selected;
    private RequestResolutions[] requestResolutions;
    
    @PostConstruct
    private void init() {
        abfragen = UcmdbAbfTableHandler.getAbfragen();
        requestResolutions = RequestResolutions.values();
    }

    public void newAbfrage() {
        selected = new Abfrage();
    }

    public void saveAbfrage() {
        if (selected.getPk() == null) {
            selected.setPk(UUID.randomUUID());
            UcmdbAbfTableHandler.insertAbfrage(selected);
            abfragen.add(selected);
        }
        else {
            UcmdbAbfTableHandler.updateAbfrage(selected);
        }
        PrimeFaces.current().executeScript("PF('manageQueriesDialog').hide()");
        PrimeFaces.current().ajax().update("dt-queries");
    }
    
    public void startAbfrage(Abfrage abf) {
        UcmdbAbfrageInteface.doRequest(abf);
    }
    
    public void deleteAbfrage() {
        if(selected != null) {
            UcmdbAbfTableHandler.deleteAbfrage(selected);
            abfragen.remove(selected);
        }
        PrimeFaces.current().ajax().update("dt-queries");
    }
    
    public List<Abfrage> getAbfragen() { return abfragen; }
    public Abfrage getSelected() { return selected; }
    public RequestResolutions[] getRequestResolutions() { return requestResolutions; }
    public void setSelected(Abfrage selected) { this.selected = selected; }

}

I've included all imports, because maybe one is off a false package. My problem is, if I click on new the dialog stays empty, because he thinks the object is empty. When I click on the edit button the object is loaded, but I can't save it because abfTyp is empty (it was required="true"), after I set required to false I could save, but my object had the old data and not the date I had changed. I have an almost similar page which is working fine and I can't find the difference. RequestResolutions is a stupid ENUM without any functions.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Check https://stackoverflow.com/questions/25339056/understanding-primefaces-process-update-and-jsf-fajax-execute-render-attributes – Jasper de Vries May 20 '21 at 11:45
  • .. and https://stackoverflow.com/questions/2118656/commandbutton-commandlink-ajax-action-listener-method-not-invoked-or-input-value – Jasper de Vries May 20 '21 at 11:55
  • Hi I had moved the page out of au tabbed view to an own view and I missed giving it an own . Thanks for the reminder, seen it in inspecting the page. – Daniel Becker May 21 '21 at 11:22

1 Answers1

1

The dialog is empty when using "neu" because you create a new version of "selected" each time. The old data is reappearing on "edit" because the previous time failed the validation, but you immediately close the dialog. Then you use p:resetInput which resets back to the stored value. If the selectList value is empty, it means that what's coming from the data source does not match any values in the Enum select list that you provide.

I had a number of issues getting the sample to work... missing form, update= having bad references. But I think the main design issue is that you're not displaying any validation errors in the dialog - just closing the dialog window immediately. And, by the way, you should mostly be using action= on command buttons, not actionListener=. See here to understand why. All field validation will have passed before the action method gets executed.

I suggest the following amendments:

    <p:commandButton value="Neu" icon="pi pi-plus" action="#{abfrageHandler.newAbfrage}"
                     update=":ucmdbform:manage-queries-content" 
                     oncomplete="PF('manageQueriesDialog').show()"
                     styleClass="ui-button-success" style="margin-right: .5rem">
<!--    <p:resetInput target=":ucmdbform:manage-queries-content"/> -->
    </p:commandButton>
    .
    .
    <p:commandButton value="Speichern" icon="pi pi-check" 
                     action="#{abfrageHandler.saveAbfrage}"
                     update=":ucmdbform:dt-queries :ucmdbform:manage-queries-content" 
                     oncomplete="if ( args.saved == 1 ) { PF('manageQueriesDialog').hide()};"/>

Plus all actionListeners="..." --> action="..."; plus add p:message to all dialog fields that could possibly fail validation.

    public void saveAbfrage() {
        if (selected.getPk() == null) {
            selected.setPk(UUID.randomUUID());
            UcmdbAbfTableHandler.insertAbfrage(selected);        
            abfragen.add(selected);
        } else {
            UcmdbAbfTableHandler.updateAbfrage(selected);
        }
        PrimeFaces.current().ajax().addCallbackParam("saved", 1);
//        PrimeFaces.current().ajax().update(":ucmdbform:dt-queries");
//        PrimeFaces.current().executeScript("PF('manageQueriesDialog').hide();");
    }
Brooksie
  • 361
  • 2
  • 5