A new Group Manager UI for Sakai and Vula

Posted by Lovemore Nalube on 04 March, 2010 10:40

Introduction

I have written code to make the management of adhoc groups easier, all in pure HTML (no RSF, no JSF, no JAVA). Using Entity Broker and JavaScript, I have introduced more contemporary methods to adding, removing and replacing user membership at group level.

Problem case:

Currently the UI for managing adhoc groups (Site Setup > Adhoc Groups) is clunky, unsearchable and very difficult to use for large groups ( > 100 members).

Current UI:

 

Solution:

I propose this UI:

 

Features:

  1. Facebook-like name picker (auto completer),
  2. Paste multiple usernames,
  3. Easily select users by filtering based on their last names eg: Type "a" to show only those that begin with "a", "ab" for those that begin with "ab", and so on...,
  4. Remove individuals by a one-click action,
  5. most importantly; be able to UNDO your last action.
View the screen cast

Download a high quality version at: https://vula.uct.ac.za/access/content/public/help/video/group%20manager%20cast-0.m4v

View the streaming video online: http://meeting.uct.ac.za/sakai-group-manager/

Technical: How to implement this in your sakai 2.6.x instance

  1. Update your EnityBroker using the patch at: http://jira.sakaiproject.org/browse/SAK-17471
  2. Get the html/javascript code: svn export http://source.cet.uct.ac.za/svn/sakai/uct-skins/trunk/library/content/uct/groupHelper groupHelper
  3. Copy the groupHelper folder into your sakai /library/ folder so that it is accessible via a url like this: {server}/library/groupHelper/adhoc_group_selector.html
  4. Use the Web Content tool in sakai to drop this into a site. Ensure you have the content path set to: {server}/library/content/uct/groupHelper/adhoc_group_selector.html?site=${SITE_ID}      Sakai will substitute ${SITE_ID} for the actual site ID at runtime. The code needs this parameter to work.

FYI, ONLY if the ${SITE_ID} parameter does not translate to a proper site ID as expected, do this:

  • Add this property to the Site in the Admin Tool > Sites: iframe.allowed.macros=${SITE_ID}

That's it.

Drop a comment for any questions/issues/suggestions.

 

 

Consuming a Sakai Java Messages Resource Bundle in Javascript with Fluid - i8n

Posted by Lovemore Nalube on 28 September, 2009 15:24

Many a time I have found myself feeling oh so guilty for NOT internationalising the strings in my Javascript code. There seemed to be no sure-fire way to do a simple call, in Javascript, like
messageLocator.getString("key", args)

..... until now :)

There are a few factors to chat about before considering this solution:

  1. Javascript does not pick up the proper locale. Sakai message language bundle calls are based on server locale unless a user has an override of this under Sakai Preferences. Javascript will only get the navigator object's property equaling the localised version of the web browser was installed ie:
    navigator.language /* Mozilla */ || navigator.userLanguage /* IE */ 
    This is not necessarily the same thing as the user's preferred language(s) see: http://stackoverflow.com/questions/673905/best-way-to-determine-users-locale-within-browser
  2. By defaut, the message bundles are not URI accessible as they do not deploy to a visible tomcat directory. Of course this can be solved by maven's copy-resource plugin, see: http://maven.apache.org/plugins/maven-resources-plugin/copy-resources-mojo.html

Getting inspiration from Nuno Fernendes's approach to solving this dilema see: http://codingwithcoffee.com/?p=272, I learnt the following:

  1. Replicating the way spring/rsf selects the appropriate message_*.properties file to load is a taxing feat with javascript.
    Nuno fixed this case by loading all *.properties files via individual AJAX queries and then filtering based on the browser's navigator property.

  2. Having the bundle keys as javascript objects will not work in case the keys contain javascript keywords (no pun intended) e.g: var, delete. Nuno's jQuery.i18n.properties version 1.0.2 implements a 'map' object to counter this issue.


So finally, my proposal is to use the EntityBroker to expose the right bundle and the javascript fetches it and encodes it into a Fluid Infusion  based object. To decode a key will be as easy as calling
fluid.messageLocator( messageBundle )([key], params)  //returns the equivalent string value of the language key.

Fluid will handle message string formatting in the messageLocator function, see: http://wiki.fluidproject.org/display/fluid/Framework+Functions#FrameworkFunctions-fluid.messageLocator(messageBase)

Technically speaking, these would be the steps involved:

Step 1 - in Java: Using EntityBroker, write tool level EntityProvider that loads a resource loader. ie:

ResourceLoader resourceLoader = new ResourceLoader(MESSAGES_BUNDLE_DIR); // eg. where  MESSAGES_BUNDLE_DIR = "org.sakaiproject.evaluation.tool.bundle.messages";             *** NEEDS TO BE A FOLDER!

return the key-value equivalents of resourceLoader.entrySet().iterator(); in (for example) HashMap.

Step 2 - in Java: Modify the poms to include the entitybroker-utils ie:

<dependency>
    <groupId>org.sakaiproject.entitybroker</groupId>
    <artifactId>entitybroker-utils</artifactId>
    <version>[1.3.3,1.4.0)</version>
</dependency>    

Step 3 - in Javascript: Load the Fluid Infusion library from http://wiki.fluidproject.org/display/fluid/Downloads

You only need load the fluid.js file.

Step 4 - in Javascript: In your own javascript file, at $(document).ready, call the EntityProvider URI we made in Step 1 via an AJAX request. Make sure to switch on caching. Like so:

       $.ajax({
            url: entityProviderURI,
            global: false,
            cache: true,
            dataType : "json",
            success: function(messageBundleJSON){
                messageBundle = messageBundleJSON.data;
            }
        });

As you can tell, I have chosen to request a JSON response with a data object containing the key-string matches. This makes it easy for Fluid to format.This is what myJSON object looks like:

