Document Information

Last modified:
2009/09/11 13:04 by chris_schmidt

New Selection API

This article describes the proposed New Selection API for qooxdoo 0.8.3 and beyond. If you use qooxdoo 0.8.2 or less, see the documentation of the previous selection handling.

The framework contains a couple of widgets which support selection handling. These are divided into widgets that support Single Selection and others that support Multi Selection. A widget which supports multi selection also supports single selection.

Here is a list of widgets which support single and/or multi selection:

What was wrong with the old API?

The old selection API had different methods for single and multi selection and partially different events, because an interface describing the specification was missing. To offer a consistend API an interface specification was needed. The standardization has shown, that having only one interface for single and multi selection is not enough, because it would be possible to have different events for multi and single selection (remember all multi selection widgets also supports single selection).

One possible solution was to have the same methods and events for single and multi selection. This is possible if the single and multi selection both work with arrays. Due to that fact it is possible to change widgets without having to worry about the selection method, because the method and event names don’t change.

Selection Interfaces

Selection API Interfaces

Event

Both selections fire a changeSelection event if the selection has changed. Listeners can register the event to be notified about the changes. The event contains an array with the new selected widgets. If the array is empty no widgets are selected.

Selection Methods

The ISingleSelection interface specifies the methods for single selection handling. Since the methods of the single selecting interface are re-used, the IMultiSelection only extends the interface with methods for multi selection handling.

The re-suing of the methods requires a uniform handling for setting and getting the current selection. This has been achieved by using an array for the selection handling, see setSelection and getSelection.

Single Selection

The listed single selection widgets above implement the ISingleSelection. To implement the behavior they use the MSingleSelectionHandling mixin. The mixin offers the methods for selection handling and it also initialize the manager for selection management.

The widget itself configures the mixin for allowing an empty selection or not. Dependent on the configuration, the resetSelection clears the current selection (empty array) or selects the first selectable element.

The user interactions (mouse and keyboard) are managed from the widget, which only calls the selection methods if the user interaction has an effect on the selection. So the selection management and the user interaction handling are separated. This is one thing that has changed with the new selection API.

Multi Selection

The multi selection implementation has hardly changed. The widgets supporting multiselection, also listed above, have already used a mixin called MSelectionHandling for selection handling. It offers, like the mixin for the single selection, the methods for selection and initializes the selection manager. The mixin has only been changed to be conform to the new IMultiSelection interface.

Due to the small changes the configuration for the selection mode hasn’t changed. The widgets also suport the property selectionMode with these different modes:

  • single: Only one element or none at all can be selected.
  • one: Exactly one item is selected if possible. The first selectable item is selected per default.
  • multi: Multiple items can be selected by using the modifier keys together with mouse or keyboard actions. This type also allows empty selections.
  • adaptive: Easy Web-2.0 selection mode: multiple items can be selected without modifier keys. Empty selections are possible.

How to use the new selection API

Single Selection

The example below shows how to use the single selection API, this example uses the SelectBox widget:

// creates the SelectBox
var selectBox = new qx.ui.form.SelectBox();
this.getRoot().add(selectBox, {top: 20, left: 20});
 
// registers the listener
selectBox.addListener("changeSelection", function(event) {
  this.debug("Selected (event): " + event.getData()[0].getLabel());
}, this);
 
// creates the items and select one of them
for (var i = 0; i < 10; i++)
{
  var item = new qx.ui.form.ListItem("ListItem" + i);
  selectBox.add(item);
 
  if (i == 5) {
    selectBox.setSelection([item]);
  }
}
 
this.debug("Selected (selectBox): " + selectBox.getSelection()[0].getLabel());

The output should be:

(1) Selected (event): ListItem0
(2) Selected (event): ListItem5
(3) Selected (selectBox): ListItem5

The SelectBox’s implemention doesn’t allow empty selections, so if the first item is added to the SelectBox it will be selected (1). (2) occurs, due to the selection and (3) from getSelection.

Multi Selection

