Latest Entries »

Saturday, April 9, 2011

SelectedIndexChanged doesn't fire with autopostback true in ASP.NET in List Control

Rarely when developing application in ASP.NET you stuck on any ListControl and AutoPostBack="true" and SelectedIndexChanged won't trigger. Even when server receive postback your control don't response at all.

Today I will show and explain the problem: duplicate values inside ListItem.

RatioButtonList example

Now let imagine we have that piece of code:



        protected void rblShippingMethods_IndexChanged(object sender, EventArgs e)
        {
            //This action is always performed when user change item in RadioButtonList Control
            do_rblShippingMethods_IndexChanged();
        }

Let imagine that our datasource produce something like that. In this scenario we have shipping method as text and shipping method price as value for RadioButtonList :

        
        
        


Nothing complicated and this will work almost everytime.

houston we have a problem!


But when we have ListControl with Binding from any datasource it may happen that one or more ListItem can have the same value.When that situation happen rblShippingMethods_IndexChanged won't trigger.



        
        
        
        
        



I'm really confused when I wrote a solution for this case because event is connected with Index not Value inside ListControl. But nothing is perfect.

Don't panic!

What to do when two or more ListItem have the same value? Maybe ask end user to put diffrent values in user form! Oh no really it's dummy thought! We make our users happy and everything will work as always.

First thing we need to observe is fact the PostBack is send to server. Breakpoint was hit. But not the SelectedIndexChanged.

Think, think, think... BINGO

So when we found that server receive request we have to find which control causes the postback to our server. We can do it with
//Return full ClientID of postback source. So we can find the name of control and index
//For example:
//control = ctl00$MainContent$wizSubmitOrder$rblShippingMethods$0
//control = ctl00$MainContent$wizSubmitOrder$rblShippingMethods$1
//control = ctl00$MainContent$wizSubmitOrder$rblShippingMethods$2
String control = Request["__EVENTTARGET"];
We can see that only last part after $ sign is changing. That is our SelectedIndex!
So we can put this piece of code inside Page_Load:
if (Page.IsPostBack)
{
    rblShippingMethods_CustomMethodIndexChanged();
}
protected void rblShippingMethods_CustomMethodIndexChanged()
{
    String control = Request["__EVENTTARGET"];
    String args = Request["__EVENTARGUMENT"];
    if (control != null)
    {
        if (control.Contains("rblShippingMethods"))
        {
            String selectedIndex = control.Substring(control.LastIndexOf("$") + 1);
            int si = 0;
            if (int.TryParse(selectedIndex, out si))
            {
                //We manually chage selectedIndex and then we call
                //the same method when normally rblShippingMethods_IndexChanged event
                //would occur
                rblShippingMethods.SelectedIndex = si;
                do_rblShippingMethods_IndexChanged();
            }
        }
    }
}

Tuesday, April 5, 2011

java insert and read image from mysql

Sometimes it may happen that we need to store a picture in some database table (MYSQL). At the beginning you should to create a table that will store our image data. Pictures and other binary files is kept in a BLOB data type inside table column. For this purpose we need to crate table.

