Skip to main content

JSF 2 - Dynamically manipulating the component tree with system events

Let's suppose we want to modify the metadata (attributes)  of elements such as render, requried, maxlength but we do not define in JSF tags. The manipulating components can be conducted in Drools files, for example. How could we do? I think that is what we need to change something of component tree during JSF life-cycle.


JSF supports event handling throughout the JSF life-cycle. In this post, I use two events: postAddToView for scanning components tree and preRenderView for manipulating the meta of components before rendering to GUI.

I modified my own project from previous post for this example. This is my first further JSF trying out with the project as I said before. :)

We define the tags f:event below the form - a container component of the components which we want to work on. The valid values for the attribute type for f:event can be found from tag library document of JSF 2.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:h="http://java.sun.com/jsf/html">
 <h:head>
  <title>JSF - System events Example</title>
 </h:head>
 <h:body>
  <h:form id="helloForm">
   <f:event listener="#{guiHanlder.onScanView}" type="postAddToView"/>
   <f:event listener="#{guiHanlder.onManipulateView}" type="preRenderView"/>
   
   <h:outputText value="#{helloBean.greeting}" id="greetingOutputTxt"/>
   <br/>
   <h:inputText value="#{helloBean.name}" id="nameInputText"/>
  </h:form>
 </h:body>
</html>

This is the managed bean below is just used for displaying information.

package vn.nvanhuong.jsf_myfaces;

import javax.faces.bean.ManagedBean;

@ManagedBean(name = "helloBean")
public class HelloManagedBean {
 private String greeting;
 private String name;
 
 public String getGreeting() {
  return greeting;
 }

 public void setGreeting(String greeting) {
  this.greeting = greeting;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}

Here, I just used a method from a Java class to manipulate the components. In my future posts, I am going to try to call a Drools files instead.

package vn.nvanhuong.jsf_myfaces;

import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlInputText;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.event.PostAddToViewEvent;
import javax.faces.event.PreRenderViewEvent;

@ManagedBean(name = "guiHanlder")
public class GuiManipulatingHandler {
 private List uiComponents;
 
 public void onScanView(PostAddToViewEvent event) {
  UIComponent rootView = event.getComponent();
  uiComponents = rootView.getChildren();
 }

 public void onManipulateView(PreRenderViewEvent event) {
  for (UIComponent uiComponent : uiComponents) {
   if(uiComponent instanceof HtmlOutputText){
    ((HtmlOutputText) uiComponent).setValue("Hello");
   }
   if(uiComponent instanceof HtmlInputText){
    ((HtmlInputText) uiComponent).setMaxlength(100);
    ((HtmlInputText) uiComponent).setValue("JSF system events");
   }
  }
 }
}


I ran on Tomcat (v7) and the result looks like:



Source code: https://github.com/vnnvanhuong/jsf_myfaces/tree/jsf_system_events

Reference:
[1]. http://balusc.omnifaces.org/2006/09/debug-jsf-lifecycle.html

Comments

Popular posts from this blog

Attribute 'for' of label component with id xxxx is not defined

I got the warning in the log file when I have used the tag <h:outputLabel> without attribute " for " in xhtml file. It was really polluting my server log files. The logged information actually makes sense anyway! We could find an answer as the following: "Having h:outputLabel without a "for" attribute is meaningless. If you are not attaching the label, you should be using h:outputText instead of h:outputLabel." However, these solutions are not possible just for my situation. Instead of using h:outputText for only displaying text, my team has used h:outputLabel too many places. We were nearly in our release time (next day) so it is quite risky and takes much efforts if we try to correct it. Because the style (with CSS) is already done with h:ouputLabel . The alternative by adding attribute " for " the existing h:outputLabel is not reasonable either. I really need to find another solution. Fortunately, I came across a way if I cha...

4 Remarkable Notes for JSF Apps Using HTML5

In the previous post , I've already shared with you how my team consults clients by using a HTML prototype. This post is about the used technologies for reusing the provided HTML template and communicating with backend. What is the issue when using HTML elements with Primefaces components? Primefaces is a great extension for developing JSF web apps. However, it is really frustrating in case we have to make it work with an existing HTML template. Why? - Primefaces has its own theme for styling. - Primefaces changes the HTML structure. Therefore, that would be a huge effort to use the Primefaces' components to replicate the elements of the HTML template; especially it is impossible for images drawing by " canvas " tag. That requires us to find a better approach. Since Java EE 7 (introducing JSF 2.2 included), it supports to use HTML5 elements . The idea is that JSF components don't effect the style and HTML structure, so we can easily reuse the provided HTM...

Coding Exercise, Episode 1

I have received the following exercise from an interviewer, he didn't give the name of the problem. Honestly, I have no idea how to solve this problem even I have tried to read it three times before. Since I used to be a person who always tells myself "I am not the one good at algorithms", but giving up something too soon which I feel that I didn't spend enough effort to overcome is not my way. Then, I have sticked on it for 24 hours. According to the given image on the problem, I tried to get more clues by searching. Thanks to Google, I found a similar problem on Hackerrank (attached link below). My target here was trying my best to just understand the problem and was trying to solve it accordingly by the Editorial on Hackerrank. Due to this circumstance, it turns me to love solving algorithms from now on (laugh). Check it out! Problem You are given a very organized square of size N (1-based index) and a list of S commands The i th command will follow t...

Styling Sort Icons Using Font Awesome for Primefaces' Data Table

So far, Primefaces has used image sprites for displaying the sort icons. This leads to a problem if we want to make a different style for these icons; for example, I would make the icon "arrow up" more blurry at the first time the table loading because I want to highlight the icon "arrow down". I found a way that I can replace these icons with Font Awesome icons. We will use "CSS Pseudo-classes" to achieve it. The hardest thing here is that we should handle displaying icons in different cases. There is a case both "arrow up" and "arrow down" showing and other case is only one of these icons is shown. .ui-sortable-column-icon.ui-icon.ui-icon-carat-2-n-s { background-image: none; margin-left: 5px; font-size: 1.1666em; position: relative; } .ui-sortable-column-icon.ui-icon.ui-icon-carat-2-n-s:not(.ui-icon-triangle-1-s)::before { content: "\f106"; font-family: "FontAwesome"; position: ...

Junit - Test fails on French or German string assertion

In my previous post about building a regex to check a text without special characters but allow German and French . I met a problem that the unit test works fine on my machine using Eclipse, but it was fail when running on Jenkins' build job. Here is my test: @Test public void shouldAllowFrenchAndGermanCharacters(){ String source = "ÄäÖöÜüß áÁàÀâÂéÉèÈêÊîÎçÇ"; assertFalse(SpecialCharactersUtils.isExistSpecialCharater(source)); } Production code: public static boolean isExistNotAllowedCharacters(String source){ Pattern regex = Pattern.compile("^[a-zA-Z_0-9_ÄäÖöÜüß áÁàÀâÂéÉèÈêÊîÎçÇ]*$"); Matcher matcher = regex.matcher(source); return !matcher.matches(); } The result likes the following: Failed tests: SpecialCharactersUtilsTest.shouldAllowFrenchAndGermanCharacters:32 null A guy from stackoverflow.com says: "This is probably due to the default encoding used for your Java source files. The ö in the string literal in the J...