{
  "data": {
    "evalresponders.notifications.link": "Send email message to {0} participants",
    "modifytemplate.item.na.title": "Include a 'not applicable' option for this question.",
    "controlevaluations.eval.link.title": "Quick link:",
     :
     :
    "removeitem.removed.user.message": "Item ({0}) has been removed",
    "modifytemplate.check.placeholder": "x",
    "administrate.general.enable.response.removal": "Allow responses to surveys to be removed",
    "modifytemplate.itemtype.expert": "Suggested"
  },
  "displayTitle": "message-bundle",
  "entityId": null,
  "entityProperties": {
  },
  "entityReference": "\/eval-resources",
  "entityURL": "http:\/\/lovemore-nalube.chd.uct.ac.za:8080\/direct\/eval-resources"
}

 Step 5 - in Javascript: in the same javascript file where access to the messageBundle variable is global,you can call any key value by saying (for example):

// Decoding the key "administrate.general.enable.response.removal". RESULT  removalString = "Allow responses to surveys to be removed"

var removalString = fluid.messageLocator( messageBundle )(["administrate.general.enable.response.removal"]);

 

*** For values with variable replacers like {0}  as in removeitem.removed.user.message: "Item ({0}) has been removed",

// Decoding the key "removeitem.removed.user.message". RESULT  removalString = "Item (3) has been removed"

var removalString = fluid.messageLocator( messageBundle )(["removeitem.removed.user.message"], 3 );

 
That's it! I have used this in the Sakai Course Evaluations tool with success.

An effective jQuery Date Time picker

Posted by Lovemore Nalube on 25 February, 2009 11:57

It has been a couple of weeks since my search for a 'cool' web 2.0 widget that can help populate not only a date field but a time field as well.In this post I intend to explore ways in which a suitable UI component can be found to solve this problem.

jQuery has a pretty swell date picker from their UI library and there are thoughts of extending it's current state to include more options, CSS flexibility and functional capabilities. All this is welcome development but lacks the addition of a time picker.

The Fluid Project is currently working on a Date/Time picker utilising tabs to separate date and time selectors (picture below).Fluid Date-Time picker

The jQuery Calendar by extended by Keith Wood (picture below) tried to represent a UI to select time, but the principle of using dropdowns just seems to crowd the widget at the end. Besides, there must be more intuitive ways of selecting figures than by using drop downs.

The jQuery Calendar by extended by Keith Wood

 The other proposal is by Maxime Haineault (haineault.com) in his jquery.timepickr.js library (pictured below). This is a good idea and is an interface that would really look good on Iphone/touchscreen mobile. The 'buttons' for the time digits are a nice variation from the drop down/selectable element ideas as used in the above examples. This plugin is discussed at http://ajaxian.com/archives/time-picker-ui

Maxime Haineault (haineault.com) in his jquery.timepickr.js library

Now I'd like to explore my initial ideas around a effective Time-picker extending on the jQuery UI Date picker and incorporating the jQuery UI Slider.

I propose that the easiest way to select numbers from a list would be via a slider. It has been used effectively to select numbers in may applications (native OS apps) and thanks to jQuery UI this extensiveness can now to used on the web (of course!).Therefore here is a work in progress snapshot of how the time picker component would look:

Work on the Date-time picker

Naturally a little more customisaztion of the drag image is possible. The sliders snap to times in between the labeled numbers. This would be to avoid overcrowding the UI, overwhelming the user and loosing UI's cleaness/simplicity.

 When it is plugged into the calendar component, this is what we get:

An effective jQuery Date Time picker

 The code is not yet ready; it's just a concept (for now). Updates to come in a few days!!

UPDATE 1:

I've done some preliminary work on the timepicker component alone. Thankfully I have access to an SVN repo and have stuck the project at:

http://source.cet.uct.ac.za/svn/sakai/ux/timepicker

Feel free to checkout and run "index.html" Track the logs as well to keep up to date with the development.

Used: jQuery UI 1.7 with jQuery 1.3

 

 

Post fckeditor form with ajax - Solved!

Posted by Lovemore Nalube on 27 October, 2008 12:42

So, the question at hand is how to submit a form with an FCK editor via AJAX. Someone else using Mootools put it like this:

"Hope somebody is familiar with FCKeditor. When i post a fckeditor textarea with an ajax function it comes up empty on the target page. Everything else in the form works just fine. My ajax function works, so maybe its got something to do with fckeditor. Has anyone else got this problem and how do i solve it?" - http://forum.mootools.net/topic.php?id=2554

I used jQuery in my solution but this method should work with any library out there.

The trick is to intercept the querystring, filter through the array of objects and replace the object containing the unupdated value. Like this (on form submoit event):

    //Using the jQuery Form plugin, create an array from form DOM elements

    var d = $("#form-id").formToArray();

    //Actual editor textarea value that is entered into the FCKeditor

    var fckVal = FCKeditorAPI.GetInstance('field-name').GetHTML();     //the field name is NOT the field's id

    //iterate through returned formToArray elements and replace input value with editor value


    for (var i = 0; i < d.length; i++) {
        if ($(d[i]).attr('name') == 'item-text:1:input') {
            $(d[i]).attr('value',fckVal);
        }
    }


    $.ajax({
        type: 'POST',
        url: 'target-page',
        data: d
        });

 

This will fix the bug. All comments are welcome esp. if you're having problems after this patch.

Virgin

Posted by Lovemore Nalube on 18 August, 2008 13:10

Ok.

So this is my first mark on ANY UCTconduit - it feels awesome!

So far so good.

 Will blog some more later. Gots to churn some code.

Welcome to Lovemore's World

01419110

Categories

Links

  • General

recently...

archives

Syndicate