Working with JQuery Portlets

I had a difficult time finding good examples working with the JQuery Portlets, so I created by own. Based on the Portlet Example, here is source code that demonstrates the following features:

  • Draggable & Sortable
  • Different Sized Columns
  • Close Button
  • Settings Menu
  • Change Visibility Of Each Portlet
  • Change Column Widths
  • Scrollable Portlet Contents

Visit the Live Demo. Download the source code at GitHub.

dashboard.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">

<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Sample Dashboard</title>
    <link rel='stylesheet' 
        href='http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/cupertino/jquery-ui.css'/>
    <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js'></script>
    <script src='http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js'></script>
    <link rel='stylesheet' href='dashboard.css'/>
    <script src="dashboard.js" type="text/javascript" charset="utf-8"></script>
  </head>
  <body id="dashboard">
    <div id='header' class="ui-widget-header ui-corner-all ui-widget">
      <div>Dashboard test</div>
      <div id="menu2" class="ui-icon ui-icon-wrench"></div>
      <br class='clear'/>
    </div>
    <div class="demo">
      <div id="window_dialog" class="hidden">
        <fieldset>
          <legend>Column Widths</legend>
          <label>Left:</label><input type='text'  id='c1-width'>
          <label>Middle:</label><input type='text'  id='c2-width'>
          <label>Right:</label><input type='text'  id='c3-width'>
        </fieldset>
        <fieldset>
            <legend>Window Visibility</legend>
        <input type="checkbox"  id="feeds-visible"  /><label>Feeds</label><br/>
        <input type="checkbox" id="shopping-visible"  /><label>Shopping</label><br/>
        <input type="checkbox" id="news-visible"  /><label>News</label><br/>
        <input type="checkbox" id="links-visible"  /><label>Links</label><br/>
        <input type="checkbox"  id="images-visible"  /><label>Images</label><br/>
        </fieldset>
      </div>
    <div class="column1">
      <div id='feeds-portlet' class="portlet">
        <div class="portlet-header">Feeds</div>
        <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
      </div>

      <div id="news-portlet" class="portlet">
        <div class="portlet-header">News</div>
        <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
      </div>
    </div>
    <div class="column2">
      <div class="portlet" id='shopping-portlet'>
        <div class="portlet-header">Shopping</div>
        <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
      </div>
    </div>
    <div class="column3">
      <div id="links-portlet" class="portlet">
        <div class="portlet-header">Links</div>
        <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit</div>
      </div>
      <div id="images-portlet" class="portlet">
        <div class="portlet-header">Images</div>
        <div class="portlet-content">Lorem ipsum dolor sit amet, consectetuer adipiscing elit 
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor 
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud 
exercitation ullamco laboris nisi 
        </div>
      </div>
    </div>
    </div><!-- End demo -->
  </body>
</html>


dashboard.css

body{min-width: 900px;}
h1{color: red;}
.button{padding: 5px; border: 1px solid gray;}
.column1 { width: 170px; float: left; padding-bottom: 100px; }
.column2 {width: 500px; float: left; padding-bottom: 100px; }
.column3 { width: 170px; float: left; padding-bottom: 100px; }

.portlet { margin: 0 1em 1em 0; }
.portlet-header { margin: 0.3em; padding-bottom: 4px; padding-left: 0.2em; }
.portlet-header .ui-icon { float: right; }
.portlet-content { padding: 0.4em; }
.ui-sortable-placeholder { border: 1px dotted black; visibility: visible !important; height: 50px !important; }
.ui-sortable-placeholder * { visibility: hidden; }
.portlet-content {
    max-height:200px;
    _height:expression(this.scrollHeight>199?"200px":"auto");
    overflow:auto;
    overflow-x:hidden;
}
.hidden{display: none}
#header{margin-bottom: 5px; padding: 3px}
#header div{float: left;}
#menu2{float:left;}
br.clear{clear:both;}


dashboard.js

var portlets = ["feeds", "shopping", "news", "links", "images"];

