3

I have a backing bean containing a field creditCard which can have two string values y or n populated from the DB. I would like to display this in checkbox so that y and n gets converted to boolean.

How can I implement it? I can't use a custom converter as getAsString() returns String while rendering the response whereas I need a boolean.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Tarun Sapra
  • 1,851
  • 6
  • 26
  • 40
  • why can't you change the Backing Bean instance variable (creditCard) to be a Boolean - it's best not to represent types which Java has an Object to represent by a String. – planetjones Jun 15 '11 at 11:23
  • it's a requirement to have the type as 'y' or 'n' as in the legacy DB it's 'y' or 'n' – Tarun Sapra Jun 15 '11 at 11:26
  • yes but Java is a layer over your database - which is Object Orientated. By leaving as a String you're not using Objects effectively. So in the Java Object it can be a Boolean and then in your SQL interactions convert it to 'y' or 'n'. So when reading convert char to Boolean and when writing convert Boolean to char. – planetjones Jun 15 '11 at 11:27
  • planetjones, this is exactly what i had suggested to the client but the client wants the bean to have 'y' or 'n' only – Tarun Sapra Jun 15 '11 at 11:32
  • oh right ok @Tarun - sounds like you're unlucky there. Thankfully I've never had a requirement which specifies what data types the Objects should be ;) In that case the @BalusC to change the accessors to convert to Boolean sounds sensible. – planetjones Jun 15 '11 at 11:40

3 Answers3

21

The <h:selectBooleanCheckbox> component does not support a custom converter. The property has to be a boolean. Period.

Best what you can do is to do the conversion in the persistence layer or to add extra boolean getter/setter which decorates the original y/n getter/setter or to just replace the old getter/setter altogether. E.g.

private String useCreditcard; // I'd rather use a char, but ala.

public boolean isUseCreditcard() {
    return "y".equals(useCreditcard);
}

public void setUseCreditcard(boolean useCreditcard) {
    this.useCreditcard = useCreditcard ? "y" : "n";
}

and then use it in the <h:selectBooleanCheckbox> instead.

<h:selectBooleanCheckbox value="#{bean.useCreditcard}" />
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Try not to forget replacing `get` with `is` while you are doing this trick. :) – Yigitalp Ertem Dec 04 '14 at 12:54
  • 1
    Any reason why `` is not supporting a custom converter? 15k persons ended up here and the best and only answer is literally to rewrite the generated persistence layer of legacy databases. – ForguesR Nov 26 '19 at 21:23
  • 1
    @ForguesR: because the supported type of the `value` attribute is `boolean` not `Object`. If the model is representing booleans as non-booleans (char, number, string, etc) then I'd say that the model is wrong. Consider creating a composite component to keep it DRY. – BalusC Nov 27 '19 at 09:30
  • "the model is representing booleans as non-booleans" - it might be helpful if the custom model wraps a boolean value and the converter would be wrap/unwrap it – Andrew Tobilko May 01 '20 at 15:09
1

You can use the BooleanConverter for java primitives, this parses the text to boolean in your managedbean, at here just put in your code like this in you .xhtml file

<p:selectOneMenu id="id"
                        value="#{yourMB.booleanproperty}"
                        style="width:60px" converter="javax.faces.Boolean">
                        <p:ajax listener="#{yourMB.anylistener}"
                            update="anyIDcontrol" />
                        <f:selectItem itemLabel="------" itemValue="#{null}"
                            noSelectionOption="true" />
                        <f:selectItem itemLabel="y" itemValue="true" />
                        <f:selectItem itemLabel="n" itemValue="false" />                                                
                    </p:selectOneMenu>

ManagedBean:

@ManagedBean(name="yourMB")
@ViewScoped
public class YourMB implements Serializable {

       private boolean booleanproperty;


    public boolean isBooleanproperty() {
        return booleanproperty;
    }
    public void setBooleanproperty(boolean booleanproperty) {
        this.booleanproperty = booleanproperty;
    }      

}    
csstugfurher
  • 89
  • 12
0

I had the similar problem, and I agree with previous post, you should handle this issues in persistence layer. However, there are other solutions. My problem was next: I have TINYINT column in database which represented boolean true or false (0=false, 1=true). So, I wanted to display them and handle as a boolean in my JSF application. Unfortunately, that was not quite possible or just I didn't find a proper way. But instead using checkbox, my solution was to use selectOneMeny and to convert those values to "Yes" or "No". Here is the code, so someone with similar problem could use it.

Converter:

@FacesConverter("booleanConverter")

public class BooleanConverter implements Converter{

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {

    short number= 0;

    try {
        if (value.equals("Yes")) {
            number= 1;
        }
    } catch (Exception ex) {
        FacesMessage message = new FacesMessage();
        message.setSeverity(FacesMessage.SEVERITY_FATAL);
        message.setSummary(MessageSelector.getMessage("error"));
        message.setDetail(MessageSelector.getMessage("conversion_failed") + ex.getMessage());
        throw new ConverterException(message);
    }
    return number;
    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {


    return value.toString();
    //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

JSF Page:

<h:selectOneMenu id="selectOnePlayerSucc" value="#{vezbaTrening.izvedenaUspesno}" converter="booleanConverter">
  <f:selectItems id="itemsPlayerSucc" value="#{trainingOverview.bool}" var="opt" itemValue="#{opt}" itemLabel="#{opt}"></f:selectItems>

And in my ManagedBean I created a list with possible values ("Yes" and "No")

private List<String> bool;

public List<String> getBool() {
    return bool;
}

public void setBool(List<String> bool) {
    this.bool = bool;

@PostConstruct
public void init () {
    ...

    bool = new LinkedList<>();
    bool.add("Yes");
    bool.add("No");
}

enter image description here

user3459287
  • 95
  • 1
  • 2