1 /* 2 * JBoss, Home of Professional Open Source 3 * Copyright ${year}, Red Hat, Inc. and individual contributors 4 * by the @authors tag. See the copyright.txt in the distribution for a 5 * full listing of individual contributors. 6 * 7 * This is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU Lesser General Public License as 9 * published by the Free Software Foundation; either version 2.1 of 10 * the License, or (at your option) any later version. 11 * 12 * This software is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this software; if not, write to the Free 19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 21 */ 22 23 24 (function ($, rf) { 25 26 rf.ui = rf.ui || {}; 27 28 var __DEFAULT_OPTIONS = { 29 disabled : false, 30 selectable: true, 31 unselectable: false, 32 mode: "client", 33 stylePrefix: "rf-pm-itm", 34 itemStep: 20 35 }; 36 37 var SELECT_ITEM = { 38 39 /** 40 * 41 * @return {void} 42 * */ 43 exec : function (item) { 44 45 if (item.expanded) { 46 var flag = item.options.expandEvent == item.options.collapseEvent && item.options.collapseEvent == "click"; 47 if (flag && item.__fireEvent("beforeswitch") == false) return false; 48 if (!item.expanded()) { 49 if (item.options.expandEvent == "click" && item.__fireEvent("beforeexpand") == false) return false; 50 } else { 51 if (item.options.collapseEvent == "click" && item.__fireEvent("beforecollapse") == false) return false; 52 } 53 } 54 55 var mode = item.mode; 56 if (mode == "server") { 57 return this.execServer(item); 58 } else if (mode == "ajax") { 59 return this.execAjax(item); 60 } else if (mode == "client" || mode == "none") { 61 return this.execClient(item); 62 } else { 63 rf.log.error("SELECT_ITEM.exec : unknown mode (" + mode + ")"); 64 } 65 }, 66 67 /** 68 * @protected 69 * 70 * @return {Boolean} false 71 * */ 72 execServer : function (item) { 73 item.__changeState(); 74 //TODO nick - 'target' attribute? 75 76 var params = {}; 77 params[item.__panelMenu().id] = item.itemName; // TODO 78 params[item.id] = item.id; 79 80 $.extend(params, item.options["ajax"]["parameters"] || {}); 81 82 rf.submitForm(this.__getParentForm(item), params); 83 84 return false; 85 }, 86 87 /** 88 * @protected 89 * 90 * @return {Boolean} false 91 * */ 92 execAjax : function (item) { 93 var oldItem = item.__changeState(); 94 //TODO nick - check for interaction with queue 95 rf.ajax(item.id, null, $.extend({}, item.options["ajax"], {})); 96 item.__restoreState(oldItem); 97 98 return true; 99 }, 100 101 /** 102 * @protected 103 * 104 * @return {undefined} 105 * - false - if process has been terminated 106 * - true - in other cases 107 * */ 108 execClient : function (item) { 109 var panelMenu = item.__rfPanelMenu(); 110 var prevItem = panelMenu.getSelectedItem(); 111 if (prevItem) { 112 prevItem.unselect(); 113 } 114 115 panelMenu.selectedItem(item.itemName); 116 117 item.__select(); 118 var result = item.__fireSelect(); 119 120 if (item.__switch) { 121 var mode = item.mode; 122 if (mode == "client" || mode == "none") { 123 item.__switch(!item.expanded()); 124 } 125 } 126 127 return result; 128 }, 129 130 /** 131 * @private 132 * */ 133 __getParentForm : function (item) { 134 return $($(rf.getDomElement(item.id)).parents("form")[0]); 135 } 136 }; 137 138 rf.ui.PanelMenuItem = rf.BaseComponent.extendClass({ 139 // class name 140 name:"PanelMenuItem", 141 142 /** 143 * @class PanelMenuItem 144 * @name PanelMenuItem 145 * 146 * @constructor 147 * @param {String} componentId - component id 148 * @param {Hash} options - params 149 * */ 150 init : function (componentId, options) { 151 $super.constructor.call(this, componentId); 152 var rootElt = $(this.attachToDom()); 153 154 this.options = $.extend(this.options, __DEFAULT_OPTIONS, options || {}); 155 156 this.mode = this.options.mode; 157 this.itemName = this.options.name; 158 var panelMenu = this.__rfPanelMenu(); 159 panelMenu.addItem(this); 160 161 // todo move it 162 this.selectionClass = this.options.stylePrefix + "-sel"; 163 164 if (!this.options.disabled) { 165 var item = this; 166 167 if (this.options.selectable) { 168 this.__header().bind("click", function() { 169 if (item.__rfPanelMenu().selectedItem() == item.id) { 170 if (item.options.unselectable) { 171 return item.unselect(); 172 } 173 174 // we shouldn't select one item several times 175 } else { 176 return item.select(); 177 } 178 }); 179 } 180 } 181 182 item = this; 183 $(this.__panelMenu()).ready(function () { 184 item.__renderNestingLevel(); 185 }); 186 187 this.__addUserEventHandler("select"); 188 this.__addUserEventHandler("beforeselect"); 189 }, 190 191 /***************************** Public Methods ****************************************************************/ 192 193 selected : function () { 194 return this.__header().hasClass(this.selectionClass); 195 }, 196 197 /** 198 * @methodOf 199 * @name PanelMenuItem#select 200 * 201 * TODO ... 202 * 203 * @return {void} TODO ... 204 */ 205 select: function () { 206 var continueProcess = this.__fireBeforeSelect(); 207 if (!continueProcess) { 208 return false; 209 } 210 211 return SELECT_ITEM.exec(this) 212 }, 213 214 /** 215 * please, remove this method when client side ajax events will be added 216 * 217 * */ 218 onCompleteHandler : function () { 219 SELECT_ITEM.execClient(this); 220 }, 221 222 unselect: function () { 223 var panelMenu = this.__rfPanelMenu(); 224 if (panelMenu.selectedItem() == this.itemName) { 225 panelMenu.selectedItem(null); 226 } else { 227 rf.log.warn("You tried to unselect item (name=" + this.itemName + ") that isn't seleted") 228 } 229 230 this.__unselect(); 231 232 return this.__fireUnselect(); 233 }, 234 235 /***************************** Private Methods ****************************************************************/ 236 __rfParentItem : function () { 237 var res = this.__item().parents(".rf-pm-gr")[0]; 238 if (!res) { 239 res = this.__item().parents(".rf-pm-top-gr")[0]; 240 } 241 242 if (!res) { 243 res = this.__panelMenu(); 244 } 245 246 return res ? rf.component(res) : null; 247 }, 248 249 __getNestingLevel : function () { 250 if (!this.nestingLevel) { 251 var parentItem = this.__rfParentItem(); 252 if (parentItem && parentItem.__getNestingLevel) { 253 this.nestingLevel = parentItem.__getNestingLevel() + 1; 254 } else { 255 this.nestingLevel = 0; 256 } 257 } 258 259 return this.nestingLevel; 260 }, 261 262 __renderNestingLevel : function () { 263 this.__item().find("td").first().css("padding-left", this.options.itemStep * this.__getNestingLevel()); 264 }, 265 266 __panelMenu : function () { 267 return this.__item().parents(".rf-pm")[0]; 268 }, 269 270 __rfPanelMenu : function () { 271 return rf.component(this.__panelMenu()); 272 }, 273 274 __changeState : function () { 275 return this.__rfPanelMenu().selectedItem(this.itemName); 276 }, 277 278 __restoreState : function (state) { 279 if (state) { 280 this.__rfPanelMenu().selectedItem(state); 281 } 282 }, 283 284 __item : function () { 285 return $(rf.getDomElement(this.id)); 286 }, 287 288 __header : function () { 289 return this.__item(); 290 }, 291 292 __isSelected: function() { 293 return this.__header().hasClass(this.selectionClass); 294 }, 295 296 __select: function () { 297 this.__header().addClass(this.selectionClass); 298 }, 299 300 __unselect: function () { 301 this.__header().removeClass(this.selectionClass); 302 }, 303 304 __fireBeforeSelect : function () { 305 return rf.Event.fireById(this.id, "beforeselect", { 306 item: this 307 }); 308 }, 309 310 __fireSelect : function () { 311 return rf.Event.fireById(this.id, "select", { 312 item: this 313 }); 314 }, 315 316 __fireUnselect : function () { 317 return rf.Event.fireById(this.id, "unselect", { 318 item: this 319 }); 320 }, 321 322 __fireEvent : function (eventType, event) { 323 return this.invokeEvent(eventType, rf.getDomElement(this.id), event, {id: this.id, item: this}); 324 }, 325 326 /** 327 * @private 328 * */ 329 __addUserEventHandler : function (name) { 330 var handler = this.options["on" + name]; 331 if (handler) { 332 rf.Event.bindById(this.id, name, handler); 333 } 334 }, 335 336 __rfTopGroup : function () { 337 var res = this.__item().parents(".rf-pm-top-gr")[0]; 338 return res ? res : null; 339 }, 340 341 destroy: function () { 342 var panelMenu = this.__rfPanelMenu(); 343 if (panelMenu) { 344 panelMenu.deleteItem(this); 345 } 346 347 $super.destroy.call(this); 348 } 349 }); 350 351 // define super class link 352 var $super = rf.ui.PanelMenuItem.$super; 353 })(RichFaces.jQuery, RichFaces); 354