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