Latest Entries »

Tuesday, October 25, 2011

Android HTML parser in less than 5 minutes.

Yes it's true. You can create a simple application that parse a html document and get all data you need in less than 5 minutes.

Introduction

In this tutorial I will use standalone Java SE parser called Jsoup. We have few jsoup files available:

In android world size matter so I want only my jsoup-1.6.1-sources.jar. So far jar is an archive so I use 7-zip to extract content of  jsoup-1.6.1-sources.jar into folder. Next thing is to create Android Application from Eclipse IDE. 
After extracting sources from jsoup you should copy all directories inside your src folder. You should have similar application structure:




public class HtmlAParseActivity extends Activity {
 EditText text1;
 Button btn1;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  text1 = (EditText) findViewById(R.id.editText1);
  btn1 = (Button) findViewById(R.id.button1);
  btn1.setOnClickListener(new OnClickListener() {

   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    Document doc;
    try {
     doc = Jsoup.connect(text1.getText().toString()).get();
     Elements links = doc.select("a[href]");
     Elements media = doc.select("[src]");
     Elements imports = doc.select("link[href]");
     print("\nMedia: (%d)", media.size());
     for (Element src : media) {
      if (src.tagName().equals("img"))
       print(" * %s: <%s> %sx%s (%s)", src.tagName(),
         src.attr("abs:src"), src.attr("width"),
         src.attr("height"),
         trim(src.attr("alt"), 20));
      else
       print(" * %s: <%s>", src.tagName(),
         src.attr("abs:src"));
     }

     print("\nImports: (%d)", imports.size());
     for (Element link : imports) {
      print(" * %s <%s> (%s)", link.tagName(),
        link.attr("abs:href"), link.attr("rel"));
     }

     print("\nLinks: (%d)", links.size());
     for (Element link : links) {
      print(" * a: <%s>  (%s)", link.attr("abs:href"),
        trim(link.text(), 35));
     }
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }

   }
  });
 }

 private static void print(String msg, Object... args) {
  System.out.println(String.format(msg, args));
 }

 private static String trim(String s, int width) {
  if (s.length() > width)
   return s.substring(0, width - 1) + ".";
  else
   return s;
 }
}
Of course don't forget to add permission for internet connection.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.persmission.ACCESS_NETWORK_STATE" />

Code in HtmlAParseActivity  was from org.jsoup.example package with some modifications.

Thats all.

Tuesday, September 27, 2011

Insert Update row with MERGE keyword SQL 2008

