logo
Home j4j Tag LIbrary

Proxy Id for a JSF Custom Component


Description

The JavaServerTM Faces custom components have a dynamic id. This can create problems when trying to access these components from JavaScript code on the client side. This tiny library contains a custom component that allows you to get the dynamic id for any of the other JSF components.

The component name is j4j:idProxy. It has only one mandatory id attribute. The component is rendered as a <span> HTML tag that has two attributes. The first attribute named Id has the same value as the id attribute of this component. The second attribute named title contains the clientId of the parent component. Because id is static, it makes it possible to easily reach this component from the browser DOM tree and then get a the dynamic ID for the desired JSF component.

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:idProxy component as a child of the actual JSF component that you want to reach. For example:

<h:inputText id="firstName" value="#{GetNameBean.firstName}">
	<j4j:idProxy id="firstName_" />
</h:inputText>
<h:commandButton id="submit" action="sayhello" value="Say Hello">
	<j4j:idProxy id="submitId" />
</h:commandButton>

4. Use document.getElementById() within the client-side JavaScript to get a reference to the proxy component. Then use its title attribute to get the value of the dynamic id you want. For example, to set a focus to the inputText component shown in the snippet above use:

    <script language="javascript">
    	var iid=document.getElementById("firstName_").title;
    	document.getElementById(iid).focus();
    </script>

Source Code

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

Here is the content of faces-config.xml referencing the proxy component:

<?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>
  <component-type>org.j4j.idProxy</component-type>
  <component-class>org.j4j.components.UIIDProxy</component-class>
 </component>
  <!--
 .....
 other components desclarations
 .....
 -->
 <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>j4j</short-name>
 <uri>http://javascript4jsf.dev.java.net/</uri>
 <tag>
  <name>idProxy</name>
  <tag-class>org.j4j.tags.IDProxyTag</tag-class>
  <body-content>empty</body-content>
  <attribute>
   <name>id</name>
   <required>true</required>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
 </tag>
 <!--
 .....
 other tags desclarations
 .....
 -->
</taglib>

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

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

import javax.faces.webapp.UIComponentTag;

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

	public String getRendererType() {
		return null;
	}
	
}

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

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

import java.io.IOException;

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

/**
 * @author sim
 *
 */
public class UIIDProxy 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();
		writer.startElement("span", null);
		UIComponent parent=super.getParent();
		String componentID=parent.getClientId(context);
		String id = (String)getAttributes().get("id");
		writer.writeAttribute("id", id, "id");
		writer.writeAttribute("title", componentID, "id");
		writer.flush();
		writer.endElement("span");
	}
	
}

Example

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

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

Here is the content for inputname.jsp page from 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>

      <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" />
      </h:form>
    </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="helloForm" method="post" action="/j4j-proxy/pages/inputname.jsf;jsessionid=[skipped]"
		 enctype="application/x-www-form-urlencoded">
    		<table>
<tbody>
<tr>
<td>Id:</td>
<td><input id="helloForm:id" type="text" name="helloForm:id" value="1" /></td>
</tr>
<tr>
<td>First Name:</td>
<td><span id="firstName_" title="helloForm:firstName"></span><input 
	id="helloForm:firstName" type="text" name="helloForm:firstName" value="" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input id="helloForm:lastName" type="text" name="helloForm:lastName" value="" /></td>
</tr>
</tbody>
</table>

	<input id="helloForm:submit" type="submit" name="helloForm:submit" value="Say Hello" />
    	<input type="hidden" name="helloForm" value="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 component allows to define and pass parameters to the next page.

j4j:defaultAction - Default Action for a JSF Form


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