0

I've got a list of books and I try to filter them based off a text (title) and a category

The index.xhtml file looks something like this

<h:form>

            <h:inputText  a:placeholder="Search by title" value="#{booksBean.searchString}"
                         onkeypress="if (event.keyCode == 13) {onchange(event); return false;}"
                         onchange="return event.keyCode !== undefined">
                <f:ajax listener="#{booksBean.updateBook}" render="output"/>
            </h:inputText>

            <h:panelGroup style = "margin-left: 5px;">
                <h:form>
                    <h:selectOneMenu id="combo" value="#{booksBean.selectedCategory}">
                        <f:selectItems value="#{booksBean.categories}" var="category" itemValue="#{category}" />
                        <f:ajax listener="#{booksBean.updateBook}" render="output" />
                    </h:selectOneMenu>

                </h:form>
            </h:panelGroup>

</h:form>
<h:panelGroup id="output">
            <h:form>
                <ui:repeat value="#{booksBean.books}" var="book">
                    <ui:decorate template="/templates/product-summary.xhtml">
                        <ui:param name="book" value="#{book}"/>
                        <ui:define name="product-description">
                            <p>#{book.description}</p>
                        </ui:define>
                    </ui:decorate>
                </ui:repeat>
            </h:form>
        </h:panelGroup>

When the searchString is set, the selectedCategory variable gets null and vice versa

Bean looks like this

@Named("booksBean") //name of the bean is booksBean
@RequestScoped
public class BooksBean {

private BookRepository bookRepository = new BookRepository();


public Set<String> getCategories() {
    return categories;
}

public void setCategories(Set<String> categories) {
    this.categories = categories;
}

private Set<String> categories = new LinkedHashSet<>();

private String searchString = "";

private List<Book> books;

public String getSelectedCategory() {
    return selectedCategory;
}

public void setSelectedCategory(String selectedCategory) {
    this.selectedCategory = selectedCategory;
}

private String selectedCategory = "";

@PostConstruct
public void initialize() {
    books = bookRepository.getBooksByTitleAndCategory(searchString, selectedCategory);
    getAllCategories();
}

public List<Book> getBooks() {
    return books;
}

public String getSearchString() {
    return searchString;
}

public void setSearchString(String searchString) {
    this.searchString = searchString;
}

private void getAllCategories() {
    categories.add("");
    for (Book book : bookRepository.findAll()) {
        categories.add(book.getCategory_name());
    }

}


public void updateBook(AjaxBehaviorEvent event) {
    this.books = bookRepository.getBooksByTitleAndCategory(searchString, selectedCategory);
}

}

Is there any way I can make the ajax take into account both variables when making the call?

  • In order to retain the previous value of a property while resubmitting, you need to use broader than a request scoped bean, at least a view scoped bean in this case. – Tiny Jul 11 '17 at 15:13
  • Could you give me a hint about how that'd be done? –  Jul 11 '17 at 15:17
  • Change `@RequestScoped` to `@ViewScoped` above the managed bean `BooksBean` (import that annotation from the CDI package carefully, `javax.faces.view.ViewScoped`). – Tiny Jul 11 '17 at 15:22
  • That actually worked. Thank you very much! –  Jul 11 '17 at 15:43
  • 1
    https://stackoverflow.com/questions/7031885/how-to-choose-the-right-bean-scope – Kukeltje Jul 11 '17 at 16:03

1 Answers1

1

As Tiny suggested

"Change @RequestScoped to @ViewScoped above the managed bean BooksBean (import that annotation from the CDI package carefully, javax.faces.view.ViewScoped)."

Navoneel Talukdar
  • 4,393
  • 5
  • 21
  • 42