DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Coding
  3. Frameworks
  4. Jsf 2.0 ClientId with jQuery

Jsf 2.0 ClientId with jQuery

Robert Piesnikowski user avatar by
Robert Piesnikowski
·
Feb. 23, 11 · Interview
Like (0)
Save
Tweet
Share
35.21K Views

Join the DZone community and get the full member experience.

Join For Free

 In this article I will show how to work with the clientId property of UIComponent, which has been improved in JavaServer Faces 2.0, about finding concrete id from client side and how to use this knowledge with jQuery library. We will examine Composite Components, Facelets Composition , Facelets Templating and UIComponents with NamingContainer (for example UIData).

Pre-requirements 

In this article I used NetBeans 6.9 IDE, Mojarra 2.0.2 (FCS b10) as JSF 2.0 implementation and GlassFish 3.0.1.

Hello ClientId

 In this step we will create our first simple web application with only one page.

 1.From the NetBeans wizard choose Java Web -> Web application ->ClientIdExampleApp -> Select EE 6 Web and Glassfish 3 -> Select JavaServer Faces Framework (with Facelets View ) and click finish. 

Receiving ClientId from new JSF 2.0 ${component} EL Expression

<h:form id="form1" prependId="true">
${component.clientId}
<h:commandButton id="btn1" value="${component.clientId}" />
${component.clientId}
<h:panelGroup id="panel1" layout="block">
${component.clientId}
</h:panelGroup>
</h:form> 

 That code should produce something like that:

<form enctype="application/x-www-form-urlencoded" action="/WebApplication1/faces/index.xhtml" method="post" name="form1" id="form1">
(1)form1
<input type="submit" (2)value="form1:btn1" name="form1:btn1" id="form1:btn1">
(3)form1
<div id="form1:panel1">
(4)form1:panel1
</div>
</form>

 Although this example is really easy to code we can see that:

${component.clientId} returns the "nearest" parent UIComponent. Points (2) and (4) resolved clientId properly while (1) and (3) resolved clientId of parent: UIForm . If we need to create javascript function this solution is really quick and good enought. On the other hand when we need to have cross page javascript id reference better aproach is to use binding attributes.

Receiving ClientId from binding attributes of UIComponents

 The second way is more complicated but is more effective in various cases. Two steps are needed to get the clientId by binding. First we need to add binding attribute and connect this attribute with Managed Bean property corresponding to the particular UIComponent subclasses.

 Simple form:

<h:form id="form1" prependId="true" binding="(1)${index.form1}" style="background-color: red">
ClientId: (2)${index.form1.clientId}<br />
Simple attribute of form1: (3)${index.form1.attributes["style"]}<br />
<h:commandButton id="btn1" value="(4)#{index.form1.findComponent('btn1').clientId} :-)" />

<h:panelGroup id="panel1" layout="block">
(5)${component.clientId} <br />
</h:panelGroup><br />
panel1 clientId: (6)#{index.form1.findComponent("panel1").clientId} <br />
panel1 layout attribute (7)#{index.form1.findComponent("panel1").attributes["layout"]}
</h:form>
  Java managed bean code:
@ManagedBean
@RequestScoped
public class index {

private UIForm form1;

public UIForm getForm1() {
return form1;
}

public void setForm1(UIForm form1) {
this.form1 = form1;
}

public index() {
}
}
 Rendered html:
<form style="background-color: red;" enctype="application/x-www-form-urlencoded" action="/WebApplication1/faces/index.xhtml;jsessionid=64e609789a8d90f6993151f964d4" method="post" name="form1" id="form1">
ClientId: form1<br>
Simple attribute of form1: background-color: red<br /><input type="submit" value="form1:btn1 :-)" name="form1:btn1" id="form1:btn1"><div id="form1:panel1">
form1:panel1 <br /></div><br />
panel1 clientId: form1: panel1 <br />
panel1 layout attribute: block
</form>

 Short clarification

 In points: (1),(2),(3) and (5) we used a dollar sign $ to access the properties (form1 and component) of the managed bean. In (4),(7),(6) we used the hash sign # to refer UIComponent methods like findComponent to find child component and uses panel1 properties. 

ClientId with NamingContainer

Now I will add some examples of my web application and explain how does it all work. Let start with h:dataTable with few rows and two columns. The second column will contain a h:commandButton and we want use this button to do some client Javascript action.

 Here is a simple datatable:

<h:dataTable id="dt1" binding="${clientIdExample.dt1}" value="#{clientIdExample.localeList}" var="item"
dir="LTR" frame="hsides" rules="all" summary="This is a JSF code to create dataTable." >

