Showing posts with label JSF. Show all posts
Showing posts with label JSF. Show all posts

Saturday, 25 February 2012

JSF How to spell check on JSF (facelets and bean)

Work in progress...If you have any comment to extend/optimize it please post!

The goal

I want to spell check all *.xhtml and *.java in my JSF application

The solution (incomplete)

find . -name *.xhtml -exec aspell --mode=html -c {} \;
Criticism: EL exressions (e.g. #{fooBean.foo()}) are not skipped by the speller.

Friday, 24 February 2012

JSF: Changes made to submitted value by the Managed Bean are not rendered after ajax call and using immediate="true"

The goal and problem

In a facet form I have a value. When I click the commandButton it calls an action on the Managed Bean which changes the submitted value. The updated value should be rendered on the view...but it doesn't! Note that I use immediate="true" to skip the validation phase (because validation error may be shown).
[Actually what I want to do is render some numerical values and randomize them each time I click the commandButton] Managed Bean Foo.java:
public void submit() {
   this.val = 3; //the new value
}
Facelet:
<h:form>
<p:inputText value="#{fooBean.val}"></p:inputText>

<p:commandButton value="Submit"
  action="#{fooBean.submit()}" 
  update="@form"
  immediate="true" />
</h:form>

The solution

Skipping validation doesn't mean that the input value is not submitted!! In the Managed Bean I change the value foobean.val and indeed changes but the component p:inputText preserves the old value because its attribute submittedValue is the old one. The solution is to use the attribute process="@this" because this way we don't submit the value!. The correct Facelet is the following:
<h:form>
<p:inputText value="#{fooBean.val}"></p:inputText>

<p:commandButton value="Submit"
  action="#{fooBean.submit()}" 
  update="@form"
  immediate="true"
  process="@this" />
</h:form>

Wednesday, 15 February 2012

JSF: How to bind a Double to and format it (or: How to tackle "java.lang.Long cannot be cast to java.lang.Double")

The problem:If the inputText is bound to a Double and an integer value is given (e.g. 100) then a java.lang.Long cannot be cast to java.lang.Double exception is thrown.

The solution (hint):The solution is at the end of the post..

Goal 1: Bind the Double attribute value of the ManagedBean fooBean into a inputText

<p:inputText value="#{fooBean.value}" />
OK the above works fine.

Goal 2: Add formatting

<p:inputText value="#{fooBean.value}">
  <f:convertNumber maxFractionDigits="2" type="number"/>
</p:inputText>
But...if I give as input a number without a decimal part (e.g. 100) a coversion exceptions is thrown: java.lang.Long cannot be cast to java.lang.Double. The reason for this exception is described in stack overflow Phill's post:

After some investigation (see e.g. here, here and here) that <f:convertNumber> is the problem. It seems that the number it converts to is dependent on the input you give it - it could be an integer or a floating point number. In other words, it doesn't look at the target type - it just generates an instance of java.lang.Number. Which is hardly ideal, although I can't determine whether this is because somewhere I'm using an old version of JSF or EL or something like that. Proposals from the internet:

  • Add converterId="javax.faces.Double" into ...But: accepts and validates doubles but formatting doesn't work! (see )

Solution

In a few words..Formating works only if the value is bound to a BigDecimal! Double doesn't work :(
<p:inputText value="#{fooBean.value}" style="width:50px">
  <f:validateDoubleRange />
  <f:convertNumber maxFractionDigits="2" type="number"/>
</p:inputText>

References of people tackling the same problem

Monday, 13 February 2012

JSF: How to access from a Facelet an enum declared in the Managed Bean

Enum (TYPE.java):
public enum TYPE {
 TYPE_A,
 TYPE_B;

 //...
}
Managed Bean (FooBean.java):
public void init(TYPE type) {
  //...
}
Facelet:

<f:metadata>
   <f:event type="preRenderView" listener="#{fooBean.init('TYPE_A')}"/>
</f:metadata>

References

http://stackoverflow.com/questions/3916871/passing-a-enum-value-as-a-parameter-from-jsf

Thursday, 2 February 2012

JPA:Facelets: How to create a locale variable in a facelet


<!-- setting value1 into foo1 -->
<ui:param name="foo1" value="#{'value1'}"/>
<!-- calling a managed bean method myMethod() an setting the result into foo2 -->
<ui:param name="foo2" value="#{mybean.myMethod()}"/>

Note 1

<c:set /> and #{pageScope.set()} hasn't worked for me (see http://www.warski.org/blog/2008/04/value-to-variable-binding-let-tag-for-jsf-facelets-and-seam/).

Note 2

A <c:set /> variable has page scope meaning that I cannot be sent to a managed bean (e.g. as a method argument).

Monday, 30 January 2012

JSF: outputText doesn't not localize a Double-value

I want to localize the Double attribute value of the managed bean fooBean in Greek; i.e. number 12.3 should be 12,3 in greek locale (locale=el) and 12.3 in english locale (locale=en) Wrong code:
 <h:outputText value="#{fooBean.value}" />
Right code:
 <h:outputText value="#{fooBean.value">
    <f:convertNumber type="number" />
</h:outputText>

Friday, 27 January 2012

JSF:Composite Components: How to update a form which contains a composite component from the cc

Goal: The facelet outer.xhtml contains the composite component resources/components/foocomp.xhtml. I want when I click the button in the foocomp.xhtml to update the form in order I see any errors/messages in <messages>

Attempt 1: using @form (not working)

Facelet outer.xhtml:
xmlns:comps="http://java.sun.com/jsf/composite/components">

<h:form>
   <!-- PrimeFaces messages component; equivalent to <h:messages> -->
   <p:messages showDetail="false" globalOnly="true"></p:messages>
   <comps:foocomp></comps:foocomp>
  
</h:form>

<p:commandButton action="#{fooBean.myAction()}" 
   update="@form"></p:commandButton>

Output:
javax.faces.FacesException: Cannot find component with identifier "'id_j3'" in view.
* Note: the id id_j3 is the random id given to the form as I found out.

Attempt 2: giving the form an id (not working)

Facelet outer.xhtml:

xmlns:comps="http://java.sun.com/jsf/composite/components">

<h:form id="outerForm" prependId="false">
   <!-- PrimeFaces messages component; equivalent to <h:messages> -->
   <p:messages showDetail="false" globalOnly="true"></p:messages>
   <comps:foocomp formId="outerForm"></comps:foocomp>
  
</h:form>

<composite:interface>
  <!-- the enclosed form id which will updated after an action is triggered -->
  <composite:attribute name="formId" type="java.lang.String" required="true" />
</composite:interface>

<p:commandButton action="#{fooBean.myAction()}" 
   update="#{cc.attrs.formId}">
</p:commandButton>


Output:
javax.faces.FacesException: Cannot find component with identifier "'outerForm'" in view.

Attempt 3: giving the form an id and referencing it with ':' (working!)

Facelet outer.xhtml:
xmlns:comps="http://java.sun.com/jsf/composite/components">

<h:form id="outerForm" prependId="false">
   <!-- PrimeFaces messages component; equivalent to <h:messages> -->
   <p:messages showDetail="false" globalOnly="true"></p:messages>
   <comps:foocomp formId="outerForm"></comps:foocomp>
  
</h:form>
<composite:interface>
  <!-- the enclosed form id which will updated after an action is triggered -->
  <composite:attribute name="formId" type="java.lang.String" required="true" />
</composite:interface>

<p:commandButton action="#{fooBean.myAction()}" 
   update=":#{cc.attrs.formId}"></p:commandButton>

Thursday, 19 January 2012

Primefaces <p:button> java.lang.NullPointerException

Exception
java.lang.NullPointerException
 at org.primefaces.component.button.ButtonRenderer.buildOnclick(ButtonRenderer.java:128)
 at org.primefaces.component.button.ButtonRenderer.encodeMarkup(ButtonRenderer.java:59)
Solution:<p:button> points to an invalid link..

JSF: <p:selectOneRadio> gives "Value is not valid"

Facelet:
<p:selectOneRadio
   value="#{fooBean.val}"
   converter="valConverter">
 <f:selectItems value="#{fooBean.refValues}" var="v" itemLabel="#{v.label}" itemValue="#{v}" />
</p:selectOneRadio>

Solution

Make sure that:
  • Make sure that val has properly implemented hashCode() and equals() (see StackOverflow)

Wednesday, 18 January 2012

JSF does not support class-level validation!

still open..see https://hibernate.onjira.com/browse/BVAL-214

For a description+example of JSR 303 class-level validation see the following link (the comments)

JSF: How to get the current web page address

String currentPage = FacesContext.getCurrentInstance().getViewRoot().getViewId();

Tuesday, 17 January 2012

JSF:Facelet:Composite Component:Troubleshooting: Cannot find component with id blah

Wrong 1:
<composite:implementation>
 <p:inputText id="input" />
 <p:message for="#{cc.clientId}:input" />
Wrong 2:
<composite:implementation>
 <p:inputText id="input" />
 <p:message for="#{cc.component}:input" />
Right:
<composite:implementation>
 <p:inputText id="input" />
 <p:message for="input" />

Friday, 13 January 2012

JSF:Facelet: How to use <f:metadata> with a template

view01.xhtml
    <ui:composition template="template.xhtml">
        <ui:define name="metadata">
          <f:metadata>
            <f:viewParam name="id"/>
          </f:metadata>
        </ui:define>
        <ui:define name="content">
            <h1>The big news stories of the day</h1>
        </ui:define>
    </ui:composition> 
template.xhtml
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:f="http://java.sun.com/jsf/core"
          xml:lang="en" lang="en">
     
    <body>
    <f:view>
       
            <ui:insert name="metadata"/>
       
        <div id="container">
            <ui:insert name="content"/>
        </div>
    </f:view>
    </body>
    </html> 

References

Thursday, 12 January 2012

JSF:Facelets: How to format output as Double with 2 decimal digits

<h:outputText value="#{fooBean.value}">
  <f:convertNumber maxFractionDigits="2" groupingUsed="false" />
</h:outputText>

JSF:Facelets: How to format output as Integer

<h:outputText value="#{fooBean.value}">
  <f:convertNumber maxFractionDigits="0" groupingUsed="false" />
</h:outputText>

Monday, 9 January 2012

Friday, 16 December 2011

PrimeFaces p:button vs HTML button (or: why does p:button re-GETs the page?)

// NOT GET; NOT POST
<button onclick="foo()">My button</button>

function updateAllCells() {
 ...
 //returns nothing
}
//CAUSES GET; page is redisplayed
<p:button onclick="foo();" value="My button" />
// NOT GET; NOT POST
<p:button onclick="foo();return false;" value="My button" />

Tuesday, 13 December 2011

JSF+PrimeFaces: how to download Excel (with actionListener)

public void exportExcelActionListener(ActionEvent event) {
  try {
    String filename = "myexceltodownload.xls";
         
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    externalContext.setResponseContentType("application/vnd.ms-excel");
      
    // http://stackoverflow.com/questions/3592058/how-to-send-byte-as-pdf-to-browser-in-java-web-application
    // attachment (pops up a "Save As" dialogue) or inline (let the web browser handle the display itself)
    externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\""+filename+"\"");
 
    getWorkbook().write(externalContext.getResponseOutputStream()); //get workbook
    facesContext.responseComplete(); //if I don't call responseComplete() => IllegalStateException
      
    return null; //remain on same page
  } catch(Exception e) {
    // handle exception...
    return null; //remain on same page
   }
}

  
    
  

Note: To experiment with the download commandbutton of primefaces...
Note: Strangely didn't work for me....