$(document).ready(function () {
  $('#menu2').click(function(event) {
    $('#window_dialog').dialog({
        autoOpen: true,
        draggable: false,
        modal: true,
        title: 'Settings',
        buttons: {
            "Save": function () { 
              
              $(portlets).each(function() {
                set_window_visibility(this);
              });
              $(".column1").width(parseInt($('#c1-width').val()));
              $(".column2").width(parseInt($('#c2-width').val()));
              $(".column3").width(parseInt($('#c3-width').val()));
              $(this).dialog('destroy');
            },
            "Cancel": function () {
              $(this).dialog('destroy');
            }
        } 
      });
  });
  function set_window_visibility(name){
    if($('#'+name+'-visible').is(':checked'))
      $('#'+name+'-portlet').show();
    else
      $('#'+name+'-portlet').hide();
  }
  function set_visible_check(name){
    if($('#'+name+'-portlet').is(":visible"))
      $('#'+name+'-visible').each(function(){ this.checked = true; });
    else
      $('#'+name+'-visible').attr("checked", false);
  }
  $( "#settings_dialog" ).bind( "dialogopen", function(event, ui) {

  });
  $( "#window_dialog" ).bind( "dialogopen", function(event, ui) {
    $(portlets).each(function() {
      set_visible_check(this);
    });
    $('#c1-width').val($(".column1").width());
    $('#c2-width').val($(".column2").width());
    $('#c3-width').val($(".column3").width());
  });
});

$(function() {
  $( ".column1" ).sortable({
    connectWith: ".column1, .column2, .column3"
  });
  $( ".column2" ).sortable({
    connectWith: ".column1, .column2, .column3"
  });
  $( ".column3" ).sortable({
    connectWith: ".column1, .column2, .column3"
  });
  $( ".portlet" ).addClass( "ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" )
    .find( ".portlet-header" )
      .addClass( "ui-widget-header ui-corner-all" )
      .prepend( "<span  class='ui-icon ui-icon-closethick icon-close'></span><span class='ui-icon ui-icon-minusthick icon-vis'></span>")
      .end()
    .find( ".portlet-content" );

  $( ".icon-vis" ).click(function() {
    $( this ).toggleClass( "ui-icon-minusthick" ).toggleClass( "ui-icon-plusthick" );
    $( this ).parents( ".portlet:first" ).find( ".portlet-content" ).toggle();
  });
  $( ".icon-close" ).click(function() {
    //$( this ).toggleClass( "ui-icon-minusthick" ).toggleClass( "ui-icon-plusthick" );
    $( this ).parents( ".portlet:first" ).hide();
  });
  $( ".column" ).disableSelection();
});

Using dataforms with xmpp4r pubsub

I could not find an example anywhere for using data forms with xmpp4r pubsub feature. Here’s a working example. Note that I included only the publishing site of it since I’m using javascript for the subscribers.

#!/usr/bin/ruby

require 'rubygems'
require 'xmpp4r'
require "xmpp4r/pubsub"
require "xmpp4r/dataforms"
require "xmpp4r/pubsub/helper/servicehelper.rb"
require "xmpp4r/pubsub/helper/nodebrowser.rb"
require "xmpp4r/pubsub/helper/nodehelper.rb"
include Jabber

JID='smpallen99@xmpp'
PASSWD='test123'
SERVICE='pubsub.xmpp'
NODE='xmpp/ahearsion'

Jabber::debug = true

cl = Jabber::Client.new(Jabber::JID.new(JID))
puts "Connecting"
cl.connect
cl.auth(PASSWD)
cl.send(Jabber::Presence.new.set_priority(-1))

pubsub = PubSub::ServiceHelper.new(cl, SERVICE)

def create_node(pubsub)
  pubsub.create_node(NODE)
end

def publish(action, user, pubsub)
  item = Jabber::PubSub::Item.new
  
  fa = Jabber::Dataforms::XDataField.new("action")
  fa.value = action
  fu = Jabber::Dataforms::XDataField.new("user")
  fu.value = user
  
  df = Jabber::Dataforms::XData.new :result
  df.add(fa)
  df.add(fu)
  
  item.add(df)
  pubsub.publish_item_to(NODE, item)
end

cont = true
while cont
  puts "Enter your command (a |d |c|q) "
  input = gets
  tokens = input.split(" ")
  case tokens.first
  when "a"
    user = tokens[1]
    publish("activate", user, pubsub)
    puts "Activated #{user}\n"
  when "d"
    user = tokens[1]
    publish("deactivate", user, pubsub)
    puts "Deactivated #{user}\n"
  when "q"
    cont = false
    puts "quitting...\n"
  when "c"
    puts "Creating node...\n"
    create_node(pubsub)
  else
    puts "Don't understand command #{tokens.first}\n"
  end
  
end
cl.close