<f:facet name="header">
<h:outputText value="This is 'dataTable' demo" />
</f:facet>
<h:column id="col1">
${component.clientId}
<f:facet name="header">
<h:outputText value="name"/>
</f:facet>
<h:outputText value="#{item.displayName}" style="margin:5px; padding:5px"></h:outputText>
</h:column>
<h:column id="col2">
<f:facet name="header">
<h:outputText value="click"/>
</f:facet>
<h:commandButton id="editRow" value="click" onclick="toggleRow('${component.clientId}');return false;"
style="margin:5px; padding:5px"/>
</h:column>
<f:facet name="footer">
<h:outputText value="The End" />
</f:facet>
</h:dataTable>
And of course our ManagedBean:
@Named(value = "clientIdExample")
@RequestScoped
public class ClientIdExample {
private Locale[] localeList;
private HtmlDataTable dt1;

public Locale[] getLocaleList() {
Locale[] tmp = Locale.getAvailableLocales();
localeList = new Locale[5];
for (int i=0;i< localeList.length;i++){
localeList[i] = tmp[i];
}

return localeList;
}

public void setLocaleList(Locale[] localeList) {
this.localeList = localeList;
}

public HtmlDataTable getDt1() {
return dt1;
}

public void setDt1(HtmlDataTable dt1) {
this.dt1 = dt1;
}

public ClientIdExample() {
}
}

And generated HTML should look like:

    <table rules="all" frame="hsides" summary="This is a JSF code to create dataTable." dir="LTR" id="form1-dt1">
<thead>
<tr><th scope="colgroup" colspan="2">This is 'dataTable' demo</th></tr>
<tr>
<th scope="col">name</th>
<th scope="col">click</th>
</tr>
</thead>
<tfoot>
<tr><td colspan="2">The End</td></tr>
</tfoot>
<tbody>
<tr class="">
<td>
form1-dt1-0
<span style="margin: 5px; padding: 5px;">japoński (Japonia)</span></td>
<td><input type="submit" style="margin: 5px; padding: 5px;" value="click" name="form1-dt1-0-editRow" id="form1-dt1-0-editRow"></td>
</tr>
<tr class="">
<td>
form1-dt1-1
<span style="margin: 5px; padding: 5px;">hiszpański (Peru)</span></td>
<td><input type="submit" style="margin: 5px; padding: 5px;" value="click" name="form1-dt1-1-editRow" id="form1-dt1-1-editRow"></td>
</tr>
<tr class="">
<td>
form1-dt1-2
<span style="margin: 5px; padding: 5px;">angielski</span></td>
<td><input type="submit" style="margin: 5px; padding: 5px;" value="click" name="form1-dt1-2-editRow" id="form1-dt1-2-editRow"></td>
</tr>
<tr class="">
<td>
form1-dt1-3
<span style="margin: 5px; padding: 5px;">japoński (Japonia,JP)</span></td>
<td><input type="submit" style="margin: 5px; padding: 5px;" value="click" name="form1-dt1-3-editRow" id="form1-dt1-3-editRow"></td>
</tr>
<tr>
<td>
form1-dt1-4
<span style="margin: 5px; padding: 5px;">hiszpański (Panama)</span></td>
<td><input type="submit" style="margin: 5px; padding: 5px;" value="click" name="form1-dt1-4-editRow" id="form1-dt1-4-editRow"></td>
</tr>
</tbody>
</table>

 Now I will present 3 ways to highlight entire row with click event. Those functions are simple so they don't need an explanation.

1)
function toggleRow(clientId)
{
$('#'+clientId).closest('tr').toggleClass("selectedRow");
}
2)
$(document).ready(function(){
$('input[id$=editRow]').click(function(){
$(this).closest('tr').toggleClass("selectedRow");
return false;
});
});
3)
$(document).ready(function(){
$('#${clientIdExample.dt1.clientId} tr td > input').click(function(){
$(this).closest('tr').toggleClass("selectedRow");
return false;
});
});

 Working with jQuery and JSF 2.0(javax.faces.SEPARATOR_CHAR)

Generally when you use the JSF framework and look inside the HTML output you will find that clientId is separated by a colon sign ":". Unfortunately this sign is not allowed when you use the jQuery library because it is reserved for jQuery selectors. JavaServer Faces 2.0 comes with a parameter: javax.faces.SEPARATOR_CHAR. In this case you should change default separator to another one which is accepted by jQuery. For example (web.xml):

    <context-param>
<param-name>javax.faces.SEPARATOR_CHAR</param-name>
<param-value>-</param-value>
</context-param>

Call Ajax across Facelets Template and Clients 

In this example I will show how to call Ajax to update UIComponent in Template.xhtml from AjaxEngine.xhtml(Facelets Client). We will use the Javascript function jsf.ajax.request instead of f:ajax and we will use the clientId property of UIControl. 

If we want to use Javascript jsf.ajax.request in pure form we need to load appropriate client script

<h:outputScript name="jsf.js" library="javax.faces" target="head" />

This will generate something like this:

<script src="/PrimeFacesLearning/javax.faces.resource/jsf.js.jsf?ln=javax.faces&amp;stage=Development" type="text/javascript"></script>

Template.xhtml: 

