Strange multiselect in Flex lists

With old halo lists mx:List you can allow the user to select multiple list items. Set allowMultipleSelection = true and you can add single items to the selected group via Ctrl + Click. Via Shift + Click you can select a set of items. Click on one item to select the first and then Shift + Click on another one to select the whole range of items between the first and last one (each included).

Nothing unexpected so far.

But if you do another Shift + Click to change the selected range, the Flex list reacts strangely. For example, say you’ve clicked on item 3 and then Shift + clicked on item 5, you select items 3 to 5. But what happens when you Shift + click on item 7 afterwards? Windows Explorer and MacOS X Finder will select items 3 to 7. If you then Shift + click on 1, they select 1 to 3. So, the general rule for those standard item lists is that you set an anchor with the first click and each following Shift + click selects all items between this anchor and the last clicked item.

But not so in the Flex list. mx:List resets the anchor with every Shift + click to the last clicked item. The following table highlights the described differences between Explorer/Finder and the Flex list:

Action Explorer Finder mx:List
click 3 3 3 3
shift+click 5 3-5 3-5 3-5
shift+click 7 3-7 3-7 5-7
shift+click 1 1-3 1-3 1-7

I think this is very confusing for the user, because there is no obvious reason for the flex lists to behave in a different way than the corresponding native lists of the operating system. So I wrote the following patch to fix this:

import mx.collections.CursorBookmark;
import mx.controls.List;
import mx.controls.listClasses.IListItemRenderer;

public class OSLikeList extends List {

    private var firstShiftClick:Boolean = true;
    private var oldAnchorBookmark:CursorBookmark;
    private var oldAnchorIndex:int;

    public function OSLikeList() {
        super();
    }

    override protected function selectItem(item:IListItemRenderer, shiftKey:Boolean, ctrlKey:Boolean, transition:Boolean = true):Boolean {
        if (shiftKey && allowMultipleSelection) {
            if (firstShiftClick) {
                oldAnchorBookmark = anchorBookmark;
                oldAnchorIndex = anchorIndex;
                firstShiftClick = false;
            } else {
                anchorIndex = oldAnchorIndex;
                anchorBookmark = oldAnchorBookmark;
            }
        } else {
            firstShiftClick = true;
        }
        return super.selectItem(item,  shiftKey, ctrlKey, transition);
    }

}
Advertisements

Flex application not redrawing screen

From time to time we observe issues with the Pepper player, the built-in Flash player of the Chrome browser. Since January we fight against the problem that our Flex application is not properly redrawing the screen after user interaction.

Fortunately, we stumbled across this issue in the chromium bug database. According to the comments there we have to force the refresh of the application. Of course, we should do this for the Pepper player only, but this is not a great deal. The Adobe online help states how to detect a Pepper player.

Solution

First we check if the user has a Pepper player. In this case we create a timer which calls every 500 ms invalidateDisplayList() on the main Application object.

private static var _refreshTimer:Timer;

public static function checkPepperPlayer(app:Application):void {
    if (Capabilities.manufacturer === "Google Pepper" && !_refreshTimer) {
        _refreshTimer = new Timer(500);
        _refreshTimer.addEventListener(TimerEvent.TIMER, function(event:TimerEvent):void {
            app.invalidateDisplayList()
        });
        _refreshTimer.start();
    }
}

Flash Container Height in IE10

Recently we had a problem with our flash client container within Internet Explorer 10. Within the CSS the height and width of the container is set to 100% to consume all available space. Firefox, Chrome, Opera and IE (pre version 10) have no problem to size the flash container correctly. However, IE 10 shows the flash container about 30% of the height while consuming 100% of the width. The div container has 100% in height, but the included embed object has not.

Our html source looks like:

<div style="height: 100%; width: 100%;">
  < embed id="RewooClient" width="100%" height="100%"
    type="application/x-shockwave-flash" name="Rewoo" src="Rewoo.swf"
    allowfullscreeninteractive="true" allowscriptaccess="sameDomain" >
    <!-- ... -->
  </embed>
</div>

Internet searches did not help. It seems that nobody else have this problem. The pragmatic solution was to use jQuery to set the height manually on page load and on page resizes:

(function($) {
$(document).ready(function() {
  if ($.browser.msie && $.browser.version >= 10) {
    $('#RewooClient').attr('height', $(window).height());
    $(window).resize(function() {
      $('#RewooClient').attr('height', $(window).height());
    });
  }
})(jQuery);

[update 2013-05-13] Starting with jQuery 1.9 the $.browser feature was removed and you need to add the jQuery Migration plugin to get the code working again (Thanks to Ed Graham)[/update]

Maybe this might help you… And if you know a better solution, please drop a line.