      1 (function ($, rf) {
      2
      3     rf.ui = rf.ui || {};
      4
      5     rf.ui.OrderingList = function(id, options) {
      6         var mergedOptions = $.extend({}, defaultOptions, options);
      7         $super.constructor.call(this, id, mergedOptions);
      8         this.namespace = this.namespace || "." + rf.Event.createNamespace(this.name, this.id);
      9         this.attachToDom();
     10         mergedOptions['scrollContainer'] = $(document.getElementById(id + "Items"));
     11         this.orderingList = $(document.getElementById(id));
     12         this.list = new rf.ui.ListMulti(id+ "List", mergedOptions);
     13         var hiddenId = mergedOptions['hiddenId'] ===null ? id + "SelValue" : mergedOptions['hiddenId'];
     14         this.hiddenValues = $(document.getElementById(hiddenId));
     15         this.selectItemCss = mergedOptions['selectItemCss'];
     16         this.disabled = mergedOptions.disabled;
     17
     18         this.upButton = $('.rf-ord-up', this.orderingList);
     19         this.upButton.bind("click", $.proxy(this.up, this));
     20         this.upTopButton = $('.rf-ord-up-tp', this.orderingList);
     21         this.upTopButton.bind("click", $.proxy(this.upTop, this));
     22         this.downButton = $('.rf-ord-dn', this.orderingList);
     23         this.downButton.bind("click", $.proxy(this.down, this));
     24         this.downBottomButton = $('.rf-ord-dn-bt', this.orderingList);
     25         this.downBottomButton.bind("click", $.proxy(this.downBottom, this));
     26
     27         this.focused = false;
     28         this.keepingFocus = false;
     29         bindFocusEventHandlers.call(this, mergedOptions);
     30
     31         if (mergedOptions['onmoveitems'] && typeof mergedOptions['onmoveitems'] == 'function') {
     32             rf.Event.bind(this.list, "moveitems", mergedOptions['onmoveitems']);
     33         }
     34         rf.Event.bind(this.list, "moveitems", $.proxy(this.toggleButtons, this));
     35
     36         rf.Event.bind(this.list, "selectItem", $.proxy(this.toggleButtons, this));
     37         rf.Event.bind(this.list, "unselectItem", $.proxy(this.toggleButtons, this));
     38
     39         rf.Event.bind(this.list, "keydown" + this.list.namespace, $.proxy(this.__keydownHandler, this));
     40
     41         if (options['onchange'] && typeof options['onchange'] == 'function') {
     42             rf.Event.bind(this, "change" + this.namespace, options['onchange']);
     43         }
     44
     45         // TODO: Is there a "Richfaces way" of executing a method after page load?
     46         $(document).ready($.proxy(this.toggleButtons, this));
     47     };
     48     rf.BaseComponent.extend(rf.ui.OrderingList);
     49     var $super = rf.ui.OrderingList.$super;
     50
     51     var defaultOptions = {
     52         defaultLabel: "",
     53         itemCss: "rf-ord-opt",
     54         selectItemCss: "rf-ord-sel",
     55         listCss: "rf-ord-lst-cord",
     56         clickRequiredToSelect: true,
     57         disabled : false,
     58         hiddenId : null
     59     };
     60
     61     var bindFocusEventHandlers = function (options) {
     62         if (options['onfocus'] && typeof options['onfocus'] == 'function') {
     63             rf.Event.bind(this, "listfocus" + this.namespace, options['onfocus']);
     64         }
     65         if (options['onblur'] && typeof options['onblur'] == 'function') {
     66             rf.Event.bind(this, "listblur" + this.namespace, options['onblur']);
     67         }
     68
     69         var focusEventHandlers = {};
     70         focusEventHandlers["listfocus" + this.list.namespace] = $.proxy(this.__focusHandler, this);
     71         focusEventHandlers["listblur" + this.list.namespace] = $.proxy(this.__blurHandler, this);
     72         rf.Event.bind(this.list, focusEventHandlers, this);
     73
     74         focusEventHandlers = {};
     75         focusEventHandlers["focus" + this.namespace] = $.proxy(this.__focusHandler, this);
     76         focusEventHandlers["blur" + this.namespace] = $.proxy(this.__blurHandler, this);
     77         rf.Event.bind(this.upButton, focusEventHandlers, this);
     78         rf.Event.bind(this.upTopButton, focusEventHandlers, this);
     79         rf.Event.bind(this.downButton, focusEventHandlers, this);
     80         rf.Event.bind(this.downBottomButton, focusEventHandlers, this);
     81     };
     82
     83
     84     $.extend(rf.ui.OrderingList.prototype, (function () {
     85
     86         return {
     87             name : "ordList",
     88             defaultLabelClass : "rf-ord-dflt-lbl",
     89
     90             getName: function() {
     91                 return this.name;
     92             },
     93             getNamespace: function() {
     94                 return this.namespace;
     95             },
     96
     97             __focusHandler: function(e) {
     98                 this.keepingFocus = this.focused;
     99                 if (! this.focused) {
    100                     this.focused = true;
    101                     rf.Event.fire(this, "listfocus" + this.namespace, e);
    102                 }
    103             },
    104
    105             __blurHandler: function(e) {
    106                 var that = this;
    107                 this.timeoutId = window.setTimeout(function() {
    108                     if (!that.keepingFocus) { // If no other orderingList "sub" component has grabbed the focus during the timeout
    109                         that.focused = false;
    110                         rf.Event.fire(that, "listblur" + that.namespace, e);
    111                     }
    112                     that.keepingFocus = false;
    113                 }, 200);
    114             },
    115
    116             __keydownHandler: function(e) {
    117                 if (e.isDefaultPrevented()) return;
    118                 if (! e.metaKey) return;
    119
    120                 var code;
    121                 if (e.keyCode) {
    122                     code = e.keyCode;
    123                 } else if (e.which) {
    124                     code = e.which;
    125                 }
    126
    127                 switch (code) {
    128                     case rf.KEYS.DOWN:
    129                         e.preventDefault();
    130                         this.down();
    131                         break;
    132
    133                     case rf.KEYS.UP:
    134                         e.preventDefault();
    135                         this.up();
    136                         break;
    137
    138                     case rf.KEYS.HOME:
    139                         e.preventDefault();
    140                         this.upTop();
    141                         break;
    142
    143                     case rf.KEYS.END:
    144                         e.preventDefault();
    145                         this.downBottom();
    146                         break;
    147
    148                     default:
    149                         break;
    150                 }
    151                 return;
    152             },
    153
    154             getList: function() {
    155                 return this.list;
    156             },
    157
    158             up: function() {
    159                 this.keepingFocus = true;
    160                 this.list.setFocus();
    161                 var items = this.list.getSelectedItems();
    162                 this.list.move(items, -1);
    163                 this.encodeHiddenValues();
    164             },
    165
    166             down: function() {
    167                 this.keepingFocus = true;
    168                 this.list.setFocus();
    169                 var items = this.list.getSelectedItems();
    170                 this.list.move(items, 1);
    171                 this.encodeHiddenValues();
    172             },
    173
    174             upTop: function() {
    175                 this.keepingFocus = true;
    176                 this.list.setFocus();
    177                 var selectedItems = this.list.getSelectedItems();
    178                 var index = this.list.items.index(selectedItems.first());
    179                 this.list.move(selectedItems, -index);
    180                 this.encodeHiddenValues();
    181             },
    182
    183             downBottom: function() {
    184                 this.keepingFocus = true;
    185                 this.list.setFocus();
    186                 var selectedItems = this.list.getSelectedItems();
    187                 var index = this.list.items.index(selectedItems.last());
    188                 this.list.move(selectedItems, (this.list.items.length -1) - index);
    189                 this.encodeHiddenValues();
    190             },
    191
    192             encodeHiddenValues: function() {
    193     			var oldValues = this.hiddenValues.val();
    194 				var newValues = this.list.csvEncodeValues();
    195 				if (oldValues !== newValues) {
    196 					this.hiddenValues.val(newValues);
    197 					rf.Event.fire(this, "change" + this.namespace, {oldValues : oldValues, newValues : newValues});
    198 				}
    199             },
    200
    201             toggleButtons: function() {
    202                 var list = this.list.__getItems();
    203                 if (this.disabled || this.list.getSelectedItems().length === 0) {
    204                     this.__disableButton(this.upButton);
    205                     this.__disableButton(this.upTopButton);
    206                     this.__disableButton(this.downButton);
    207                     this.__disableButton(this.downBottomButton);
    208                 } else {
    209                     if (this.list.items.index(this.list.getSelectedItems().first()) === 0) {
    210                         this.__disableButton(this.upButton);
    211                         this.__disableButton(this.upTopButton);
    212                     } else {
    213                         this.__enableButton(this.upButton);
    214                         this.__enableButton(this.upTopButton);
    215                     }
    216                     if (this.list.items.index(this.list.getSelectedItems().last()) === (this.list.items.length - 1)) {
    217                         this.__disableButton(this.downButton);
    218                         this.__disableButton(this.downBottomButton);
    219                     } else {
    220                         this.__enableButton(this.downButton);
    221                         this.__enableButton(this.downBottomButton);
    222                     }
    223                 }
    224             },
    225
    226             __disableButton: function (button) {
    227                  if (! button.hasClass('rf-ord-btn-dis')) {
    228                     button.addClass('rf-ord-btn-dis')
    229                 }
    230                 if (! button.attr('disabled')) {
    231                     button.attr('disabled', true);
    232                 }
    233             },
    234
    235             __enableButton: function(button) {
    236                 if (button.hasClass('rf-ord-btn-dis')) {
    237                     button.removeClass('rf-ord-btn-dis')
    238                 }
    239                 if (button.attr('disabled')) {
    240                     button.attr('disabled', false);
    241                 }
    242             }
    243         };
    244     })());
    245
    246 })(RichFaces.jQuery, window.RichFaces);
    247