« March 2009 | Main | May 2009 »

April 2009 Archives

April 3, 2009

How to vertically center images in jCarousel and Thickbox3.

jCarousel is a jQuery plugin for controlling a list of items in horizontal or vertical order. The items, which can be static HTML content or loaded with (or without) AJAX, can be scrolled back and forth (with or without animation).
jCarousel is a good solution for a scrolling gallery of thumbnail images, but it doesn't have a built-in feature to vertically center images of different size.
This how to is based on the special example of jCarousel working together with Thickbox 3.

This is the original code used to create the html of each item of the carousel:


/**
* Item html creation helper.
*/
function mycarousel_getItemHTML(item)
{
  var url_m = item.url.replace(/_s.jpg/g, '_m.jpg');
  return '<a href="' + url_m + '" title="' + item.title + '"><img src="' + item.url + '" width="75" height="75" border="0" alt="' + item.title + '" /></a>';
};

Let's modify it using the jQuery Image, a Javascript object :


function mycarousel_getItemHTML(item)
{
  var url_m = item.url.replace(/_s.jpg/g, '_m.jpg');
  var img = new Image();
  $(img).attr('src', item.url).attr('title',item.title).attr('alt',item.title).css('border','0');
  return $('<a href="' + url_m + '" title="' + item.title + '"></a>').append(img);
};

Now it is possible to add an onload function as explained in this article.
When the image is downloaded we can work with its width and height and align it vertically:


function mycarousel_getItemHTML(item)
{
  var url_m = item.url.replace(/_s.jpg/g, '_m.jpg');
  var img = new Image();
  $(img).load(function () {
    $(this).hide();
    /* $(this).parent() is the <a> element,
     $(this).parent().parent() is the carousel item container */
    $(this).css('margin-top', ($(this).parent().parent().height()-$(this).height())/2);
    $(this).fadeIn();
  }).error(function () {
     // notify the user that the image could not be loaded
  }).attr('src', item.url).attr('title',item.title).attr('alt',item.title).css('border','0');
  return $('<a href="' + url_m + '" title="' + item.title + '"></a>').append(img);
};

In the same way it is possible to modify the horizontal alignment of the image:


  $(this).css('margin-left', ($(this).parent().parent().width()-$(this).width())/2);

It is also possible to change the height and width attribute of the Image object to fit images to the container. With some other tricks you could also create your personal loading animation.

April 6, 2009

Comtaste partners with SpringSource to deliver Spring training

SpringSource_logo.png

I am glad to announce that Comtaste has recently signed a partnership agreement with SpringSource, the proven leader in creating lean software products that dramatically improve productivity and cut complexity of enterprise Java applications on the basis of the open source Spring platform (the de facto standard programming model for enterprise Java applications).

As a result, Comtaste today is the only organization officially entitled to promote and deliver the SpringSource's training courses in Italy.

Here are the next Italian editions:

* Rich Web Applications with Spring: Rome 21-24 Apr '09

* Core Spring: Milan, 5-8 May '09 and Rome 16-19 June '09

* Enterprise Integration with Spring Training: Rome, 19-22 May '09

For further info, please visit www.comtaste.com/en/training

Continue reading "Comtaste partners with SpringSource to deliver Spring training" »

April 17, 2009

Rich Interactive Applications restyling: A matter of usability

When you have to plan a Rich Internet Application from the start it’s quite easy, i mean that you have the freedom to follow the right workflow in order to guarantee your clients the best results. You can think about target, markets, you can plan the navigation and design the interface taking care of every important rules, but what happen when you find yourself in front an already made application and someone ask you to do the restyling?

Most of the time talking with clients it’s not so simple to make them understand that a very important part of an application is usability, that is not only a matter of “this or that color, this or that icon”, so in those cases we must work hard doing our best to get a good compromise between “the best and the worst”.

