Monthly Archives: July 2013

Dealing with f:setPropertyActionListener and actionListener in JSF

setactlist
One important thing about f:setPropertyActionListener tag.
ActionListeners will executes in order they defined!

For ex. see next code.
On page:

 <p:commandLink actionListener="#{SomeBean.onSomeAction}" ajax="true">
    <f:setPropertyActionListener 
        target="#{SomeBean.someProperty}" value="SOME_NEW_VALUE !!!" />
    <h:outputText value="Here is some text..." />
</p:commandLink>

JSF Bean:

public class SomeBean implements Serializable {
    private String someProperty;

    public void onSomeAction(ActionEvent event) {
        System.out.println("SomeBean.onSomeAction() fired!");
    }

	public String getSomeProperty() {
        return someProperty;
    }

    public void setSelectedProperty(String someProperty) {
	    System.out.println("SomeBean.setSomeProperty() fired!");
        this.someProperty = someProperty;
    }
}

So, be aware of situation when your property will set after command action listener fired.

The output:

  SomeBean.onSomeAction() fired!
  SomeBean.setSomeProperty() fired!

To solve the issue, you have to use action instead of actionListener.
That’s all.

Also, see http://stackoverflow.com/a/14160010

Passing values from Page to Bean in JSF

passvalue
There are three ways to pass values from page to JSF ManagedBean:

  1. Passing value with f:param tag – using action attribute
  2. Passing value with f:attribute tag – using actionListener attribute
  3. Passing value with f:setPropertyActionListener tag – no need for additional dealing, value allplies directly to bean property!

 

Here is an example JSF project:

File web.xml:

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>bootstrap</param-value>
    </context-param>
</web-app>

File faces-config.xml:

 <?xml version="1.0"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">

    <managed-bean>
        <managed-bean-name>PassParamBean</managed-bean-name>
        <managed-bean-class>passvalue.PassParamBean</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

    <navigation-rule>
        <navigation-case>
            <from-outcome>pass_value</from-outcome>
            <to-view-id>/pass_value.xhtml</to-view-id>
            <redirect />
        </navigation-case>
    </navigation-rule>

</faces-config>

File pass_value.xhtml:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>Passing Values</title>
</h:head>
<h:body>

<h1>Case 1 - f:param</h1>
<h:form>
    <p><h:outputText value="#{PassParamBean.someParam}" /></p>
    <p:commandButton value="Pass Param" action="#{PassParamBean.passParam}">
        <f:param name="someParamHolder" value="THIS is VALUE_OF_PARAM !!!" />
    </p:commandButton>

    <p>&nbsp;</p>

    <h1>Case 2 - f:attribute</h1>
    <p><h:outputText id="someAttributeId" value="#{PassParamBean.someAttribute}" /></p>
    <p:commandButton value="Pass Attribute" actionListener="#{PassParamBean.passAttributeListener}"
        ajax="true" update="someAttributeId">
        <f:attribute name="someAttributeHolder" value="THIS is VALUE_OF_ATTRIBUTE !!!" />
    </p:commandButton>

    <p>&nbsp;</p>

    <h1>Case 3 - f:setPropertyActionListener</h1>
    <p><h:outputText id="somePropertyId" value="#{PassParamBean.someProperty}" /></p>
    <p:commandButton value="Pass Property"
       ajax="true" update="somePropertyId">
       <f:setPropertyActionListener target="#{PassParamBean.someProperty}" 
           value="THIS is VALUE_OF_PROPERTY !!!" />
    </p:commandButton>

    <p>&nbsp;</p>

    <p:commandButton value="Reset" action="#{PassParamBean.reset}" />
</h:form>

</h:body>
</html>

File PassParamBean.java:

 package passvalue;

import java.io.Serializable;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

public class PassParamBean implements Serializable {

    private static final long serialVersionUID = 7980827794690701951L;

    private static final String DEFAULT_OUTCOME = "pass_value";

    private String someParam;
    private String someAttribute;
    private String someProperty;

    public String reset() {
        someParam = null;
        someAttribute = null;
        someProperty = null;

        return DEFAULT_OUTCOME;
    }

    public String passParam() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();

        Map<String, String> params = externalContext.getRequestParameterMap();
        someParam = params.get("someParamHolder");

        return DEFAULT_OUTCOME;
    }

    public void passAttributeListener(ActionEvent event) {
        UIComponent component = event.getComponent();
        Map<String, Object> attrs = component.getAttributes();
        someAttribute = (String) attrs.get("someAttributeHolder");
    }

    public String getSomeParam() {
        return someParam;
    }

    public void setSomeParam(String someParam) {
        this.someParam = someParam;
    }

    public String getSomeAttribute() {
        return someAttribute;
    }

    public void setSomeAttribute(String someAttribute) {
        this.someAttribute = someAttribute;
    }

    public String getSomeProperty() {
        return someProperty;
    }

    public void setSomeProperty(String someProperty) {
        this.someProperty = someProperty;
    }
}

Also, you can download whole project here: passValues.

Creating JSF beans in Java. Best practice.

jsf_isolation
Commonly, the post is related to task when we deal with JSF managed beans.
TO – transfer object for DAO. It presents a big temptation to use TO as a field of JSF Bean.

For ex. in this case we have a TO:

public class SomeTO {
  private String id;
  private String name;
  private String value;
}

TO is used by DAO:

public class SomeDAO {
  public SomeTO get() {
    return new SomeTO();
  }
}

A JSF Bean (wrong way!):

public class SomeBean implements Serializable {
  private SomeTO to;

  public SomeTO getTo() {
    if (to == null) {
      to = new SomeTO();
    }
    return to;
  }
}

And so, on page:

 <p:inputText id="name" value="#{SomeBean.to.name}" />

BUT! A little problem occurs here. We lost the most important thing – loose coupling
So, the right way is to use next:

public class SomeBean implements Serializable {
  private String id;
  private String name;
  private String value;
}

And then, on page:

 <p:inputText id="name" value="#{SomeBean.name}" />

Yes, we duplicate the code. But save it free if we decide to change TO anytime.
Be sure for the mistake!
JSF beans are the part of presentation and they must be independent out of core.

Web

Overriding methods in Javascript

js_override
To override any method in JS+jQuery, use:

$(function(){
  SomeObject.prototype.someMethodName = function() {
    alert('Is overriden !!!');
  }
});

Ex is http://code.google.com/p/primefaces/issues/detail?id=4291
https://gist.github.com/sgruhier/1086231

Web

Bind event to element in jQuery

ordjq
To bind any event to element (for ex. textarea) use next code:

$(document).ready(function() {
  var prevValue = $("#some_id").val();
  $("#some_id").bind('change click keyup', function(e){
    if($(this).val() != prevValue){
      alert(e.which);
    }
    prevValue = $(this).val();
  });
});
Web

Cross-platform css shadow

css-box-shadow
To use cross platform css shadow:

.shadow {
    -moz-box-shadow: 3px 3px 10px #000;
    -webkit-box-shadow: 3px 3px 10px #000;
    box-shadow: 3px 3px 10px #000;
    /* For IE 8 */
    -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=10, Direction=135, Color='#000000')";
    /* For IE 5.5 - 7 */
    filter: progid:DXImageTransform.Microsoft.Shadow(Strength=10, Direction=135, Color='#000000');
}