Prototype Portal Class

August 26th, 2007

I have always wanted to create a Class to handle in a easy way portal page like netvibes. After having tried to used Sortable of script.aculo.us, I decided to write my own Class. I really like Sortable Class but it was too tricky to use it for a portal behavior. But I use Draggable and Droppable of course!

This article talks about the first version I made. It has been tested on Safari, Firefox, Opera and IE 6/7. The first version is based on Prototype 1.5.1.1 because I could not use 1.6. but the next version will be based on 1.6.

Here is how it works.

1) Create an HTML page with as many columns you need. Columns width can be fixed or variable, and with different size.

Here is a HTML sample with 3 columns
   1  <div id="page">
   2    <div id="widget_col_0"></div>
   3    <div id="widget_col_1"></div>
   4    <div id="widget_col_2"></div>
   5  </div>
And the CSS file
   1  #page {
   2    margin: 10px auto;
   3  }
   4  
   5  #widget_col_0 { 
   6    float:left;
   7    width: 30%;  
   8  }
   9  
  10  #widget_col_1 {
  11    width: 50%;
  12    float:left;
  13  }   
  14  
  15  #widget_col_2 { 
  16    float:left;
  17    width: 20%;  
  18  } 
Pretty easy!

2) You need to instanciate a Portal class with those columns:
   1  var  portal = new Xilinus.Portal("#page div")
3) Add widgets to this portal. There is a Widget class, fully CSS skinnable (there is a default theme), just create a new Widget instance and add it to the portal by specifying the column index. For example:
   1  portal.add(new Xilinus.Widget(), 0)
   2  
   3  // Or with title and content
   4  portal.add(new Xilinus.Widget().setTitle("Widget Title").setContent("bla bla bla"), 1);
And that’s it!! There are also some options when you create the portal:
  • url: Url called by Ajax.Request after a drop (default null, no requests)
  • onOverWidget: Called when the mouse goes over a widget (default null)
  • onOutWidget: Called when the mouse goes out of a widget (default null)
  • onChange: Called a widget has been move during drag and drop (default null)
  • onUpdate: Called a widget has been move after drag and drop (default null)
  • removeEffect: Remove effect (by default no effects), you can set it to Effect.SwitchOff for example
And main functions are:
  • add(widget, columnIndex): add a new widget .
  • remove(widget): remove a new widget.
  • serialize(): returns a parameters string for Ajax.Request

You could a see a live example here. I have used onOverWidget/onOutWidget to add edit/delete buttons on widget and I added a remove effect to show how to use it with advanced features.

You can download the widget.js javascript file or check out code from svn: svn co http://svn.itseb.com/public/prototype-portal/trunk prototype-portal

Next I will create a full website for this class with documentation and CSS details (it’s based on sliding doors technique), port it to prototype 1.6 with new Element class (I will remove builder.js) and the new class model. Prototype rocks!!

The 1.6 version will also include unit tests.

One more thing, it’s under MIT license, as Prototype and script.aculo.us, so feel free to use it.

PS: Thanks to Seb for testing and debugging!

