0

I'm trying to create simple web application (studies project) that allows to create books and libraries (book contains information about library).

My problems is: I want to show user select list of libraries while editing (Create/Update) library and allow choose one that will be saved within DB.

For now I have something like this: edit.xhtml (part)

        <h:form id="book_form" prependId="false">
            <p:messages id="msgs" autoUpdate="true"/>
            <p:panelGrid columns="2">
                <p:outputLabel value="Title" for="title"/>
                <p:inputText id="title" required="true"
                             value="#{bookController.book.title}">
                    <f:validateLength maximum="50"/>
                </p:inputText>
                <p:outputLabel value="Author" for="author"/>
                <p:inputText id="author" required="true"
                             value="#{bookController.book.author}">
                    <f:validateLength maximum="50"/>
                </p:inputText>
                <p:outputLabel value="Year" for="year"/>
                <p:inputText id="year" required="true"
                             value="#{bookController.book.year}">
                    <f:convertNumber pattern="0"/>
                    <f:validateDoubleRange minimum="0" maximum="2020"/>
                </p:inputText>
                <p:outputLabel value="Library" for="library"/>
                <p:selectOneMenu id="library" value="#{bookController.libId}" effect="fold" editable="true"> <!--converter="libraryConverter"  value="#{bookController.book.library}"-->
                    <f:selectItem itemLabel="Select One" itemValue="#{null}" />
                    <f:selectItems value="#{bookController.libraries}" var="library" itemValue="#{library.id}" itemLabel="#{library.name}"/> <!-- itemValue="#{library.id}"--> <!-- var="library" itemLabel="#{library.name}" itemValue="#{library}" val-->
                </p:selectOneMenu>
                <f:facet name="footer">
                    <p:commandButton id="save_btn" value="Save"
                                     update="@form"
                                     action="#{bookController.actionSave()}"/>
                    <p:button value="Return to menu"
                              href="./index.xhtml"/>
                </f:facet>
            </p:panelGrid>
        </h:form>

LibraryConverter.java - basing on Conversion Error setting value for 'null Converter' - Why do I need a Converter in JSF?

 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.polsl.lab45r.library;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import pl.LAB.model.Library;

/**
 * Converter for library objects
 * @version 1.0
 */
@FacesConverter("libraryConverter")
public class LibraryConverter implements Converter {

    /**
     * Bean for finding library
     */
    @EJB
    LibraryBean libraryBean;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        if (submittedValue == null || submittedValue.isEmpty()) {
            return null;
        }

        try {
            return libraryBean.findLibraryById(Integer.valueOf(submittedValue));
        } catch (NumberFormatException e) {
            throw new ConverterException(new FacesMessage(submittedValue + " is not a valid Library ID"), e);
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
        if (modelValue == null) {
            return "";
        }

        if (modelValue instanceof Library) {
            return String.valueOf(((Library) modelValue).getId());
        } else {
            throw new ConverterException(new FacesMessage(modelValue + " is not a valid Library"));
        }
    }

}

At first I tried saving library just as library object (not as some ID), but when I was trying to save I was getting errors that some name of library is not valid ID, however getAsString and getAsObject should work only on IDs, not on names. You can see what I tried in XHTML comments.

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
OldShaterhan
  • 175
  • 1
  • 2
  • 12
  • 3
    This converter should work with `itemValue="#{library}"`, but I won't guess on "was getting errors". – Selaron Jan 13 '20 at 07:06
  • 1
    Your model value `libId` is not at all the `Library` object but it's its ID which is probably `Long`. Either fix it to be of `Library` type, or simply remove the converter (JSF has already built-in automatic converters for `Long`). – BalusC Jan 13 '20 at 09:13
  • @BalusC, please find my comment below code - `At first I tried saving library just as library object (not as some ID)`. I started trying with ID, when I still had problems with conversion. – OldShaterhan Jan 13 '20 at 12:08
  • @Selaron, so I should set itemValue="#{library}" , label can I set anyway? If yes, I'll send you my errors, when I'll be home. – OldShaterhan Jan 13 '20 at 12:08
  • The code as you posted is not supposed to work as you expected. Work through the basic examples provided in the abovelinked duplicate to grasp the basic concepts first. It totally answers the question stated in your current title. – BalusC Jan 13 '20 at 12:28
  • @BalusC I reviewed your answer there and I'm using it this way you wrote (at least I think), if you would check my HTML code, then you'd probably notice it. I fixed two things for using converter (editable set to false and way of notating converter) – OldShaterhan Jan 13 '20 at 22:00
  • Okay, I found the main problem - missing ManagedBean and RequestScoped annotations for LibraryConverter classes. – OldShaterhan Jan 13 '20 at 22:06

0 Answers0