Pages

I've migrated my blog

Thanks for visiting my blog. I am no longer maintaining this and I've migrated the blog to my personal domain . If you would like to follow my blog kindly use my new RSS feed

Monday, February 7, 2011

Creating a webpage like iGoogle using jQuery

Would you like to create a webpage like iGoogle (www.google.co.in/ig)??

This blog post is for you!!

I hope you are aware of the following stuffs which are the building blocks of this blog post.
1.HTML
2.CSS
3.jQuery

Let us design the page using “Divide and Conquer” Approach. The tasks involved are
1.Defining the webpage layout using HTML
2.Style the webpage and Widgets(Sample iGoogle Mock up Widgets) using CSS
3.Add the drag and drop functionality using jQuery.

Task 1: Defining the webpage layout using HTML
The HTML is very straight forward. Entire webpage contents have been placed inside a div with the id “iGoogle”. Then each column (iGoogle uses three column layout) is defined by a div element with the id representing the corresponding columns. These columns act as a placeholder for Widgets. Each widget defined as a div element which contains two div elements inside it which represents the header and the body of the Widgets

Widget 1
Widget 2
Widget 3
Widget 4
Widget 5
Widget 6


Task 2: Style the webpage and widgets
Now we have the HTML Layout ready. Our next task would be applying style to the webpage and the widgets using CSS.
/* Entire Page has been divided into 3Columns. 
Note: iGoogle Page has 3 columns */
#column1,#column2,#column3 
{
display:inline-block;
float:left;
width: 33%;            
height: auto;            
text-align:center;
padding-bottom: 100px;
}

/* Css Classes for Entire Widget */

.Widget 
{         
margin: 10px;
margin-left: auto;
margin-right: auto;
width: 95%;
min-height: 200px;
border: 1px solid Black;
}


/* Css Classes for Widget Headers */

.WidgetHeader 
{
height: 25px;    
cursor: move; 
text-align: left;
padding-left: 3px;
color: White;
font-weight: bold;                      
}        

.GreenWidgetHeader 
{
background-color:Green;
}

.GrayWidgetHeader 
{
background-color:Gray;
}

.PurpleWidgetHeader 
{
background-color:Purple;
}

/* Css Classes for Widget Body */
.WidgetBody 
{
min-height: 175px;
height:auto;
background: #F0F0F0;
}

/* Placeholder while dragging the widget using jQuery*/
.ui-sortable-placeholder { 
border: 1px dashed black; 
visibility: visible !important; 
height: 50px !important; 
}
.ui-sortable-placeholder * { visibility: hidden; }

.footer 
{
clear:both;
display:block;                                    
position:absolute;         
color: Green;                
bottom: 5px;
right: 5px;
}       


Task 3: Add the drag and drop functionality using jQuery
jQuery offers a rich set of functionality which can be implemented by less lines of coding. With jQuery you can “write less and do more”. All you need to refer the jQuery API files in your javascript and make use of the functionality it provides. To implement the drag and drop functionality we need the following jQuery library files which can be downloaded from the locations mentioned in the “src” attribute






Now we have the necessary jQuery libraries to implement the drag and drop functionality and all set for implementing the drag and drop support. Here is the code part which implements the drag and drop functionality.


Yes!! That’s it!! Just three function calls and seven lines of coding!!
Now you can drag and drop the widgets and play!!

Well, let me explain the jQuery code
The jQuery UI Sortable plugin makes selected elements sortable by dragging with the mouse. Here in our case the selected elements refer to “column1, column2, colum3” which are the placeholders of the widgets. This sortable plugin has many optional arguments which define how drag and drop should be done. “connectWith” option allows drag and drop between the columns. i.e., Elements (Widgets in our case) inside the column1 or column2 or column3 can be dragged and dropped on column1 or column2 or column3. “handle” option specifies the element which can be used to drag the widget between the columns. “opacity” option defines the transparency of the widget while dragging. The “disableSelection()” function disable text selection in a widget which often occur while dragging a mouse across a widget. Reference: http://docs.jquery.com/UI/Sortable

Summary:
To keep the blog post simple, I didn’t implement the persistence of the widget positions. So widgets should not retain its positions when you refresh the page. You can see the source code of this blog post Here

Thanks
Tamizhvendan S

