0

i have a Java EE setup with JSF and primefaces and i'm trying to generate a selection, based on the chosen entry in a <selectOneMenu>. My problem is that the selectManyCheckbox (or any other similar ui element) has all items filled in correctly and the items are selectable, but if a selection was made, the action of the commandButton doesn't get called. I've set a breakpoint on the method. If I don't choose any item, the breakpoint gets hit, if I choose any amount of items greater than zero, the breakpoint doesn't get hit.

I read that one solution could be to define a converter. I tried that and if I set a breakpoint, it correctly converts the items, I chose, but nevertheless the method, defined as action, doesn't get called.

Btw: Sorry for german code, i'm a german and naming the methods and variables in german was set by guideline

The xhtml File:

<h:form>
            <p:panelGrid columns="2">
            <p:outputLabel for="kennzeichenInput">Kennzeichen: </p:outputLabel>  
            <p:inputText id="kennzeichenInput"></p:inputText> 

            <p:outputLabel for="studiengang">Studiengang: </p:outputLabel>
            <p:selectOneMenu id="studiengang" value="#{registrationsController.gewaehlterStudiengang}">
                <f:selectItem itemValue="#{null}" itemLabel="--Studiengang aussuchen--"/>
                <f:selectItems value="#{registrationsController.getAlleStudiengaenge()}"/>
                <p:ajax value="valueChange" update="vorlesungenInStudiengang" listener="#{registrationsController.onStudiengangGeaendert}"/>
            </p:selectOneMenu>      
            </p:panelGrid>
            <h:selectManyCheckbox  id="vorlesungenInStudiengang" 
                value="#{registrationsController.gewaehlteVorlesungen}" 
                label="Vorlesungen" converter="de.phwt.parkhwt.domain.converter.vorlesung_converter">
                <f:selectItems value="#{registrationsController.vorlesungen}"/>
            </h:selectManyCheckbox > 
            <p:commandButton value="Registrieren" type="submit" action="#{registrationsController.registriereKennzeichen()}"/>
</h:form>

The Bean:

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.enterprise.context.RequestScoped;
import javax.faces.event.AjaxBehaviorEvent;
import javax.inject.Inject;
import javax.inject.Named;

import de.phwt.parkhwt.domain.CollectionKonverter;
import de.phwt.parkhwt.domain.KennzeichenRepository;
import de.phwt.parkhwt.domain.Studiengang;
import de.phwt.parkhwt.domain.Vorlesung;

@RequestScoped
@Named
public class RegistrationsController
{

    @Inject
    private KennzeichenRepository repository;

    private String gewaehlterStudiengang;

    private List<Vorlesung> vorlesungen;

    private List<Vorlesung> gewaehlteVorlesungen;

    public String getGewaehlterStudiengang()
    {
        return gewaehlterStudiengang;
    }

    public void setGewaehlterStudiengang(String gewaehlterStudiengang)
    {
        this.gewaehlterStudiengang = gewaehlterStudiengang;
    }

    public List<Vorlesung> getVorlesungen()
    {
        return vorlesungen;
    }

    public void setVorlesungen(List<Vorlesung> vorlesungen)
    {
        this.vorlesungen = vorlesungen;
    }

    public Vorlesung getVorlesung(String name)
    {
        return this.repository.sucheVorlesung(name);
    }

    public List<Vorlesung> getGewaehlteVorlesungen()
    {
        return gewaehlteVorlesungen;
    }

    public void setGewaehlteVorlesungen(List<Vorlesung> gewählteVorlesungen)
    {
        this.gewaehlteVorlesungen = gewählteVorlesungen;
    }

    public Set<Studiengang> getAlleStudiengaenge()
    {
        return repository.getAlleStudiengaenge();
    }

    public List<Vorlesung> getVorlesungenDesStudiengangs(String gewaehlterStudiengang)
    {
        Studiengang studiengang = repository.sucheStudiengang(gewaehlterStudiengang);
        return CollectionKonverter.toList(studiengang.getVorlesungen());
    }