CREATE TABLE IF NOT EXISTS `Images` (
  `ImageId` int(11) NOT NULL AUTO_INCREMENT,
  `Description` varchar(150) COLLATE utf8_polish_ci NOT NULL DEFAULT '-',
  `ImageData` blob NOT NULL,
  PRIMARY KEY (`ImageId`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci

And now to manipulate the database we use two methods:

    //Insert Image
    public void InsertImage(String description,FileInputStream fotos);
    //read image from table with specific id
    public  BufferedImage getMySqlPhoto(int ImageId);

public  BufferedImage getMySqlPhoto(int ImageId){
        BufferedImage BI = null;
        Statement S;
        ResultSet rs;
        String sqlStatement = "SELECT ImageData FROM Images WHERE ImageId = '"+ImageId+"'";
        try {
            S = con.createStatement();
            rs = S.executeQuery(sqlStatement);
            if (rs.next()){
                Blob image = rs.getBlob("ImageData");
                InputStream input = image.getBinaryStream();
                BI=ImageIO.read(input);
                // set read buffer size
                input.close();
            }
        }
        catch (SQLException ex)
        {
            ex.printStackTrace();
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
        return BI;
    }
    public void InsertIntoZdjecie(String Description,FileInputStream fotos)
    {
        String INSERT = "INSERT INTO Images(Description,ImageData) VALUES (?,?)";
        System.out.println(INSERT);
        PreparedStatement ps1;

        try {
            ps1 = con.prepareStatement(INSERT);
            ps1.setString(1, Description);
            ps1.setBinaryStream(2, fotos);
            ps1.executeUpdate();
        } catch (SQLException ex) {
            ex.printStackTrace();
            
        }
    }

Isn't it cute ? :-)

Wednesday, March 23, 2011

Android Candlestick Chart with Google Chart API

Good morning. Today I would like to share with other how to create CandleStick Chart with little support of Google Chart API.

Browsing around the web I hadn't found any good open source library for charting in android which directly support Candlestick Chart so I decided to use online solution based on HTTP GET/POST.

So let's start our sourvey.

First we need to take a look closer to Google Chart API. For this tutorial I will use simple basic text format to put series data inside HTTP GET request to get image I want to.
There is one thing which sadden me.
Basic text-formatted data lets you specify floating point values from 0—100, inclusive, as numbers. Values below zero are marked as missing; values above 100 are truncated to 100.

Preparing Chart Data

In most cases our data is larger than 100 and it would be stupid to have truncated all data. For this reason we need to do some scaling. Scaling will make all data suitable for requirements.
/**
     * This method transform any Double[] series to suitable series accepted by
     * Google Chart API
     */
    public static ArrayList<integer[]> transformChartSeries(ArrayList<double[]> input) {
        ArrayList<integer[]> scaledInput = new ArrayList<integer[]>();
        //Getting scale between minimum and maximum value from input series
        double scaleRatio = getScaleRatio(Min(input), Max(input));
        for (int i = 0; i &lt; input.size(); i++) {
            scaledInput.add(scale(input.get(i), scaleRatio));
            displayArray(scaledInput.get(i));
        }
        return scaledInput;
    }

    private static double Max(ArrayList<double[]> arr) {
        ArrayList<double> tmp = new ArrayList<double>();
        for (int i = 0; i &lt; arr.size(); i++) {
            tmp.add(Max(arr.get(i)));
        }
        return Collections.max(tmp);
    }

    private static double Max(Double[] input) {
        return Collections.max(Arrays.asList(input));
    }

    private static double Min(ArrayList<double[]> arr) {
        ArrayList<double> tmp = new ArrayList<double>();
        for (int i = 0; i &lt; arr.size(); i++) {
            tmp.add(Min(arr.get(i)));
        }
        return Collections.min(tmp);
    }

    private static double Min(Double[] input) {
        return Collections.min(Arrays.asList(input));
    }

    private static double getScaleRatio(double min, double max) {
        double ratio = 0;
        //Dividing value. You can manipulate this parameter to get 
        //smaller or bigger chart.
        int div = 80;
        ratio = (max - min) / div;
        return ratio;
    }
    private static Integer[] scale(Double[] input, double ratio) {
        Integer[] scaledData = new Integer[input.length];
        for (int i = 0; i &lt; input.length; i++) {
            scaledData[i] = new Integer((int) Math.round(input[i] / ratio));
        }
        return scaledData;
    }

Preparing Chart

Now when we finished data transformation we can create CandleStick Chart with Google Chart API :-) We will use cht=lc (Line Chart) as scaffolding for CandleStick Chart. Whole trick with line chart is that we will hide series data with chd:t0 parameter and next we will display CandleSticks with chm=F (CandleStick Markers). In chm=F link you have full documentation of markers.
public Intent execute(Context context) {
        Double[] _1st = CandleStickChart.generateRandomArray(seriesCount);
        Double[] _2nd = CandleStickChart.incrementArray(_1st, 1000d);
        Double[] _3rd = CandleStickChart.incrementArray(_1st, 2000d);
        Double[] _4th = CandleStickChart.incrementArray(_1st, 3000d);
        ArrayList<double[]> series = new ArrayList<double[]>();
        series.add(_1st);
        series.add(_2nd);
        series.add(_3rd);
        series.add(_4th);

        String abc = createCandleStickChart(series);
        Uri uri = Uri.parse(abc);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        return intent;
        // TODO Auto-generated method stub
    }

private String createCandleStickChart(ArrayList<double[]> dataSeries) {
        ArrayList<integer[]> chd = transformChartSeries(dataSeries);
        StringBuilder sbChart = new StringBuilder();
        //Four series data
        StringBuilder sb1 = new StringBuilder("-1,");
        StringBuilder sb2 = new StringBuilder("-1,");
        StringBuilder sb3 = new StringBuilder("-1,");
        StringBuilder sb4 = new StringBuilder("-1,");
        //Axis Labels
        StringBuilder axis = new StringBuilder("&amp;chl=");
        for (int i = 0; i &lt; chd.get(0).length; i++) {
            sb1.append((chd.get(0)[i]) + ",");
            sb2.append((chd.get(1)[i]) + ",");
            sb3.append((chd.get(2)[i]) + ",");
            sb4.append((chd.get(3)[i]) + ",");
            axis.append(i + "|");
        }

        sb1.append("-1|");
        sb2.append("-1|");
        sb3.append("-1|");
        sb4.append("-1");
        sbChart.append("https://chart.googleapis.com/chart?");//API URL
        sbChart.append("chs=800x200&amp;");//Chart Size
        sbChart.append("cht=lc&amp;chm=F,0000FF,0,,10&amp;");//CandleStick marker
        sbChart.append("chxt=y&amp;");//Visible axis: Left y-axis
        sbChart.append("chd=t0:");//Chart Data t0 - all series are hidden
        String chdd = sbChart.toString() + sb1.toString() + sb2.toString() + sb3.toString() + sb4.toString() + axis.toString();
        System.out.println(chdd);
     
     return chdd;
 }

Final result

Code above use Intent.ACTION_VIEW to open WebActivity for display generated image from Google Chart API

Source Code

You can download Charting Demo application from
here

Wednesday, March 16, 2011

Check/uncheck checkbox in table (GridView) with jQuery. Modern way.

Few moments ago I found a really preety and simple way to check/unckeck all input:checkbox inside GridView(table) column. I was really shocked!
And so you code:

.aspx
<asp:GridView ID="CmpJobOfferCandidatesGv" runat="server" AutoGenerateColumns="False"
 CssClass="EntityGridView">
 <Columns>
 <asp:TemplateField>
 <HeaderTemplate>
  <asp:CheckBox runat="server" ID="checkAllChb" />
 </HeaderTemplate>
  <ItemTemplate>
   <asp:CheckBox runat="server" ID="inviteToExamChb" style="width:20px;margin:0 auto;display:block;" />
  </ItemTemplate>
 </asp:TemplateField>
  <asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-Width="25px" />
 </Columns>
</asp:GridView>

.js
var chbClickEvent = function () {
    $('table[id*="CmpJobOfferCandidatesGv"] tr > td input:checkbox').each(function (index, Element) {
        $(this).trigger("click");
    })
}
$(document).ready(function () {
    $('input:checkbox[id*="checkAllChb"]').click(chbClickEvent);
});
                    

The magic above is caused because I trigger click event foreach checkbox in GridView Column instead of dealing with bunch of if statements to figure out state of checkbox.

$(document).ready(function () {
    $('input:checkbox[id*="checkAllChb"]').click(function () {
        $('table[id*="CmpJobOfferCandidatesGv"] tr > td input:checkbox').each(function (index, Element) {
            if ($(Element).attr('checked') == false) {
                $(Element).attr('checked', true);
            } else {
                $(Element).attr('checked', false);
            }
        });
    });
});

Monday, February 21, 2011

JavaServer Faces 2.0 ClientId with jQuery

Introduction

In this article I will show how to work with clientId property of UIComponent, which has been improved in JavaServer Faces 2.0 about finding concrete id from client side and how 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  as JSF 2.0 implementation and GlassFish 3.0.1.

Hello ClientId

 In this step we will create first simple web application with only one page.
 1.From 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 very various cases. Two steps are needed to get clientId by binding. First we need to add binding attribute and connect this attribute with Managed Bean property corresponding to 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 dolar sign $ to access properties (form1 and component)of managed bean. In (4),(7),(6) we used hash sign # to refer UIComponent methods like findComponent to find child component and uses panel1 properties.

ClientId with NamingContainer

Now I will put some examples of my web application and explain how does it all work. Let start with h:dataTable with few rows and two columns. Second column will contain a h:commandButton and we want use this button to do some client javascript action.
 Here is 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 I don't put explaination.

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

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


Generally when you use jsf framework and look inside html output you can find that clientId is separated by colon sign ":". Unfortunatelly this sign is not allowed when you use jQuery library because is reserved for jQuery selectors. JavaServer Faces 2.0 comes with 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 javascript
jsf.ajax.request function instead of f:ajax and we will use 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 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}. 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


In the almost of the end of article I would'n 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 scenarious. You should also know how to use jsf 2.0 with jQuery and you have learned how to call ajax without f:ajax tag. You can download 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 referene to jsf.js library.
jsf ajax example Example with f:actionListener and jsf.ajax.request(...)
FireBug Oh God. This is one of the best tool for browse client html,
debug javascript and watch real ajax requests.
PrimeFaces My favourite jsf tag library. Uses jQuery as 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 simplify developer life.
Subversion repository of code.Simple NetBeans project where I learn JSF 2.0