22 comments:

  1. Hi Tamizhvendan,

    Excellent presentation! Your divide and conquer technique makes it easy to learn dynamic web pages creation.

    Thanks

    Best regards,
    Ma Sivakumar

    ReplyDelete
  2. Hi, how do I achieve persistence?

    thanks !!

    Vincenzo

    ReplyDelete
  3. Hi Vincenzo,
    You can achieve using the receive event handler

    $(selector).sortable({
    ...
    ...
    receive: function (event, ui)
    {
    // Add your persistance logic here via Ajax Request
    }
    });

    You can get from more information about the other events which are raised during drag and drop from here http://jqueryui.it/demos/sortable

    ReplyDelete
  4. Thanks a lot for this article, nice and easy.
    One thing though, whenever I move my widget it reloads itself. is there any way to stop it doing that. Also how to impliment close and minimize widgets.

    ReplyDelete
  5. Hi Agrawala ,

    Can you elaborate what you exactly mean in “whenever I move my widget it reloads itself”

    Regarding minimizing and closing the widget, you can easily do that by adding two more span tags inside the
    Widget Header div and handling its Click events

    ReplyDelete
  6. Thanks for the reply TamizVendan. Say you have the gadget in column 1 and it does some dynamic stuff i.e. loading the data from the server. if you then move the gadget to column 2, it reloads the data again. I was wondering if there is any way to stop that. as it can cause performance problems.

    ReplyDelete
  7. Hi,
    Sorry for the delayed reply.
    I've simulated the behavior that you mentioned it doesn't seem to reload. Can you share the code snippet.

    ReplyDelete
  8. Hi,

    I'm have found the same issue. When a widget is moved (dragged and dropped) it reloads/resets.

    The data is loaded from the "$(document).ready(function()" event in the iFrame. Is there another way to do it?


    Cheers Paul.

    ReplyDelete
    Replies
    1. Hi Paul,

      I'm not able to reproduce the same. Can you try handling the receive event of sortable plugin and do event.preventDefault() or return false in the event handler.

      Delete
  9. hello i got an error like $("#column1 #column2 #column3").sortable is not a function.... how can i solve this .... please help...

    ReplyDelete
    Replies
    1. ZER,
      Sorry for the delayed reply.

      Have you added all the javascript references files mentioned in the post ?

      Delete
  10. Your demo is not working unfortunately. Latest Firefox/Ubuntu

    ReplyDelete
    Replies
    1. I noticed that as well. Mac/Chrome

      Delete
    2. I have just checked it out.. As the jQuery library files are not being loaded, it is not working.. Updated the blog post to point to a gist instead of the demo

      Delete
  11. Hi,

    The article is really nice. Help me a lot.i want to know two things
    1.I want to fix the Widget1. So that the it should not be movable and any other widget should not swap the widget1.
    2. Once all the widget in one column say (widget5 and 6 from column 3) were moved to column2. Now once the column is empty.then,i want to move the widget in that column then it should be placed on the column. Right now, once the column is empty, widget cannot be moved to that column.

    Please Help me. Thanks

    ReplyDelete
    Replies
    1. 1. You can achieve fixed widget by specifying what are all the elements that you want to drag and drop by specifying like below

      Suppose, if you added a class called 'Sortable' to all the 'Widget' elements, then you enable sorting only on them by using

      $("#column1,#column2,#column3").sortable({
      connectWith: "#column1,#column2,#column3",
      handle: '.WidgetHeader',
      opacity: 0.6,
      items : '.Sortable'
      });

      2. It is actually a bug, updated the source code, kindly check out the new code in the gist.

      Delete
  12. Thanks for the reply.
    my second query is solved.

    But, the first query is not solved yet.Actually i want to stop the moving and swapping of widget1(of column 1).
    I fixed the movable issue of widget1 [of column1] by apply the style "Cursor:none;" to the widget1.
    But when i m dragging the widget 4 or 5 from the column2 or 3 respectively,then widget 4 swap the widget1 and the widget4 is now placed on the top left of the page.[Widget4 takes the position of widget1 and widget1 shifts below]. I want to stop this swapping of widget1. It remains at the top left position. So please help me to solve this issue.

    ReplyDelete
    Replies
    1. Hi, Please refer the gist here to achieve fixed widgets https://gist.github.com/3838578

      Delete
    2. Thank you very much for your help.
      It works fine. :)

      Delete
  13. This comment has been removed by the author.

    ReplyDelete
  14. In Google Chrome and Windows XP when widgets have expanded the vertical scroll of the page (no content widgets) does not reach the bottom of the page. In IE and FireFox works fine. In Windows 7 too.

    Any idea or solution?

    Thank you, Oscar.

    ReplyDelete
    Replies
    1. You can check this problem in the next page: http://TuPlaneta.es/new/

      Thanks, Oscar.

      Delete