The next example uses the List widget:

// creates the List and sets the selection mode
var list = new qx.ui.form.List();
list.setSelectionMode("multi");
this.getRoot().add(list, {top: 20, left: 20});
      
// registers the listener
list.addListener("changeSelection", function(event) {
  this.debug("Selection (event): " + event.getData());
}, this);
      
// creates the items
for (var i = 0; i < 10; i++)
{
  var item = new qx.ui.form.ListItem("ListItem" + i);
  list.add(item);
}
      
// sets selection
list.setSelection([list.getChildren()[1], list.getChildren()[4]]);
      
this.debug("Selection (list): " + list.getSelection());

The output could look like this:

(1) Selection (event): qx.ui.form.ListItem[1p],qx.ui.form.ListItem[2a]
(2) Selection (list): qx.ui.form.ListItem[1p],qx.ui.form.ListItem[2a]

How to migrate from the old to the new selection API

The old selection API is set to deprecated. This mean that the old selection API can still be used, but deprecation warnings occur in the source version of the application. So the old code runs with using the old selection API, but in the future the deprecated methods will be removed, so please change as soon as possible to the new selection API.

By changing the framework applications, like the Demo Browser, to the new selection API, useful steps have been found:

  1. Search for only one widget, that use the old selection API, in the source code.
  2. Replace the old method/event with the new one, but only for the classes that contains a reference from the widget.
  3. Run generate.py source, start the application and test your changes.
  4. If the application runs without errors go to step one and chose the next widget, otherwise fix the problem.
  5. If you have searched for all widget and renamed the old methods/events in these classes, search for the old method/event-names in the complete source code and rename them, if they are really using the old API.
  6. Run generate.py source, start your application and test your changes again.
  7. If there are now errors or deprecation warnings by testing your code, you have finished the migration.

What does 'rename' the method/event mean?

It means to replace the old method/event names with the new method/event names, but don’t forget to customize the method parameter and return values!!! If you only rename the method/event-names you will get many errors!!!

The examples below show some use cases, for renaming the old methods/events.

All examples started with step (1) searching for qx.ui.form.SelectBox. We found the variable __group that references a SelectBox instance.

Example for renaming 'setSelected' to 'setSelection'
  this.__group.setSelected(firstItem);
 
  /*
   * To rename this method, we have to change the method 'setSelected'
   * to 'setSelection' and putting the 'firstItem' into an array.
   */
 
  this.__group.setSelection([firstItem]);
Example renaming 'getSelected' to 'getSelection'
  var selectedGroup = this.__group.getSelected();
 
  /*
   * To rename this method, we have to change the method 'getSelected'
   * to 'getSelection' and select the first element from the returned array.
   */
 
  var selectedGroup = this.__group.getSelection()[0];
Example renaming 'changeSelected' to 'changeSelection'
  this.__group.addListener("changeSelected", function(event) {
    var selectedGroup = event.getData();
  });
 
  /*
   * To rename that event, we have to change the event 'changeSelected'
   * to 'changeSelection' and select the first element from the data array.
   */
 
  this.__group.addListener("changeSelection", function(event) {
    var selectedGroup = event.getData()[0];
  });

Be careful with mindless renaming methods and events, because an error only occurs if the code part is executed.

So if you are not sure that the method or event is the right to rename, then add a TODO comment and rename it later, by trying to execute this code part, if this is relay a old method/event a deprecation warning occurs.

Information

Last modified:
2009/09/11 13:04 by chris_schmidt

Account

Not logged in

 
 

Rich Ajax Platform (RAP)

RAP uses qooxdoo, Java and the Eclipse development model to build rich web applications. Read more...

qooxdoo Web Toolkit (QWT)

Similar to GWT this framework allows to create impressive qooxdoo applications just using Java. Read more...

Pustefix

Pustefix is a MVC-based web application framework using Java and XML/XSLT. Read more...

 
SourceForge.net Logo

Bad Behavior has blocked 0 potential spam attempts in the last 7 days.