      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