logo
Home j4j Tag LIbrary

Default Action for a JSF Form


Description

The current JSF-RI implementation does not allow to you to define the default action in case the user submits the form by pressing the Enter key instead of clicking the action button explicitly. As a result, the form action becomes undefined and the current page is just reloaded. Developers have to write additional javascript code to prevent such undesirable behavior.

The j4j:defaultAction custom component included in the j4j tag libraries allows you to define the default action for a form by adding <j4j:defaultAction /> as a child tag to the commandButton tag.

PS: This component was writen before even first version fo Firefox is released. This is a code that works also in FireFox. function trapEnter(evt) { var keycode; if (evt) ; else if (window.event) evt = window.event; else if (event) evt = event; else return true; if (evt.charCode) keycode = evt.charCode; else if (evt.keyCode) keycode = evt.keyCode; else if (evt.which) keycode = evt.which; else keycode = 0; if (keycode == 13) { document.getElementById('form:save').click(); return false; } else return true; }

How to Download

Download the compiled code using this URL: j4j.jar (4 K)

How to Use

1. Put the j4j.jar file in the WEB-INF/lib folder of your project.

2. Add the following declaration at the top of the page:

<%@ taglib uri="http://javascript4jsf.dev.java.net/" prefix="j4j" %>

3. Add the j4j:defaultAction component as an empty child element of the commandButton that you want to make a default button. For example:

<h:commandButton id="submit" action="sayhello" value="Say Hello" >
	<j4j:defaultAction />
</h:commandButton>

Source Code

Here is the part of the library structure in j4j.jar that relates to this component:

The boldfaced code shows how to insert a reference to the proxy component in the faces-config.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
                              "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config>
 <component>
   <!-- 
  other components declarations
   -->
 <component>
  <component-type>org.j4j.defaultAction</component-type>
  <component-class>org.j4j.components.UIDefaultAction</component-class>
 </component>
 <lifecycle/>
 <application>
  <locale-config/>
 </application>
 <factory/>
</faces-config>

Here is the content of the j4j.tld file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
                        "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
 <tlib-version>0.3</tlib-version>
 <jsp-version>1.2</jsp-version>
 <short-name>j2j</short-name>
 <uri>http://javascript4jsf.dev.java.net/</uri>
   <!-- 
  other tags declarations
   -->
 <tag>
  <name>defaultAction</name>
  <tag-class>org.j4j.tags.DefaultActionTag</tag-class>
  <attribute>
   <name>id</name>
  </attribute>
  <attribute>
   <name>required</name>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
 </tag>
</taglib>

Here is the source code for the org.j4j.tags.DefaultActionTag class:

/*
 * Created on 09.08.2004
 *
 */
package org.j4j.tags;

import javax.faces.webapp.UIComponentTag;

/**
 * @author sim
 *
 */
public class DefaultActionTag extends UIComponentTag {
	public String getComponentType() {
		return "org.j4j.defaultAction";
	}

	public String getRendererType() {
		return null;
	}
	
}

Here is the source code for the org.j4j.tags.UIDefaultAction class:

/*
 * Created on 09.08.2004
 *
 */
package org.j4j.components;

import java.io.IOException;

import javax.faces.component.UIOutput;
import javax.faces.component.UIForm;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.component.UIComponent;

/**
 * @author sim
 *
 */
public class UIDefaultAction extends UIOutput {
	
	
public void encodeBegin(FacesContext context) throws IOException {
	return;
}
	public void decode(FacesContext context) {
	return;
}
public void encodeEnd(FacesContext context) throws IOException {
	ResponseWriter writer = context.getResponseWriter();
	UIComponent actionComponent=super.getParent();
	String acId = actionComponent.getClientId(context); 
	UIForm form= getForm(actionComponent);
	if (form != null) {
			
		String formId = form.getClientId(context);

		writer.startElement("script", null);
		String functionBody = 
		   "{var keycode;" + 
		   "if (window.event) keycode = window.event.keyCode;" +
		   "else if (event) keycode = event.which;" +
		   "else return true;" + 
		   "if (keycode == 13) { " +
		   "document.getElementById('"+acId+"').click();return false; } " +
		   "else  return true; }";

		String functionCode = 
		   "document.forms['"+formId+"'].onkeypress ="+
		   "new Function(\""+ functionBody+"\");"; 
		writer.write(functionCode);
			
		writer.endElement("script");
	}
}
	