Few days ago I've got question how to perform insert/update taks in one query. I couldn't answer because I've never used MERGE in SQL 2008 Server. With my curiosity I make reaserch and google and found a solution. Furthermore almost all examples about MERGE was connected with two tables joining by PK-FK but I needed MERGE with one table. For show this query let first prepare a simple table:
CREATE TABLE [dbo].[Target](
	[EmployeeID] [int] IDENTITY(1,1) NOT NULL,
	[EmployeeName] [nvarchar](500) NOT NULL,
 CONSTRAINT [PK_Target] PRIMARY KEY CLUSTERED 
(
	[EmployeeID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,
 ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

Now It's time for write stored procedure that takes adventage of MERGE.

ALTER PROCEDURE [dbo].[TargetInsertUpdate]
(
   @EmployeeID INT,
   @EmployeeName NVARCHAR(500),
   @NewEmployeeID   int OUTPUT
)
AS
SET NOCOUNT ON


MERGE dbo.[Target]  T
-- To check if row is in database we put
-- existing row data inside USING (Source table )(S)
-- if row exists then name is updated
-- otherwise new row is added
-- and @NewEmployeeID indicates newly added ID
USING (SELECT @EmployeeID as EmployeeID,@EmployeeName as EmployeeName) as S
ON T.EmployeeID = S.EmployeeID
WHEN NOT MATCHED BY TARGET THEN
INSERT(EmployeeName) VALUES(S.EmployeeName)
WHEN MATCHED THEN
UPDATE SET T.EmployeeName = S.EmployeeName;

SET @NewEmployeeID = scope_identity()
GO

Monday, June 20, 2011

How to Send Email via Java Mail, CKEditor with NetBeans IDE

This post is copy of my article from here.


Introduction

In this tutorial I will show you how to create a simple JFrame to send email containing HTML content:

This article is divided into several parts, covering topics from the writing of simple e-mail sender Java classes to the integration of a JFrame with CKEditor, which is a rich web HTML editor.


Downloading and Registering Libraries in NetBeans IDE 6.8

First of all, you need to download the latest version of Java Mail from this page, as well as DJ Native Swing. After you download the libraries, you need to put them into the NetBeans Library Manager. I recommend you store all libraries in, for example, C:\Program Files\Java\libraries.


Creating a Java Application and Adding Libraries to the Project

Take the following steps to begin creating the application:
  1. Choose File -> New Project -> Java Application. Click Next.
  2. When Name and Location Window shows up, name your project FCKEditorEmailSender and uncheck Create Main Class so that you end up creating an empty project. Click Finish.
  3. In the Projects Tab click right click Libraries and Add Library from the menu. Then select the libraries which you added from Library Manager. You should have now Java Mail and DJNativeSwing JAR files. Your project should now look like the image shown below:


Creating the Package and Java Classes

Now let's do the real coding work. Go to the project you created and then create a package named EmailSender. In this package, create a Java class named EmailSender (the same name, don't worry) from the New File dialog. In the class, create private fields as shown below:
public class EmailSender {
  private String smtpServer;
  private String port;
  private String user;
  private String password;
  private String auth;
  private String from;
Provide a simple constructor by pressing ALT + INSERT and selecting Constructor... . Select all the fields in the window.

To enable the sending of e-mails by the Java Mail API, you need to create a Properties object where you put all the needed information about SMTP session, such as the server, port, and user. For this purpose create the following method: 
private Properties prepareProperties()
Next, when you prepare the Properties object, you can simply model an email message. This method returns a MimeMessage (which stands for Multipurpose Internet Mail Extensions Message Class). Then create this method:
private MimeMessage prepareMessage(Session mailSession,String charset,
String from, String subject,
String HtmlMessage,String[] recipient) 
The next step about sending emails via Internet involves creating a method for sending HTML content messages. Create this method:
public void sendEmail(String subject,String HtmlMessage,String[] to) 
Now we add the implementations of the methods shown above:
private Properties prepareProperties()
{
   Properties props = new Properties();
   props.setProperty("mail.smtp.host", smtpServer);
   props.setProperty("mail.smtp.port", port);
   props.setProperty("mail.smtp.user", user);
   props.setProperty("mail.smtp.password", password);
   props.setProperty("mail.smtp.auth", auth);
   return props;
}
private MimeMessage prepareMessage(Session mailSession,String charset,
                                        String from, String subject,
                                        String HtmlMessage,String[] recipient) {
        //Multipurpose Internet Mail Extensions
        MimeMessage message = null;
        try {
            message = new MimeMessage(mailSession);
            message.setFrom(new InternetAddress(from));
            message.setSubject(subject);
            for (int i=0;i<recipient.length;i++)
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(recipient[i]));
            message.setContent(HtmlMessage, "text/html; charset=\""+charset+"\"");
        } catch (Exception ex) {
            Logger.getLogger(EmailSender.class.getName()).log(Level.SEVERE, null, ex);
        }
        return message;
    }
public void sendEmail(String subject,String HtmlMessage,String[] to)
    {
        Transport transport = null;
        try {
            Properties props = prepareProperties();
            Session mailSession = Session.getDefaultInstance(
                            props, new SMTPAuthenticator(from, password, true));
            transport =  mailSession.getTransport("smtp");
            MimeMessage message = prepareMessage(mailSession, "ISO-8859-2",
                                                from, subject, HtmlMessage, to);
            transport.connect();
            Transport.send(message);
        } catch (Exception ex) {    
        }
        finally{
            try {
                transport.close();
            } catch (MessagingException ex) {
                Logger.getLogger(EmailSender.class.getName()).
                                                    log(Level.SEVERE, null, ex);
            }
        }
    }
package EmailSender;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

public class SMTPAuthenticator extends Authenticator{
    private String username;
    private String password;
    private boolean needAuth;

    public SMTPAuthenticator(String username, String password,boolean needAuth)
    {
        this.username = username;
        this.password = password;
        this.needAuth = needAuth;
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        if (needAuth)
            return new PasswordAuthentication(username, password);
                else return null;
    }
}


Creating a Swing Form to Provide a Nice GUI

Now that we have finished the e-mail work, we concentrate on the Swing and FCKEditor integration. You need to click right button over package EmailSender and choose New -> JFrame Form, call this class SendEmail and put this class in EmailSender package. Now right click over JFrame Design View and select: Set Layout -> Border Layout.
Now when you try to drop JPanel from Pallete into Design View you will see a few borders which are simpy Content Holders of Border Layout. Please read about BorderLayout from official Java Docs. Click Panel from Pallete and drop panel as is in image below. In this area you will next put controls to get smtp values.
Now right click over the panel above and select : Set Layout -> Null Layout. This will make your controls not floating when user will resize window and secondly controls will be in the same position as it was created in Design view. Test with some diffrent Layouts when you run your application to see what will happen :) Now you will need to create buttons to interact with user. Put new JPanel into lower "Place holder".
Add the two buttons:
And we are close to finishing the tutorial. Last thing to do is put FCKEditor in main method. Modify your:
public static void main(String[] args) 
    UIUtils.setPreferredLookAndFeel();
    NativeInterface.open();
    final String configurationScript =
      "FCKConfig.ToolbarSets[\"Default\"] = [\n" +
      "['Source','DocProps','-','Save','NewPage','Preview','-','Templates'],\n" +
      "['Cut','Copy','Paste','PasteText','PasteWord','-','Print','SpellCheck'],\n" +
      "['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],\n" +
      "['Form','Checkbox','Radio','TextField','Textarea','Select','Button','ImageButton','HiddenField'],\n" +
      "'/',\n" +
      "['Style','FontFormat','FontName','FontSize'],\n" +
      "['TextColor','BGColor'],\n" +
      "'/',\n" +
      "['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],\n" +
      "['OrderedList','UnorderedList','-','Outdent','Indent','Blockquote'],\n" +
      "['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],\n" +
      "['Link','Unlink','Anchor'],\n" +
      "['Image','Flash','Table','Rule','Smiley','SpecialChar','PageBreak', '-', 'ShowBlocks'],\n" +
      "];\n" +
      "FCKConfig.ToolbarCanCollapse = false;\n";
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                htmlEditor = new JHTMLEditor(HTMLEditorImplementation.FCKEditor,
JHTMLEditor.FCKEditorOptions.setCustomJavascriptConfiguration(configurationScript));
                SendEmail es2 = new SendEmail();
                es2.setSize(new Dimension(800,600));
                es2.add(htmlEditor,BorderLayout.CENTER);
                es2.setLocationByPlatform(true);
                es2.setVisible(true);
            }
        });
    }
Now when you replace main method go to your Design View and double click both buttons to generate actionPerformed . Put this codes into proper buttons.Notice that I used code below to provide new Thread to prevent block Graphical User Interface during send e-mail:
javax.swing.SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    emailer.sendEmail(subject.getText(),
    htmlEditor.getHTMLContent(),
    recipientsString); 
    }
});  
private void sendEmailActionPerformed(java.awt.event.ActionEvent evt) {                                          
        // TODO add your handling code here:
                StringTokenizer recepientsTokenizer = new StringTokenizer(to.getText(), ",");
                final String[] recipientsString = new String[recepientsTokenizer.countTokens()];
                for (int i = 0; i < recipientsString.length; i++) {
                    recipientsString[i] = recepientsTokenizer.nextToken();
                }
                 final EmailSender emailer = new EmailSender(smtpServer.getText(),
                        port.getText(), username.getText(),
                        password.getPassword().toString(),
                        "true", from.getText());
              javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                emailer.sendEmail(subject.getText(),
                        htmlEditor.getHTMLContent(),
                        recipientsString);
            }
        });
    }
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
  // TODO add your handling code here:
  dispose();
} 
Now you can build your project and show off to your friends :)
Here you can download the packed NetBeans project.
Tip:
When you download DJ Native you can double-click the DJNativeSwing-SWTDemo.jar to look closer into the various amazing classesm such as JWebBrowser JHtmlEditor with different HtmlEditors.

After many reqests for source code of project which was unavailable due to closed magaupload I uploaded project one time more. So I Uploaded again source code. 

Thursday, June 16, 2011

Persist checkbox client side row selection inside GridView in asp:UpdatePanel

Comming Soon :-) //After defend my thesis.

Monday, June 13, 2011

Disappearing content in FCKEditor after mode change.

Comming soon :-)

Sunday, May 29, 2011

Hightly efficiently GridView with JSON and Caching(in part 2)



Introduction

Hello. In this article I will show you how to extremely improve GridView performance. For this purpose I prepared table with huge amout of data (about 4000 rows). We will start with trivial things and then we will do real code exhibition. Note that I don't use pagination now.

Little things matter. Really.

Take a look at this GridView:
<asp:GridView ID="GblContactsGv" runat="server" AutoGenerateColumns="False" CssClass="EntityGridView"
        OnRowCommand="GblContactsGv_RowCommand" OnRowDeleting="GblContactsGv_Deleting">
        <Columns>
            <asp:TemplateField HeaderText="ID">
                <ItemTemplate>
                    <asp:Label runat="server" ID="glbContactIdLbl" Text='<%# Eval("gblContactId") %>'
                        CssClass="label" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Email">
                <ItemTemplate>
                    <asp:Label runat="server" ID="glbContactIdLbl" Text='<%# Eval("Email") %>' CssClass="label" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Phone">
                <ItemTemplate>
                    <asp:Label runat="server" ID="glbContactIdLbl" Text='<%# Eval("Phone") %>' CssClass="label" />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
This simple GridView will render your HTML such like this:
<tr>
   <td>
                    <span class="label" id="ctl00_CenterColumn_GblContactsGv_ctl02_glbContactIdLbl">78</span>
                </td><td>
                    <span class="label" id="ctl00_CenterColumn_GblContactsGv_ctl02_glbContactIdLbl">test@test.test 78</span>
                </td><td>
                    <span class="label" id="ctl00_CenterColumn_GblContactsGv_ctl02_glbContactIdLbl">123456 78</span>
                </td>
  </tr>
On the other hand the same result could be done with this GridView:
<asp:GridView ID="GblContactsGv" runat="server" AutoGenerateColumns="False" CssClass="EntityGridView"
        OnRowCommand="GblContactsGv_RowCommand" OnRowDeleting="GblContactsGv_Deleting">
        <Columns>
            <asp:BoundField DataField="gblContactId" HeaderText="ID" />
            <asp:BoundField DataField="Email" HeaderText="Email" />
            <asp:BoundField DataField="Phone" HeaderText="Phone" />
        </Columns>
</asp:GridView>
So again let see what is going to send to browser:
<tr>
    <td>
        78
    </td>
    <td>
        test@test.test 78
    </td>
    <td>
        123456 78
    </td>
</tr>
In first code listing each row(for 3 columns) contains 438 characters and in second GridView using BoundFields each row contains just 112 characters. In this case I saved 326 characters per row. Assuming you use UTF-8 as page encoding it's 652 bytes by row!

Depending on amount of rows and columns I can save about 30%-40% of data.  Wherever you can you should avoid any control with runat="server" because each row is using NamingContainer to add unique ClientID.

Avoid PostBacks and UpdatePanels.

Now I will show you how to make dramatically performance improvement. In this scenario I will use GridView shown above but I added all columns definied in C# class holding database table. I also fill table with ~ 4000 rows. I will create 3 pages: PostBack.aspx, UpdatePanel.aspx and jQuery.aspx. First will won't use any AJAX, second will use build in asp.net UpdatePanel to create AJAX Request and last example will be using jQuery.ajax() method with JSON and [WebMethod()].
<asp:GridView ID="GblContactsGv" runat="server" AutoGenerateColumns="False" CssClass="EntityGridView"
        OnRowCommand="GblContactsGv_RowCommand" OnRowDeleting="GblContactsGv_Deleting">
        <Columns>
            <asp:BoundField DataField="gblContactId" HeaderText="ID" />
            <asp:BoundField DataField="Email" HeaderText="Email" />
            <asp:BoundField DataField="Phone" HeaderText="Phone" />
            <asp:BoundField DataField="URL" HeaderText="URL" />
            <asp:BoundField DataField="Description" HeaderText="Description" HtmlEncode="false" />
            <asp:BoundField DataField="Address" HeaderText="Address" />
            <asp:TemplateField HeaderText="Delete">
                <ItemTemplate>
                    <asp:LinkButton runat="server" ID="deleteBtn" CommandArgument='<%# Eval("gblContactId") %>' CommandName="delete" 
                    Text="Delete" />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
</asp:GridView>

Now we will need FireBug and Network Tab to show some magic.

Here I got first page. Whenever I load page or perform <asp:linkbutton /> action I receive alost 3MB of data.


Now I thought a UpdatePanel will be better solution doing AJAX request. Let's try:
<asp:UpdatePanel runat="server" ID="upPanel1">
        <ContentTemplate>
   <!-- The same GridView like before -->
  </ContentTemplate>
</asp:UpdatePanel>

And again take a look what happen when I click LinkButton:


Image above show that Request["__VIEWSTATE"] (1,13 MB) and Request["__EVENTVALIDATION"] (31,7 KB) is extremly big! Whenever you use ajax request each time those two hidden inputs are send to server. Even when you update just one single Label.

Now I will show how to do simple action via jQuery.ajax() and C# [WebMethod()] for performance improve. One thing what will change in aspx file will be script tag:
$(document).ready(function () {
    $('.delete').click(function () {
        var commentId = $(this).closest('tr').find(':hidden').val();
        var row = $(this).closest('tr');

        $.ajax({
            type: "POST",
            url: "jQuery.aspx/DeleteComment",
            data: "{'c':'" + commentId + "'}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            beforeSend: function () {
                $('#Result').html('Deleting...');
            },
            success: function (msg, textStatus, jqXHR) {
                if (msg.d == '0') {
                    row.closest('tr').hide();
                    $('#Result').html('Deleted !');
                } else {

                }
                return false;
            },
            error: function (jqXHR, textStatus, errorThrown) {
                $('#Result').html('Error !' + errorThrown);
            }
        });
        return false;
    });
And in GridView let modify last column:
<asp:TemplateField HeaderText="Delete">
 <ItemTemplate>
  <input type="hidden" value='<%# Eval("gblContactId") %>' />
  <asp:LinkButton runat="server" ID="deleteBtn" CommandArgument='<%# Eval("gblContactId") %>'
   CommandName="delete" CssClass="delete" Text="Usuń" />&nbsp;&nbsp;
  <a href="#" class="delete">Delete</a>
 </ItemTemplate>
</asp:TemplateField>
Last thing to show off is aspx.cs method:
[WebMethod()]
    public static string DeleteComment(string c)
    {
        string response = "";

        if (DataRepository.GblContactProvider.Delete(int.Parse(c)))
        {
            response = "0";
        }
        return response;
    }
Now let's look on Firebug and see some magic. Here we got Request data:

And here we got answer from server:
Here is real performance shock. I don't want even count performance improvment!

Loading data with JSON

If we have need to load huge amout of data we should consider load pure JSON data and process this data inside JavaScript code. Before we perform this we need have class which has [Serializable()] attribute and then use any JSON serializer available in .NET world. Here I used build in System.Runtime.Serialization.Json.DataContractJsonSerializer class. Here is example:
[Serializable()]
class Contact
{
    public int GblContactId;
    public string Email;
    //Other properties

    public Contact(int gblcontactId, string email, string url, string desc, string phone, string address)
    {
        this.GblContactId = gblcontactId;
        this.Email = email;
        //Other stuff in constructor
    }
    //GetAll() for load data
    //....
    //....
}
// Inside aspx.cs
[WebMethod()]
    public static string LoadCommentsAjax()
    {
        List contacts = Contact.GetAll();
        return Serialize(contacts);
    }

    public static string Serialize<T>(T obj)
    {
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
        using (MemoryStream ms = new MemoryStream())
        {
            serializer.WriteObject(ms, obj);
            return Encoding.Default.GetString(ms.ToArray());
        }
    }
For big JSON data we need to modify web.config:
<system.web.extensions>
<scripting>
  <scriptResourceHandler enableCaching="true" enableCompression="true"/>
  <webServices>
 <jsonSerialization maxJsonLength="2147483644" />
  </webServices>
</scripting>
</system.web.extensions>

Now let's test this with script:
$('.ajaxloadjQuery').click(function () {
    $.ajax({
        type: "POST",
        url: "jQuery.aspx/LoadCommentsAjax",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        beforeSend: function () {
            $('#Result').html(' Loading comments ...');
        },
        success: function (msg, textStatus, jqXHR) {
            var items = $.parseJSON(msg.d);

            $(items).each(function () {
                console.log('ID: ' + this.GblContactId + ' Address: ' + this.Address + ' Description ' + this.Description + ' Email: ' + this.Email + ' Phone: ' + this.Phone + ' URL: ' + this.Url);
            });
            var jq = jqXHR;
            return false;
        },
        error: function (jqXHR, textStatus, errorThrown) {}
    });
    return false;
});
When we click we will have ajax request with just 888.2 KB rather than about 2.8MB. It's more than 30% less request size.

One important notice is that in $(items).each(function(...)) I've used something this.GblContactId or this.Address. This is because DataContractJsonSerializer automatically maps serialized class into JSON object with the same property names. Okey we used Console.Log() to print output into FireBug but I will show you a complete script to create html table from client side based on JSON data:
$('.ajaxloadjQuery').click(function () {
    $.ajax({
        type: "POST",
        url: "jQuery.aspx/LoadCommentsAjax",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        beforeSend: function () {
            $('#Result').html(' ładuje komentarze ...');
        },
        success: function (msg, textStatus, jqXHR) {
            var ts = textStatus;
            var items = $.parseJSON(msg.d);
            var rows = '';
            //Adding header info:
            rows += '<tr>'
            rows += '<th>ID</th>';
            rows += '<th>Address</th>';
            rows += '<th>Description</th>';
            rows += '<th>Email</th>';
            rows += '<th>Phone</th>';
            rows += '<th>Url</th>';
            rows += '<th>Delete</th>';
            rows += '</tr>';
            var counter = 0;
            //('#myTable').show();
            $(items).each(function () {
                rows += '<tr>';
                rows += '<td>' + this.GblContactId + '</td>';
                rows += '<td>' + this.Address + '</td>';
                rows += '<td>' + this.Description + '</td>';
                rows += '<td>' + this.Email + '</td>';
                rows += '<td>' + this.Phone + '</td>';
                rows += '<td>' + this.Url + '</td>';
                rows += '<td> <input type="hidden" value="' + this.GblContactId + '" /> <a href="#" class="delete">Delete</a> </td';
                rows += '</tr>';
                counter++;
                //For showing JSON data in portion with 100 rows
                if (counter % 100 == 0) {
                    $('#myTable').append(rows);
                    rows = '';
                }
            });
            $('#myTable').append(rows);
            var jq = jqXHR;
            return false;
        },
        error: function (jqXHR, textStatus, errorThrown) {
            var ts = textStatus;
            var err = errorThrown;
            var jq = jqXHR;
            $('#Result').html('Pojawił się błąd !' + err);
            console.log(ts + ' ' + err + ' ' + jq);
        }
    });
    return false;
});

Conclusions

Here doing jQuery.ajax with big data set we saved approx 30% on our Request size passing just only JSON insted of rendered html table(GridView). Next very suprising thing that really matter was usage of Bound Fields in contradiction to using standard server controls. We saved again 30% of Request size. It's really good result.

Yes we could use pagination for making our Request much more smaller and use more sophisticated architecture but sometimes we are forced to send big data package.

Monday, May 23, 2011

Most useful features in Firebug 1.7.0

Comming soon :-)

Saturday, May 21, 2011

Saving scroll position beetween pages in ASP.NET after redirecting

Comming soon.

jQuery find function $.find('selector') versus traditional selecting $('selector')

Comming soon.

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_CHARIn 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