      1 (function ($, rf) {
      2
      3     rf.ui = rf.ui || {};
      4
      5     rf.ui.Select = function(id, options) {
      6         this.id = id;
      7         var mergedOptions = $.extend({}, defaultOptions, options);
      8         mergedOptions['attachTo'] = id;
      9         mergedOptions['scrollContainer'] = $(document.getElementById(id + "Items")).parent()[0];
     10         mergedOptions['focusKeeperEnabled'] = false;
     11         $super.constructor.call(this, id, mergedOptions);
     12
     13         this.options = mergedOptions;
     14         this.defaultLabel = mergedOptions.defaultLabel;
     15         var inputLabel = this.__getValue();
     16         this.initialValue = (inputLabel != this.defaultLabel) ? inputLabel : "";
     17         this.selValueInput = $(document.getElementById(id + "selValue"));
     18         this.container = this.selValueInput.parent();
     19         this.clientSelectItems = mergedOptions.clientSelectItems;
     20         this.filterFunction = mergedOptions.filterFunction;
     21
     22
     23         if (mergedOptions.showControl && !mergedOptions.disabled) {
     24             this.container.bind("mousedown", $.proxy(this.__onBtnMouseDown, this))
     25                 .bind("mouseup", $.proxy(this.__onMouseUp, this));
     26         }
     27
     28         this.selectFirst = mergedOptions.selectFirst;
     29         this.popupList = new rf.ui.PopupList((id + "List"), this, mergedOptions);
     30         this.list = this.popupList.__getList();
     31         this.listElem = $(document.getElementById(id + "List"));
     32
     33         this.listElem.bind("mousedown", $.proxy(this.__onListMouseDown, this));
     34         this.listElem.bind("mouseup", $.proxy(this.__onMouseUp, this));
     35
     36         var listEventHandlers = {};
     37         listEventHandlers["listshow" + this.namespace] = $.proxy(this.__listshowHandler, this);
     38         listEventHandlers["listhide" + this.namespace] = $.proxy(this.__listhideHandler, this);
     39         listEventHandlers["change" + this.namespace] = $.proxy(this.__onInputChangeHandler, this);
     40         rf.Event.bind(this.input, listEventHandlers, this);
     41
     42         this.originalItems = this.list.__getItems();
     43         this.enableManualInput = mergedOptions.enableManualInput;
     44
     45         if (this.originalItems.length > 0 && this.enableManualInput) {
     46             this.cache = new rf.utils.Cache("", this.originalItems, getData, true);
     47         }
     48         this.changeDelay = mergedOptions.changeDelay;
     49     };
     50
     51     rf.ui.InputBase.extend(rf.ui.Select);
     52     var $super = rf.ui.Select.$super;
     53
     54     var defaultOptions = {
     55         defaultLabel: "",
     56         selectFirst: true,
     57         showControl: true,
     58         enableManualInput: false,
     59         itemCss: "rf-sel-opt",
     60         selectItemCss: "rf-sel-sel",
     61         listCss: "rf-sel-lst-cord",
     62         changeDelay: 8,
     63         disabled: false,
     64         filterFunction : undefined
     65     };
     66
     67     var REGEXP_TRIM = /^[\n\s]*(.*)[\n\s]*$/;
     68
     69     var getData = function (nodeList) {
     70         var data = [];
     71         nodeList.each(function () {
     72             ;
     73             data.push($(this).text().replace(REGEXP_TRIM, "$1"));
     74         });
     75         return data;
     76     }
     77
     78     $.extend(rf.ui.Select.prototype, ( function () {
     79         return{
     80             name : "select",
     81             defaultLabelClass : "rf-sel-dflt-lbl",
     82
     83             __listshowHandler: function(e) {
     84             },
     85
     86             __listhideHandler: function(e) {
     87             },
     88
     89             __onInputChangeHandler: function(e) {
     90                 this.__setValue(this.input.val());
     91             },
     92
     93             __onBtnMouseDown: function(e) {
     94                 if (!this.popupList.isVisible()) {
     95                     this.__updateItems();
     96                     this.__showPopup();
     97                 } else {
     98                     this.__hidePopup();
     99                 }
    100                 this.isMouseDown = true;
    101             },
    102
    103             __focusHandler: function(e) {
    104                 if (!this.focused) {
    105                     if (this.__getValue() == this.defaultLabel) {
    106                         this.__setValue("");
    107                     }
    108                     this.focusValue = this.selValueInput.val();
    109                     this.focused = true;
    110                     this.invokeEvent.call(this, "focus", document.getElementById(this.id), e);
    111                 }
    112             },
    113
    114             __keydownHandler: function(e) {
    115                 var code;
    116
    117                 if (e.keyCode) {
    118                     code = e.keyCode;
    119                 } else if (e.which) {
    120                     code = e.which;
    121                 }
    122
    123                 var visible = this.popupList.isVisible();
    124
    125                 switch (code) {
    126                     case rf.KEYS.DOWN:
    127                         e.preventDefault();
    128                         if (!visible) {
    129                             this.__updateItems();
    130                             this.__showPopup();
    131                         } else {
    132                             this.list.__selectNext();
    133                         }
    134                         break;
    135
    136                     case rf.KEYS.UP:
    137                         e.preventDefault();
    138                         if (visible) {
    139                             this.list.__selectPrev();
    140                         }
    141                         break;
    142
    143                     case rf.KEYS.RETURN:
    144                         e.preventDefault();
    145                         if (visible) {
    146                             this.list.__selectCurrent();
    147                         }
    148                         return false;
    149                         break;
    150
    151                     case rf.KEYS.TAB:
    152                         break;
    153
    154                     case rf.KEYS.ESC:
    155                         e.preventDefault();
    156                         if (visible) {
    157                             this.__hidePopup();
    158                         }
    159                         break;
    160
    161                     default:
    162                         var _this = this;
    163                         window.clearTimeout(this.changeTimerId);
    164                         this.changeTimerId = window.setTimeout(function() {
    165                             _this.__onChangeValue(e);
    166                         }, this.changeDelay);
    167                         break;
    168                 }
    169             },
    170
    171             __onChangeValue: function(e) {
    172                 this.list.__selectByIndex();
    173                 var newValue = this.__getValue();
    174                 if (this.cache && this.cache.isCached(newValue)) {
    175                     this.__updateItems();
    176
    177                     if (this.list.__getItems().length != 0) {
    178                         this.container.removeClass("rf-sel-fld-err");
    179                     } else {
    180                         this.container.addClass("rf-sel-fld-err");
    181                     }
    182
    183                     if (!this.popupList.isVisible()) {
    184                         this.__showPopup();
    185                     }
    186                 }
    187             },
    188
    189             __blurHandler: function(e) {
    190                 if (!this.isMouseDown) {
    191                     var that = this;
    192                     this.timeoutId = window.setTimeout(function() {
    193                         if (that.input !== null) {
    194                             that.onblur(e);
    195                         }
    196                     }, 200);
    197                 } else {
    198                     this.__setInputFocus();
    199                     this.isMouseDown = false;
    200                 }
    201             },
    202
    203             __onListMouseDown: function(e) {
    204                 this.isMouseDown = true;
    205             },
    206
    207             __onMouseUp: function(e) {
    208                 this.isMouseDown = false;
    209                 this.__setInputFocus();
    210             },
    211
    212             __updateItems: function() {
    213                 var newValue = this.__getValue();
    214                 newValue = (newValue != this.defaultLabel) ? newValue : "";
    215                 this.__updateItemsFromCache(newValue);
    216
    217                 if (this.selectFirst) {
    218                     this.list.__selectByIndex(0);
    219                 }
    220             },
    221
    222             __updateItemsFromCache: function(value) {
    223                 if (this.originalItems.length > 0 && this.enableManualInput) {
    224                     var newItems = this.cache.getItems(value, this.filterFunction);
    225                     var items = $(newItems);
    226                     this.list.__setItems(items);
    227                     $(document.getElementById(this.id + "Items")).empty().append(items);
    228                 }
    229             },
    230
    231             __getClientItemFromCache: function(inputLabel) {
    232                 var value;
    233                 var label;
    234                 if (this.enableManualInput) {
    235                     var items = this.cache.getItems(inputLabel, this.filterFunction);
    236                     if (items && items.length > 0) {
    237                         var first = $(items[0]);
    238                         $.each(this.clientSelectItems, function() {
    239                             if (this.id == first.attr("id")) {
    240                                 label = this.label;
    241                                 value = this.value;
    242                                 return false;
    243                             }
    244                         });
    245                     } else {
    246                         label = inputLabel;
    247                         value = "";
    248                     }
    249                 }
    250
    251                 if (label) {
    252                     return {'label': label, 'value': value};
    253                 }
    254             },
    255
    256             __getClientItem: function(inputLabel) {
    257                 var value;
    258                 var label = inputLabel;
    259                 $.each(this.clientSelectItems, function() {
    260                     if (label == this.label) {
    261                         value = this.value;
    262                     }
    263                 });
    264
    265                 if (label && value) {
    266                     return {'label': label, 'value': value};
    267                 }
    268             },
    269
    270             __showPopup: function() {
    271                 this.popupList.show();
    272                 this.invokeEvent.call(this, "listshow", document.getElementById(this.id));
    273             },
    274
    275             __hidePopup: function() {
    276                 this.popupList.hide();
    277                 this.invokeEvent.call(this, "listhide", document.getElementById(this.id));
    278             },
    279
    280             showPopup: function() {
    281                 if (!this.popupList.isVisible()) {
    282                     this.__updateItems();
    283                     this.__showPopup();
    284                 }
    285                 this.__setInputFocus();
    286                 if (!this.focused) {
    287                     if (this.__getValue() == this.defaultLabel) {
    288                         this.__setValue("");
    289                     }
    290                     this.focusValue = this.selValueInput.val();
    291                     this.focused = true;
    292                     this.invokeEvent.call(this, "focus", document.getElementById(this.id));
    293                 }
    294             },
    295
    296             hidePopup: function() {
    297                 if (this.popupList.isVisible()) {
    298                     this.__hidePopup();
    299                     var inputLabel = this.__getValue();
    300
    301                     if (!inputLabel || inputLabel == "") {
    302                         this.__setValue(this.defaultLabel);
    303                         this.selValueInput.val("");
    304                     }
    305
    306                     this.focused = false;
    307                     this.invokeEvent.call(this, "blur", document.getElementById(this.id));
    308                     if (this.focusValue != this.selValueInput.val()) {
    309                         this.invokeEvent.call(this, "change", document.getElementById(this.id));
    310                     }
    311                 }
    312             },
    313
    314             processItem: function(item) {
    315                 var key = $(item).attr("id");
    316                 var label;
    317                 $.each(this.clientSelectItems, function() {
    318                     if (this.id == key) {
    319                         label = this.label;
    320                         return false;
    321                     }
    322                 });
    323                 this.__setValue(label);
    324                 this.__hidePopup();
    325                 this.__setInputFocus();
    326                 this.__save();
    327
    328                 this.invokeEvent.call(this, "selectitem", document.getElementById(this.id));
    329             },
    330
    331             __save: function() {
    332                 var value = "";
    333                 var label = "";
    334                 var inputLabel = this.__getValue();
    335                 var clientSelectItem;
    336
    337                 if (inputLabel && inputLabel != "") {
    338                     if (this.enableManualInput) {
    339                         clientSelectItem = this.__getClientItemFromCache(inputLabel);
    340                     } else {
    341                         clientSelectItem = this.__getClientItem(inputLabel);
    342                     }
    343
    344                     if (clientSelectItem) {
    345                         label = clientSelectItem.label;
    346                         value = clientSelectItem.value;
    347                     }
    348                 }
    349
    350                 this.__setValue(label);
    351                 this.selValueInput.val(value);
    352             },
    353
    354             onblur: function(e) {
    355                 this.__hidePopup();
    356                 var inputLabel = this.__getValue();
    357
    358                 if (!inputLabel || inputLabel == "") {
    359                     this.__setValue(this.defaultLabel);
    360                     this.selValueInput.val("");
    361                 }
    362
    363                 this.focused = false;
    364                 this.invokeEvent.call(this, "blur", document.getElementById(this.id), e);
    365                 if (this.focusValue != this.selValueInput.val()) {
    366                     this.invokeEvent.call(this, "change", document.getElementById(this.id), e);
    367                 }
    368             },
    369
    370             getValue: function() {
    371                 return this.selValueInput.val();
    372             },
    373
    374             setValue: function(value) {
    375                 if (value == null || value == '') {
    376                     this.__setValue('');
    377                     this.__save();
    378                     this.__updateItems();
    379                     return;
    380                 }
    381                 var item;
    382                 for (var i = 0; i < this.clientSelectItems.length; i++) {
    383                     item = this.clientSelectItems[i];
    384                     if (item.value == value) {
    385                         this.__setValue(item.label);
    386                         this.__save();
    387                         this.list.__selectByIndex(i);
    388                         return;
    389                     }
    390                 }
    391             },
    392
    393             getLabel: function() {
    394                 return this.__getValue();
    395             },
    396
    397             destroy: function() {
    398                 this.popupList.destroy();
    399                 this.popupList = null;
    400                 $super.destroy.call(this);
    401             }
    402         }
    403     })());
    404
    405     // client-side validation
    406     rf.csv = rf.csv || {};
    407     rf.csv.validateSelectLabelValue = function (input, id, params, msg) {
    408         var value = $(document.getElementById(id + 'selValue')).val();
    409         var label = $(document.getElementById(id + 'Input')).val();
    410
    411         var defaultLabel = RichFaces.component(id).defaultLabel;
    412
    413         if (!value && label && (label != defaultLabel)) {
    414             throw rf.csv.getMessage(null, 'UISELECTONE_INVALID', [id, ""]);
    415         }
    416     };
    417
    418 })(RichFaces.jQuery, window.RichFaces);