0
votes

I have a PrimeFaces slider with an associated inputText. Everything is working fine, except I can´t find a way of formatting the inputText value. I want the inputText to show and get values in currency format.

What I've tried so far:

  • Changing the p:inputText with a pe:inputNumber component: causes an exception because the value can't be set (slider simply doesn´t work with inputNumber);
  • Setting the p:slider target to a h:inputHidden component with the same value than p:inputText (with a f:convertNumber attached to): works when changing values through slider, but when using inputText to change the value slider doesn´t update (throws an UpdateModelException behind the scenes);

Update: it was found later that the second option exception is thrown because f:convertNumber expects a number type bean property, not an integer one. Both solutions shown below work around this issue.

Is there a simple way of doing this without using jQuery?

Thanks!

Filipe

2
I think that the right way is your third point. Do you use the same bean property for both components?giaffa86
Only the inputText requires a bean property, the slider only requires an inputText that it will write data to AFAIK.jfneis
Do you need an inputText? You can achieve this using inputHidden and display attribute of slidergiaffa86
@giaffa86 that´s the second option I tried. I need an inputText where the user can also type the value, so it's not a valid option.jfneis
Yes but if you don't need strictly an InputText you can achieve this using an outputText as shown in Primefaces Showcase.giaffa86

2 Answers

1
votes

Below I posted minimal requirements to obtain a custom inputText but you lost live update on it.

SliderView.java

private int number1 = 0;
private String number2 = String.valueOf(number1);

public int getNumber1() {
return number1;
}

public void setNumber1(int number1) {
this.number1 = number1;
}



public String getNumber2() {
return number2;
}

public void setNumber2(String number2) {
this.number2 = number2;
}

public void converToInt() {
log.debug(number2);
//TODO should be improved
this.number1 = Integer.parseInt(number2);
}

public void onSlideEnd(SlideEndEvent event) {
log.debug("current number: " + event.getValue());
this.number1 = event.getValue();
this.number2 = String.valueOf(event.getValue());

}

slider.xhtml

<h:form id="bcr_form_2" styleClass="form">
    <h:panelGrid columns="1" style="margin-bottom: 10px">
        <p:inputMask id="output" value="#{sliderView.number2}">
            <p:ajax event="keyup" listener="#{sliderView.converToInt}" update="@form:txt @form:slider" />
            <f:converter converterId="CurrencyConverter" />
            <pe:keyFilter regEx="/[0-9_]/i" />
        </p:inputMask>
        <h:inputHidden id="txt" value="#{sliderView.number1}" />
        <p:slider id="slider" for="txt" style="width: 200px">
            <p:ajax event="slideEnd" listener="#{sliderView.onSlideEnd}" update="@form:output" />
        </p:slider>
    </h:panelGrid>
</h:form>

CurrencyConverter.java

@FacesConverter("CurrencyConverter")
public class CurrencyConverter implements Converter {
  @Override
  public Object getAsObject(FacesContext context, UIComponent component, String value) {
    return value.replace('€', ' ').trim();
  }

  @Override
  public String getAsString(FacesContext context, UIComponent component, Object value) {
    return value.toString() + "€";
  }
}

Glad to be helpful.

0
votes

So there are 2 ways of solving this problem:

  1. Creating a custom converter (drafted by @giaffa86 in his solution);
  2. Enabling Number getters and setters to the int property and using them with inputText (what's simpler, IMO).

The code below shows how to implement the second option.

TestView.java

@ManagedBean(name="testView")
@ViewScoped
public class TestView {

    private int realValue = 500;

    public int getValueAsInt() {
        return this.realValue;
    }

    public Number getValueAsNumber() {
        return (Number)realValue;
    }

    public void setValueAsInt(int value) {
        this.realValue = value;
    }

    public void setValueAsNumber(Number value) {
        this.realValue = value.intValue();
    }

    public void onSlideEnd(SlideEndEvent event) {
        this.realValue = event.getValue();
    }
}

view.xhtml

    <p:inputText id="input" value="#{testView.valueAsNumber}">
        <p:ajax update="slider" />
        <f:convertNumber currencySymbol="$" type="currency"
            integerOnly="true" />
    </p:inputText>

    <h:inputHidden id="hidden" value="#{testView.valueAsInt}" />
    <p:slider id="slider" for="hidden" minValue="0" maxValue="1000" step="10">
        <p:ajax event="slideEnd" listener="#{testView.onSlideEnd}" update="input" />                    
    </p:slider>

This solution, as the first option, also loses live update, but that's no problem in my scenario.