1

The context is a form to add or modify an entry to/of a database table. Inside of it, I want to create a search/selection subform with :

  1. A search text input that request the database to fill a selectOneMenu
  2. The dynamically filled selectOneMenu to select a value
  3. A classic selectOneMenu with values hard-coded

So far I achieved to get the search text input to work only if I am modifying an existing entry (which id is passed via URL). It doesn't work if when I'm creating a new one.

The second problem is (in the case of modifying an entry, which is working already), when a value is chosen in the selectOneMenu, the listener seems to not be called. But with the selectOneMenu that have hard-coded values, it works fine. See EDIT for additional informations.

Here is the subform code :

<h:form>
    <h2>#{msg['addPeopleToFilm']}</h2>
    <div class="inputWrapper"> 
        <h:inputText id="search" value="#{beanPersonne.recherche}" >
            <f:ajax listener="#{beanPersonne.searchStringChanged}" render="output" event="change" />
        </h:inputText>
        <label>#{msg['personSearch']}</label>
    </div>

    <div class="selectWrapper" >
        <h:selectOneMenu value="#{beanFilm.idToAdd}" id="output" >
            <f:selectItems 
            value = "#{beanPersonne.resultatsRechercheDynamique}" 
            var="personne" 
            itemValue="#{personne.idPersonne}"
            itemLabel="#{personne.prenom} #{personne.nom}" /> 
            <f:ajax listener="#{beanFilm.idToAddChanged}" render="idToAdd" event="change" />
            </h:selectOneMenu>
        </div>

        <div class="selectWrapper" >
        <h:selectOneMenu value="#{beanFilm.categoryChoice}" id="category"> 
            <f:selectItem itemLabel="#{msg['actor']} ›" itemValue="0" />
            <f:selectItem itemLabel="#{msg['producer']} ›" itemValue="1" />
            <f:selectItem itemLabel="#{msg['director']} ›" itemValue="2" />
            <f:ajax listener="#{beanFilm.categoryChoiceChanged}" render="categoryChoice" event="change" />
            </h:selectOneMenu> 
        </div>

    <h:commandButton value="Test">
    </h:commandButton>

    <h2><h:outputText id="idToAdd" value="#{beanFilm.idToAdd}" /></h2>
    <h2><h:outputText id="categoryChoice" value="#{beanFilm.categoryChoice}" /></h2>
</h:form>

And here is most of my bean beanFilm (almost the same in beanPersonne):

public class BeanFilm implements Serializable {

    private static final long serialVersionUID = 807253156212218187L;
    private Film film = new Film();
    private String recherche = new String();
    private String idToAdd = new String();
    private String categoryChoice = new String();
    private List<Film> resultatsRechercheDynamique = new ArrayList<Film>();


    public List<Film> getResultatsRechercheFilmPro() {
        return DAOFilmJPA.getInstance().getFilmsParTitre(recherche);
    }

    public String searchByTitle(String title)
    {
        recherche = title;
        this.resultatsRechercheDynamique = getResultatsRechercheFilmPro();
        return null;
    }

    public void searchStringChanged(AjaxBehaviorEvent abe)
    {
        searchByTitle(recherche);
    }


    public void idToAddChanged(AjaxBehaviorEvent abe)
    {
        // HERE GOES FUTURE CODE
    }

    public void categoryChoiceChanged(AjaxBehaviorEvent abe)
    {
        // HERE GOES FUTURE CODE
    }


    public List<Film> getResultatsRechercheDynamique() {
        return resultatsRechercheDynamique;
    }

    public void setResultatsRechercheDynamique(
            List<Film> resultatsRechercheDynamique) {
        this.resultatsRechercheDynamique = resultatsRechercheDynamique;
    }

        public Film getFilm() {
        return film;
    }

    public void setFilm(Film film) {
        this.film = film;
    }

    public int getIdFilm() {
        return film.getIdFilm();
    }

    public void setIdFilm(int id) {
        film = DAOFilmJPA.getInstance().get(id);
    }

    public String getRecherche() {
        return recherche;
    }

    public void setRecherche(String recherche) {
        this.recherche = recherche;
    }

    public String doRecherche() {
        return "toResultatsRecherche";
    }

    public String getIdToAdd() {
        return idToAdd;
    }

    public void setIdToAdd(String idToAdd) {
        this.idToAdd = idToAdd;
    }

    public String getCategoryChoice() {
        return categoryChoice;
    }

    public void setCategoryChoice(String categoryChoice) {
        this.categoryChoice = categoryChoice;
    }
}

EDIT: If I add a selectItem with fixed value in the first selectOneMenu, next to the selectItems, it triggers the listener just fine, but only on this entry, not those generated by selectItems. With debug mode, I found that selecting a value generated by selectItems doesn't call the linked listener, while it is called when using selectItem.

MattOnyx
  • 172
  • 12
  • Try `change` for the event name. Also look in your javascript console for clues – kolossus Apr 01 '15 at 20:10
  • I just tried `change` event, and modified my code to use `f:ajax listener` instead of `valueChangedListener` but nothing changed so far. My javascript console doesn't provide any information. Please see my **EDIT** for additional details. – MattOnyx Apr 01 '15 at 21:52
  • 1
    For starters, always add `` to the form (and ajax-update it), or at least take the effort to read the server logs and JS console if something appears to be failing silently in client side. You should have noticed a missing "Validation Error: Value is not valid" message. – BalusC Apr 02 '15 at 05:45
  • Your comment and link for duplicate helped me a lot. By using `h:message` and changing my bean scope to `view` I achieved my goal. Thank you very much. – MattOnyx Apr 02 '15 at 09:59

0 Answers0