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

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: ...

Selenium - Override javascript functions to ignore downloading process

I have got an issue with downloading process on IE 8. This browser blocks my automatic-download functionality on my app so that I could not work with my test case any more after that. In my case, I didn't care about the file is downloaded or not, I just focus on the result after downloading process finished successfully. Therefore, I found a solution to ignore this process so that I can work normally. I use Primefaces, here is the remote command to trigger the download process <p:remoteCommand name="cmdGenerateDocument" actionListener="#{logic.onGenerateDocument}" update="xrflDocumentCreationPanel" oncomplete="clickDownloadButton();"/> The following is my test case: @Test public void shouldUpdateStep6ToWarningIfStep1IsValidAfterFinished(){ MainPage mainPage = new MainPage(); waitForLoading(mainPage.getDriver()); EmployeeDetailPage empDetailPage = new EmployeeDetailPage(); waitForLoading(empDetailPage.getDriver()); e...

Only allow input number value with autoNumeric.js

autoNumeric is a jQuery plugin that automatically formats currency and numbers as you type on form inputs. I used autoNumeric 1.9.21 for demo code. 1. Dowload autoNumeric.js file from  https://github.com/BobKnothe/autoNumeric 2. Import to project <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script type="text/javascript" src="js/autoNumeric.js"></script> 3. Define a function to use it <script type="text/javascript"> /* only number is accepted */ function txtNumberOnly_Mask() { var inputOrgNumber = $("#numberTxt"); inputOrgNumber.each(function() { $(this).autoNumeric({ aSep : '', aDec: '.', vMin : '0.00' }); }); } </script> 4. Call the function by event <form> <input type="text" value="" id="numberTxt"/>(only number) </form> <script ty...

DevOps for Dummies

Everyone talks about it, but not everyone knows what it is. Why DevOps? In general, whenever an organization adopts any new technology, methodology, or approach, that adoption has to be driven by a business need. Any kind of system that need rapid delivery of innovation requires DevOps (development and operations). Why? DevOps requires mechanisms to get fast feedback from all the stakeholders in the software application that's being delivered. DevOps approaches to reduce waste and rework and to shift resources to higher-value activities. DevOps aims to deliver value (of organization or project) faster and more efficiently. DevOps Capabilities The capabilities that make up DevOps are a broad set that span the software delivery life cycle. The following picture is a reference architecture which provides a template of a proven solution by using a set of preferred methods and capabilities. My Remarks Okay, that sounds cool. What does it simply mean, again? The f...

My must-have apps for daily work

There is no doubt that cool apps can help us be more productive and enjoyable at work. For the time being, I really love the following apps which are used by me almost every day. 1. A personal Kanban In fact, a personal kanban is the most useful app for me. Why does it matter? It is not just a to-do list, but it keeps me motivated every day because it helps me be able to know what my "big picture" is. I usually set up my plans together with a path to reach them.  KanbanFlow  is my preferred tool. KanbanFlow 2. A terminal Needless to say, a terminal is a must-have app for every developer, especially the ones use macOS/Linux. Due to its importance, I love to decorate and enhance it to be super exciting with various tools such as  iTerm ,  oh-my- zsh , and  thefuck . ;) iTerm + oh-my-zsh 3. A documentation "ecosystem" As a developer, I can not remember all things that I have experimented a day. Moreover, a document is really useful for sharing an...