<h:body>
<f:view contentType="text/html" locale="pl_PL">
<h:form id="form1" prependId="true" binding="#{template.form1}">
<ui:debug id="debug1" rendered="true" hotkey="l">
</ui:debug>
<div id="container">
<div id="header"></div>
<div id="center-column">
<div id="left-column">
<h:outputText id="ajaxText" binding="#{template.ajaxText}" value="${ajaxEngine.firstname}" />
</div>
<br />
<p:panel id="right-column" styleClass="right-column" toggleable="true" closable="true">
<ui:insert name="right-column" >
</ui:insert>
</p:panel>
</div>
</div>
</h:form>
</f:view>
</h:body>

 DummyAjax.xhtml

<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./resources/layout/Template.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:sc="http://java.sun.com/jsf/composite/Controls">

<ui:define name="right-column">
<h1> f:ajax example using Facelets Templating</h1>
<h:outputScript name="jsf.js" library="javax.faces" target="head" />
<script src="/PrimeFacesLearning/javax.faces.resource/jsf.js.jsf?ln=javax.faces&amp;stage=Development" type="text/javascript"></script>
<h:panelGrid id="panelGrid1">
<h:inputText value="#{ajaxEngine.firstname}" onkeyup="jsf.ajax.request(this, event,{render:'form1-text ${template.ajaxText.clientId} form1-count'}); return false">
</h:inputText>
<h:outputText id="text" value="#{ajaxEngine.firstname}" escape="false"/>
<br />
Firstname char count: <h:outputText id="count" value="#{ajaxEngine.count}" />
</h:panelGrid>
</ui:define>
</ui:composition>
    /**
* This code will be automatically called when jsf.ajax.request will
* be populated from client side.
* Here we also set another property of DummyAjax - Integer count
* to manipulate other variables in managed bean.
* @param firstname
*/
public void setFirstname(String firstname) {
this.firstname = firstname;
setCount(getFirstname().length());
}

In the code above we have two pages. Template.xhml and DummyAjax.xhtml as facelets template client. In template we have <h:outputText id="ajaxText" binding="#{template.ajaxText}" value="${ajaxEngine.firstname}" /> and in DummyAjax.xhtml we have

 <h:inputText id="input1" value="#{ajaxEngine.firstname}" />  
<h:outputText id="text" value="#{ajaxEngine.firstname}" escape="false"/>

All those three controls refers to one managed bean property: #{ajaxEngine.firstname}. The next interesting thing is calling Ajax on each keyup.

onkeyup="jsf.ajax.request(this, event,{render:'form1-text 
${template.ajaxText.clientId} form1-count'}); return false"

Method expression for getting clientId of each UIComponent:
form1-text #{template.form1.findComponent("panelGrid1").findComponent("text").clientId}
form1-input1 #{template.form1.findComponent("panelGrid1").findComponent("input1").clientId}
form1-count #{template.form1.findComponent("panelGrid1").findComponent("form1-count").clientId}

And in the end last thing is really usefull which is body of method setFirstName(String firstname) where we have a chance to update as many properties as we want.

JavaServer Faces 2.0 Control Composition

I wouldn't dwell on ${cc.attr.id} just because this works just the same as all content in article.
Short example:

<?xml version='1.0' encoding='UTF-8' ?>
<!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:p="http://primefaces.prime.com.tr/ui"
xmlns:cc="http://java.sun.com/jsf/composite">

<!-- NO INTERFACE -->
<cc:interface>
</cc:interface>

<!-- IMPLEMENTATION -->
<cc:implementation>
${cc.attrs.id},${cc.clientId} <br />
</cc:implementation>
</html>

<h:form id="form1" prependId="true">
<sc:Dummy id="dummy1" /><br />
<sc:Dummy id="dummy2" />
</hform>

<!--browser output-->
dummy1, form1-dummy1 <br />
dummy2,form1-dummy2

Article Summary

This article should give you understanding of how to get clientId with diffrent scenarios. You should also know how to use JSF 2.0 with jQuery and you have learned how to call Ajax without the f:ajax tag. You can download the source code from table below.

 Useful links

Expression Language Official reference to Java 6 EL.
Composite Components example. Simple but usefull example of how to use CC.
jsf.ajax.* javadoc Full reference to jsf.js library.
jsf ajax example Example with f:actionListener and jsf.ajax.request(...)
FireBug This is one of the best tools for browsing client html, debugging Javascript and watching real Ajax requests.
PrimeFaces My favourite jsf tag library. Uses jQuery as it's Javascript engine. Many great controls and of course open source.
First, second gool article Those article show details about JSF clientId properties.
jQuery This library simplifies a developers life.
Subversion repository of code. Simple NetBeans project where I learn JSF 2.0
JQuery Web application JavaServer Faces Property (programming)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Use AWS Controllers for Kubernetes To Deploy a Serverless Data Processing Solution With SQS, Lambda, and DynamoDB
  • ClickHouse: A Blazingly Fast DBMS With Full SQL Join Support
  • Introduction to NoSQL Database
  • Java REST API Frameworks

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: