Pages

Thursday, May 5, 2011

Facebook style quick friend search and select

Hi,

In this post, I will discuss how to create a friend selection widget as in Facebook. When ever you are inviting your friends, or sending some application request to your friend in Facebook, you might get a friend selection widget as below:

In this I have made a similar functionality using jQuery. Here is what my screen looks like:

In the above, as you start typing the name of your friend, the list below gets filtered quickly accordingly. This is not refreshing the page nor is calling any AJAX. The whole thing is in realtime. Also you can select/unselect 1 or more friend by clicking them. And finally when you click the "Send Request" button the form gets submitted with selected friends user id. This is how I have achieved this.

Each <li> contains the details of each friend, including the picture and the name. The name must not contain any tags or extra spaces. As this is what will be taken into account while filtering. A sample content of the <li> will look like:

The second DIV inside the main div must contain a checkbox, with name of your choice and "value" as the ID of the friend, followed by the name of the friend. Again, the friends name cannot contain any tags or unnecessary spaces. Each <li> that I am using above will be generated dynamically, but I have made it static, for demo purpose.

The main tricks are in the JS. First coming to the functionality for selecting and unselecting a friend. This is done by:

jQuery('.friend_container ul li').click(function(){

jQuery(this).toggleClass("active");

if(jQuery(this).find("input[type=checkbox]").attr("checked")==true){

jQuery(this).find("input[type=checkbox]").removeAttr("checked");

}else{

jQuery(this).find("input[type=checkbox]").attr("checked","checked");

}

})

In above, whenever an <li> is clicked the hidden checkbox's checked status is toggled by:

if(jQuery(this).find("input[type=checkbox]").attr("checked")==true){

jQuery(this).find("input[type=checkbox]").removeAttr("checked");

}else{

jQuery(this).find("input[type=checkbox]").attr("checked","checked");

}

The class of the <li> for the selected friend is also toggled by:
jQuery(this).toggleClass("active");

The selected and unselected friends looks like:

Now the main job for filtering the friends in realtime while typing the name of the friend. This is done by:

jQuery('#friend_name').keyup(function(){

var typed=jQuery(this).val();

if(typed==""){

jQuery('.friend_container ul li').show();

}else{

jQuery('.friend_container ul li').hide();

jQuery(".friend_container ul li").each(function(){

var name=jQuery(this).find("div:last").text();

if((name.substr(0,typed.length)).toLowerCase()==typed.toLowerCase()){

jQuery(this).show();

}

});

}

})

The idea is very simple. Whenever a match is found all the other <li> are hidden and matched one's are shown. If nothing is typed, all are show as:

var typed=jQuery(this).val();

if(typed==""){

jQuery('.friend_container ul li').show();

}else{
//........filtering
}

Now the filtering part is as:

jQuery('.friend_container ul li').hide();

jQuery(".friend_container ul li").each(function(){

var name=jQuery(this).find("div:last").text();

if((name.substr(0,typed.length)).toLowerCase()==typed.toLowerCase()){

jQuery(this).show();

}

});

First I am hiding all the <li>. Then I am traversing through all the <li> and checking if the pattern typed by the user is matching with that of each <li>'s content. i.e.