32 Responses to “Prototype Portal Class”

  1. speps Says:

    On NetVibes, columns are resizable too.

  2. Nicolás Sanguinetti Says:

    Wow! This is freaking cool :D

    One minor improvement (before trying it out): let Xilinus.Portal accept a string as argument, in which case it’s passed to $$. Thus having

    new Xilinus.Portal("#page div");

    which is a bit less cumbersome to type and follows more into Proto’s way of accepting strings or nodes for methods :) (patch @ http://pastie.caboo.se/91129.txt)

    I’ll play a little with it later :D

  3. seb Says:

    @speps: Wow I haven’t seen this, I will add this too! I like it

    @Nicolas: Thanks for the improvement, good idea. I will open a svn repository tomorrow and add it to the article.

  4. seb Says:

    I have created a svn repository (http://svn.itseb.com/public/prototype-portal/trunk) and updated the article.

  5. Fran Says:

    Good job “Le dioude”.. as always.. ;-)

  6. Samuel Lebeau Says:

    Good work !! I’ll be happy to help you port it to 1.6 as soon as possible Seb !

  7. carlo demarchis Says:

    Wow! Long time awaited… I will start playing with it tonite and will feedback asap – thanks!

  8. Chris Sanchez Says:

    Bug: If you delete the last div in a column, you can no longer drag other divs to that column.

  9. seb Says:

    @chris: I don’t understand it works fine for me. Which browser/OS?

  10. Bramus! Says:

    Nice!

    @ Chris : works fine here … (Tested in: FX2, IE7 & IE6 on a WinXP box)

  11. Nick Says:

    I think I can elaborate on Chris’s bug. You can drop stuff into the rightmost column when it’s empty, BUT only into the bottom half of the box. If you hover over the top half there’s no outline and dropping doesn’t work. Using Firefox 2.0.0.6 on Ubuntu,

  12. Ben Says:

    Awesome! I’ve written a portal app myself based on prototype/scriptaculous, it took ages and I have a couple of problems with it, namely that the layout is completely fixed and doesn’t cope well with window resizes.

    If this system receives some of Netvibes’ features like resizable columns, I’ll definitely switch over to this from my kludged sysetm :)

  13. samir Says:

    Nice work! i will try it now :)

  14. quaff Says:

    great work,mark

  15. seb Says:

    @Nick: I do not have an linux box to test and it works on FF mac :(

  16. Don Says:

    what lizenz has it? I would like to use it.

  17. joe Says:

    any idea how to store the user’s layout using the serialize function?

  18. Chris Sanchez Says:

    I’ve found the bug on IE7, FF 2.0.0.6, and Opera 9.01 on Windows XP. When you remove the last widget in a column, try dragging the top widget from another column to the column with no widgets in it. The box will not appear until you drag the column below where you wish to put it. I had this same problem with a portal I was developing for my department. I can’t remeber exactly but I believe I added code to check for columns that were empty.

  19. Chris Says:

    I guess the only thing missing is a minimize and maximize button, otherwise, freakin’ awesome!!

  20. seb Says:

    MIT licence feel free to use it :)

  21. Marc Says:

    Great stuff! However, I have a multiple page portal (tabs) and this doesn’t seem to support multiple portals on a single page. It seems that each of the drag events gets fired once for each portal even though the user is dragging in the first portal. The second time endDrag is called widget.ghost is null and this throws and error (line 248 or portal.js).

  22. seb Says:

    Correct, this version does not support multiple portals on a single page. But you can have this behavior easily

  23. Sforce Says:

    Anyone has any idea on how to create a seperate button that shows or hides a specific widget?

  24. seb Says:

    Have a look how delete button is done, and add your own control buttons the same way

  25. Vinoth Says:

    Can some one help me out in using the URL property of the Xilinus. Basically i wanted to try out loading the page in the widget(how it works in Ajax request). Thanks in advance.

  26. Chris Says:

    Seb, freakin’ awesome. Can you provide examples of how the URL method is used? Also can you tell me (using prototype’s api) how to get to the div “content_widget_#”? I’m trying to add a blindup/blinddown function to a minimize and maximize button that I’ve added to the “control_buttons” div.

    Thanks! Chris

  27. Ryan Says:

    This is great. Is there any built-in way to load content from an url? like … setContent(URL) ?? Thanks.

  28. Tom Says:

    Great Job—is there a way to reference an id in the DOM instead of using a string (i.e., var latin1 = $(“divid”); ??

  29. seb Says:

    Sorry for not answering but I have no more internet connection for a moment :(

  30. Mike Says:

    Vinoth, I tried using Ajax to load a page in a widget but the size got messed up(set the content div to the value ), Iframe works well on FF but draws an empty box under the frame in IE,

  31. TBS Says:

    Hey! This work its great but no explain very good for rokies like me! I need add new widget but i dont understand how i can do ?? :S

  32. Chris Says:

    Ok…got the minimize and maximize to work. Absolutely wonderful! Thanx Seb for this!!

Sorry, comments are closed for this article.