    public String registriereKennzeichen()
    {
        return "";
    }

    public void onStudiengangGeaendert(AjaxBehaviorEvent event)
    {
        if (getGewaehlterStudiengang() != null)
        {
            setVorlesungen(getVorlesungenDesStudiengangs(getGewaehlterStudiengang()));
        }
        else
        {
            setVorlesungen(new ArrayList<Vorlesung>());
        }
    }
}

The Converter:

import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;

import de.phwt.parkhwt.controller.RegistrationsController;

@FacesConverter("de.phwt.parkhwt.domain.converter.vorlesung_converter")
public class VorlesungConverter implements Converter
{
    @Inject
    KennzeichenRepository repository;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value)
    {
        ValueExpression vex =
                context.getApplication()
                        .getExpressionFactory()
                        .createValueExpression(context.getELContext(),
                                "#{registrationsController}", RegistrationsController.class);
        RegistrationsController reg = (RegistrationsController) vex.getValue(context.getELContext());

        Vorlesung vorlesung = reg.getVorlesung(value);
        return vorlesung;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value)
    {
        if (value.getClass() == new Vorlesung().getClass())
        {
            Vorlesung v = (Vorlesung) value;
            return v.getName();
        }
        return null;
    }
}
Kukeltje
  • 11,924
  • 4
  • 19
  • 44
  • 1
    Check https://stackoverflow.com/questions/2118656/commandbutton-commandlink-ajax-action-listener-method-not-invoked-or-input-value especially #3 – Kukeltje Jun 04 '18 at 09:56
  • 1
    There are quite a few problems with your code, first doesn't have a value attribute, you probably meant event, but in your case it's fine do not define the event as the default event is the only event that can possibly be fired from a . – Mike Balthasar Jun 04 '18 at 15:04
  • 1
    Another problem is the which if ajax is not set to false only processes itself if the process attribute is not set to ids of components you want to be processed (setters called). (vorlesungenInStudiengang for example, which has no and will not be processed if the user changes his selection). Also a ViewScoped Bean seams more appropriat in your case. – Mike Balthasar Jun 04 '18 at 15:04
  • @Kukeltje thanks for you tip, i didn't find this in my google research ! – Frederic Reisenhauer Jun 04 '18 at 15:47
  • @MikeBalthasar i will try to adopt your changes and if they were helpfull, i will mark it as resolved with your answer, if not i will just edit the post and try to study the very long answer in the link of Kuketje – Frederic Reisenhauer Jun 04 '18 at 15:49
  • The long 'answer' in combination with https://stackoverflow.com/questions/25339056/understanding-primefaces-process-update-and-jsf-fajax-execute-render-attributes are (almost) the two most important Q/A in stackoverflow for JSF – Kukeltje Jun 04 '18 at 18:06
  • And why do you use the valueexpression in the converter? You load the managed bean in there (why not inject it???). – Kukeltje Jun 04 '18 at 18:08

1 Answers1

0

Thanks to Mike Balthasar for his comment!

The solution was to add ajax="false" to my commandButton. For more information, see his comment.

  • 1
    @MikeBaltasar did not say to set ajax to false, he said: _"which if ajax is not set to false only processes itself if the process attribute is not set to ids of components you want to be processed (setters called)"_. Setting ajax to false is at most a (not too good) way to get it working. You'll be unable to use any ajax features and run into new problems if you'd want too. Setting the process attribute is a 'better' solution. Please read https://stackoverflow.com/questions/25339056/understanding-primefaces-process-update-and-jsf-fajax-execute-render-attributes (and the link I posted before!) – Kukeltje Jun 04 '18 at 18:05
  • 1
    Indeed as @Kukeltje said it's a better solution to set the process attribute. But then don't forget (a common mistake) to also reference the id of the commandButton itself as otherwise the action-method won't get called. – Mike Balthasar Jun 05 '18 at 12:08
  • 1
    or even add an empty `

    ` tag inside the other select
    – Kukeltje Jun 05 '18 at 12:25