When we look to an application that we haven’t planned, the first thing is to see how the navigation works and what this application is supposed to do, how it is the interaction with the end users, if it’s handy or complicated to follow, then we can start to find some solutions to fix the problems about usability and, at the same time, we should give some advices about the look and feel of the entire application.

If there is enough time before the final deploy we can create graphical skins for components using Adobe Illustrator, Flash or Fireworks or we can change styles of component using CSS approach in Flex. This is the best choice if there is no time to create graphics and there are even good links to help us when we are in a hurry:)

The CSS style explorer of Adobe Flex is a big help when you want to be fast, it shows in real time how the style of a component can change and, after you have defined your own style, it is possible to copy and paste the code in your application

img1.gif

img2.gif

The same thing happen with the Components explorer, here we can see how most of the standard components we use in our RIAs are made

img3.gif

img4.gif

The difficult thing being a user interface designer or a designer in general, is to make people understand that our job is made of different parts, that we take care of some practical aspects not only of “esthetic”. We design, but first of all we follow a process which includes theory before practice.

April 27, 2009

Multiple field filtering with ArrayCollection

The flex class ActionScript has a very useful method, filterFunction, that allows to pass as a parameter another function, to be applied as a filter for the data. The filter is effectively applied only after we invoke refresh() on the ArrayCollection. The result is well known: the collection will only show those items that match the filter function, while all elements, filtered or not, can be accessed from the list or source properties of the collection.

Suppose we have a collection of objects with many properties, and we want to filter on a few properties at a time, not always the same. For example we could have the class AirplaneReservation, with a subset of the properties similar to:

public var firstName:String;
public var lastName:String;
public var gender:Number;
public var reservationDate:Date;
public var destination:String;
public var departure:String;
public var seat:String;
public var menuType:Number;

and we want to filter on whatever combination of properties, using a Form component to display them all to the user.

We could create as many filter functions as our use cases, which can be a lot to handle, or we could use different approaches, tweaking the flex framework to our needs. Rotundu made a post about multiple field filtering, that can be found here, by extending the ActionScript class and adding an array of filter functions, to be eventually applied as a single one.

The approach illustrated here is similar, in that it uses many filter functions, but different in that it does not extend ArrayCollection and associates a filter function with a field of our collection object.

We can create the Form component, with input fields for every filter (TextInput, NumericStepper and so on) and, on the change event, call a single function:

<mx:TextInput id="firstName" change="applyFilter('firstName', firstName.text)" />

In most of the cases we can use a single applyFilter() function, that receives in input the name of the property to be filtered and its value. This function will then create an ad hoc filter function and apply it to our collection. We will make use of a Dictionary to associate a field with its filter function:

private function applyFilter(field:String, value:*):void {
var f:Function;
if ((value == null) || (value.length == 0))
f = null;
else {
f = function(item:Object):Boolean {
if ((item == null) || !item.hasOwnProperty(field))
return false;

if (item[field] is Boolean)
return Boolean(item[field]) == value;
if (item[field] is Number)
return Number(item[field]) == value;
if (item[field] is String)
return String(item[field]).localeCompare(value) == 0;
if (item[field] is Date)
return Date(item[field]).time == Date(value).time;
// any other object:
return item[field] == value;
};
}

_filterFunctions[field] = f;

_collection.filterFunction = multipleFilter;
_collection.refresh();
}

This will create a filter function for the field received in input, store it in the Dictionary so that it will be available for multipleFilter():

private function multipleFilter(item:Object):Boolean {
for (var key:Object in _filterFunctions) {
var f:Function = _filterFunctions[key];
if ((f != null) && !f(item))
return false;
}

return true;
}

We can now filter as many fields as we want, at the same time, using these two functions only. The applyFilter function can easily be adapted to custom business objects, by means of object polymorphism and interfaces (Java’s Comparable is a good example).

About April 2009

This page contains all entries posted to Comtaste Consulting | Enterprise RIA consulting and development in April 2009. They are listed from oldest to newest.

March 2009 is the previous archive.

May 2009 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33