      1 (function ($, rf) {
      2
      3     rf.ui = rf.ui || {};
      4
      5     rf.ui.PickList = 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 + "SourceItems"));
     11         this.sourceList = new rf.ui.ListMulti(id+ "SourceList", mergedOptions);
     12         mergedOptions['scrollContainer'] = $(document.getElementById(id + "TargetItems"));
     13         this.selectItemCss = mergedOptions['selectItemCss'];
     14         var hiddenId = id + "SelValue";
     15         this.hiddenValues = $(document.getElementById(hiddenId));
     16         mergedOptions['hiddenId'] = hiddenId;
     17         this.orderable = mergedOptions['orderable'];
     18
     19         if (this.orderable) {
     20             this.orderingList = new rf.ui.OrderingList(id+ "Target", mergedOptions);
     21             this.targetList = this.orderingList.list;
     22         } else {
     23             this.targetList = new rf.ui.ListMulti(id+ "TargetList", mergedOptions);
     24         }
     25         this.pickList = $(document.getElementById(id));
     26
     27         this.addButton = $('.rf-pick-add', this.pickList);
     28         this.addButton.bind("click", $.proxy(this.add, this));
     29         this.addAllButton = $('.rf-pick-add-all', this.pickList);
     30         this.addAllButton.bind("click", $.proxy(this.addAll, this));
     31         this.removeButton = $('.rf-pick-rem', this.pickList);
     32         this.removeButton.bind("click", $.proxy(this.remove, this));
     33         this.removeAllButton = $('.rf-pick-rem-all', this.pickList);
     34         this.removeAllButton.bind("click", $.proxy(this.removeAll, this));
     35         this.disabled = mergedOptions.disabled;
     36
     37         if (mergedOptions['onadditems'] && typeof mergedOptions['onadditems'] == 'function') {
     38             rf.Event.bind(this.targetList, "additems", mergedOptions['onadditems']);
     39         }
     40         rf.Event.bind(this.targetList, "additems", $.proxy(this.toggleButtons, this));
     41
     42         this.focused = false;
     43         this.keepingFocus = false;
     44         bindFocusEventHandlers.call(this, mergedOptions);
     45
     46         // Adding items to the source list happens after removing them from the target list
     47         if (mergedOptions['onremoveitems'] && typeof mergedOptions['onremoveitems'] == 'function') {
     48             rf.Event.bind(this.sourceList, "additems", mergedOptions['onremoveitems']);
     49         }
     50         rf.Event.bind(this.sourceList, "additems", $.proxy(this.toggleButtons, this));
     51
     52         rf.Event.bind(this.sourceList, "selectItem", $.proxy(this.toggleButtons, this));
     53         rf.Event.bind(this.sourceList, "unselectItem", $.proxy(this.toggleButtons, this));
     54         rf.Event.bind(this.targetList, "selectItem", $.proxy(this.toggleButtons, this));
     55         rf.Event.bind(this.targetList, "unselectItem", $.proxy(this.toggleButtons, this));
     56
     57         if (mergedOptions['switchByClick']) {
     58             rf.Event.bind(this.sourceList, "click", $.proxy(this.add, this));
     59             rf.Event.bind(this.targetList, "click", $.proxy(this.remove, this));
     60         }
     61
     62         if (mergedOptions['switchByDblClick']) {
     63             rf.Event.bind(this.sourceList, "dblclick", $.proxy(this.add, this));
     64             rf.Event.bind(this.targetList, "dblclick", $.proxy(this.remove, this));
     65         }
     66
     67         if (options['onchange'] && typeof options['onchange'] == 'function') {
     68             rf.Event.bind(this, "change" + this.namespace, options['onchange']);
     69         }
     70
     71         // TODO: Is there a "Richfaces way" of executing a method after page load?
     72         $(document).ready($.proxy(this.toggleButtons, this));
     73     };
     74     rf.BaseComponent.extend(rf.ui.PickList);
     75     var $super = rf.ui.PickList.$super;
     76
     77     var defaultOptions = {
     78         defaultLabel: "",
     79         itemCss: "rf-pick-opt",
     80         selectItemCss: "rf-pick-sel",
     81         listCss: "rf-pick-lst-cord",
     82         clickRequiredToSelect: true,
     83         switchByClick : false,
     84         switchByDblClick : true,
     85         disabled : false
     86     };
     87
     88     var bindFocusEventHandlers = function (options) {
     89         // source list
     90         if (options['onsourcefocus'] && typeof options['onsourcefocus'] == 'function') {
     91             rf.Event.bind(this.sourceList, "listfocus" + this.sourceList.namespace, options['onsourcefocus']);
     92         }
     93
     94         if (options['onsourceblur'] && typeof options['onsourceblur'] == 'function') {
     95             rf.Event.bind(this.sourceList, "listblur" + this.sourceList.namespace, options['onsourceblur']);
     96         }
     97
     98         // target list
     99         if (options['ontargetfocus'] && typeof options['ontargetfocus'] == 'function') {
    100             rf.Event.bind(this.targetList, "listfocus" + this.targetList.namespace, options['ontargetfocus']);
    101         }
    102         if (options['ontargetblur'] && typeof options['ontargetblur'] == 'function') {
    103             rf.Event.bind(this.targetList, "listblur" + this.targetList.namespace, options['ontargetblur']);
    104         }
    105
    106         // pick list
    107         if (options['onfocus'] && typeof options['onfocus'] == 'function') {
    108             rf.Event.bind(this, "listfocus" + this.namespace, options['onfocus']);
    109         }
    110         if (options['onblur'] && typeof options['onblur'] == 'function') {
    111             rf.Event.bind(this, "listblur" + this.namespace, options['onblur']);
    112         }
    113
    114         this.pickList.focusin($.proxy(this.__focusHandler, this));
    115         this.pickList.focusout($.proxy(this.__blurHandler, this));
    116     };
    117
    118     $.extend(rf.ui.PickList.prototype, (function () {
    119
    120         return {
    121             name : "pickList",
    122             defaultLabelClass : "rf-pick-dflt-lbl",
    123
    124             getName: function() {
    125                 return this.name;
    126             },
    127             getNamespace: function() {
    128                 return this.namespace;
    129             },
    130
    131             __focusHandler: function(e) {
    132                 if (! this.focused) {
    133                     this.focused = true;
    134                     rf.Event.fire(this, "listfocus" + this.namespace, e);
    135                     this.originalValue = this.targetList.csvEncodeValues();
    136                 }
    137             },
    138
    139             __blurHandler: function(e) {
    140                 if (this.focused) {
    141                     this.focused = false;
    142                     rf.Event.fire(this, "listblur" + this.namespace, e);
    143                 }
    144             },
    145
    146             getSourceList: function() {
    147                 return this.sourceList;
    148             },
    149
    150             getTargetList: function() {
    151                 return this.targetList;
    152             },
    153
    154             add: function() {
    155                 this.targetList.setFocus();
    156                 var items = this.sourceList.removeSelectedItems();
    157                 this.targetList.addItems(items);
    158                 this.encodeHiddenValues();
    159             },
    160
    161             remove: function() {
    162                 this.sourceList.setFocus();
    163                 var items = this.targetList.removeSelectedItems();
    164                 this.sourceList.addItems(items);
    165                 this.encodeHiddenValues();
    166             },
    167
    168             addAll: function() {
    169                 this.targetList.setFocus();
    170                 var items = this.sourceList.removeAllItems();
    171                 this.targetList.addItems(items);
    172                 this.encodeHiddenValues();
    173             },
    174
    175             removeAll: function() {
    176                 this.sourceList.setFocus();
    177                 var items = this.targetList.removeAllItems();
    178                 this.sourceList.addItems(items);
    179                 this.encodeHiddenValues();
    180             },
    181
    182             encodeHiddenValues: function() {
    183                 var oldValues = this.hiddenValues.val();
    184                 var newValues = this.targetList.csvEncodeValues();
    185                 if (oldValues !== newValues) {
    186                     this.hiddenValues.val(newValues);
    187                 }
    188                 rf.Event.fire(this, "change" + this.namespace, {oldValues : oldValues, newValues : newValues});
    189             },
    190
    191             toggleButtons: function() {
    192                 this.__toggleButton(this.addButton, this.sourceList.__getItems().filter('.' + this.selectItemCss).length > 0);
    193                 this.__toggleButton(this.removeButton, this.targetList.__getItems().filter('.' + this.selectItemCss).length > 0);
    194                 this.__toggleButton(this.addAllButton, this.sourceList.__getItems().length > 0);
    195                 this.__toggleButton(this.removeAllButton, this.targetList.__getItems().length > 0);
    196                 if (this.orderable) {
    197                     this.orderingList.toggleButtons();
    198                 }
    199             },
    200
    201             __toggleButton: function(button, enabled) {
    202                 if (this.disabled || ! enabled) {
    203                     if (! button.hasClass('rf-pick-btn-dis')) {
    204                         button.addClass('rf-pick-btn-dis')
    205                     }
    206                     if (! button.attr('disabled')) {
    207                         button.attr('disabled', true);
    208                     }
    209                 } else {
    210                     if (button.hasClass('rf-pick-btn-dis')) {
    211                         button.removeClass('rf-pick-btn-dis')
    212                     }
    213                     if (button.attr('disabled')) {
    214                         button.attr('disabled', false);
    215                     }
    216                 }
    217             }
    218         };
    219     })());
    220
    221 })(RichFaces.jQuery, window.RichFaces);
    222