   private UIForm getForm(UIComponent component) {
       while (component != null) {
          if (component instanceof UIForm) {
               break;
           }
           component = component.getParent();
       }
       return (UIForm) component;
   }

	
}

Example

Exadel JSF Studio (Eclipse) project URL: j4j-testApp.zip (1.68M)

Ready-to-deploy war file URL: j4j-testApp.war(1.68M)

JSP File

Here is the content for the inputname.jsp page using the component inside the example:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://javascript4jsf.dev.java.net/" prefix="j4j" %>
<f:loadBundle basename="demo.bundle.Messages" var="Message"/>

<HTML>
  <HEAD> 
    <title>Input Name Page</title> 
  </HEAD>
  <body bgcolor="white">
    <f:view>
	<f:subview id="sv">
      <h1>
        <h:outputText value="#{Message.inputname_header}"/>
      </h1>
      <h:messages style="color: red"/>
      <h:form id="helloForm">
        <h:panelGrid columns="2">
          
          <h:outputText value="#{Message.id_promt}"/>
          <h:inputText id="id" value="#{GetNameBean.id}"/>
    	  
    	  	
          <h:outputText value="#{Message.fn_prompt}"/>
          <h:inputText id="firstName" value="#{GetNameBean.firstName}" required="true">
            <j4j:idProxy id="firstName_" />
            <f:validateLength minimum="2" maximum="20"/>
          </h:inputText>

          <h:outputText value="#{Message.ln_prompt}"/>
          <h:inputText id="lastName" value="#{GetNameBean.lastName}"/>

        </h:panelGrid>
        <h:commandButton id="submit" action="sayhello" value="Say Hello" >
        	<j4j:defaultAction />
        </h:commandButton>
        
      </h:form>
      </f:subview>
    </f:view>
  </body>
  <script language="javascript">
     var iid=document.getElementById("firstName_").title;
     document.getElementById(iid).focus();
  </script>
</HTML>  

Here is the rendered result:

<HTML>
  <HEAD> 
    <title>Input Name Page</title> 
  </HEAD>
  <body bgcolor="white">
    
	
      <h1>
        Set Focus Application
      </h1>
      
      <form id="sv:helloForm" 
	   method="post" action="/j4j-testApp/pages/inputname.jsf;jsessionid=[skipped]"
	   enctype="application/x-www-form-urlencoded">
        <table>
<tbody>
<tr>
<td>Id:</td>
<td><input id="sv:helloForm:id" type="text" name="sv:helloForm:id" value="1" /></td>
</tr>
<tr>
<td>First Name:</td>
<td><span id="firstName_" 
title="sv:helloForm:firstName">
</span><input id="sv:helloForm:firstName" 
type="text" 
name="sv:helloForm:firstName" 
value="" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input id="sv:helloForm:lastName" type="text" name="sv:helloForm:lastName" value="" /></td>
</tr>
</tbody>
</table>

        <input id="sv:helloForm:submit" type="submit"
		 name="sv:helloForm:submit" 
		 value="Say Hello" />
        	<script>document.forms['sv:helloForm'].
			onkeypress =new Function(
			"{var keycode;if (window.event)
			keycode = window.event.keyCode;
			else if (event) keycode = event.which;
			else return true;
			if (keycode == 13)
			 { document.getElementById('sv:helloForm:submit').click();
			 return false; }
			else  return true; }");</script>
        
        
      <input type="hidden" name="sv:helloForm" value="sv:helloForm" /></form>
      
    
  </body>
  <script language="javascript">
     var iid=document.getElementById("firstName_").title;
     document.getElementById(iid).focus();
  </script>
</HTML>  
See Also:

j4j:param - Form Parameter Tag


This tag allows to define and pass parameters to the next page.

Proxy Id for a JSF Custom Component


This tag allows you to get the dynamic id for any of the other JSF components.