1 /*
  2  * code review by Pavel Yaschenko
  3  * 
  4  * No event's unbindings when component would be destroyed Hint: easy way to
  5  * unbind - use namespaces when bind event handlers
  6  * 
  7  */
  8 
  9 (function($, rf) {
 10 
 11     rf.ui = rf.ui || {};
 12 
 13     var defaultIndicatorClasses = {
 14         rejectClass : "rf-ind-rejt",
 15         acceptClass : "rf-ind-acpt",
 16         draggingClass : "rf-ind-drag"
 17     };
 18 
 19     var defaultOptions = {
 20     };
 21 
 22     rf.ui.Droppable = function(id, options) {
 23         this.options = {};
 24         $.extend(this.options, defaultOptions, options || {});
 25         $super.constructor.call(this, id);
 26 
 27         this.namespace = this.namespace || "."
 28             + rf.Event.createNamespace(this.name, this.id);
 29 
 30         this.id = id;
 31 
 32         this.parentId = this.options.parentId;
 33 
 34         this.attachToDom(this.parentId);
 35 
 36         this.dropElement = $(document.getElementById(this.parentId));
 37         this.dropElement.droppable({
 38                 addClasses : false
 39             });
 40         this.dropElement.data("init", true);
 41 
 42         rf.Event.bind(this.dropElement, 'drop' + this.namespace, this.drop, this);
 43         rf.Event.bind(this.dropElement, 'dropover' + this.namespace, this.dropover, this);
 44         rf.Event.bind(this.dropElement, 'dropout' + this.namespace, this.dropout, this);
 45 
 46     };
 47 
 48     rf.BaseNonVisualComponent.extend(rf.ui.Droppable);
 49 
 50     var $super = rf.ui.Droppable.$super;
 51 
 52     $.extend(rf.ui.Droppable.prototype, (function() {
 53         return {
 54             drop : function(e) {
 55                 var ui = e.rf.data;
 56                 if (this.accept(ui.draggable)) {
 57                     this.__callAjax(e, ui);
 58                 }
 59                 var dragIndicatorObj = this.__getIndicatorObject(ui.helper);
 60                 if (dragIndicatorObj) {
 61                     ui.helper.removeClass(dragIndicatorObj.getAcceptClass());
 62                     ui.helper.removeClass(dragIndicatorObj.getRejectClass());
 63                 } else {
 64                     ui.helper.removeClass(defaultIndicatorClasses.acceptClass);
 65                     ui.helper.removeClass(defaultIndicatorClasses.rejectClass);
 66                 }
 67             },
 68 
 69             dropover : function(e) {
 70                 var ui = e.rf.data;
 71                 var draggable = ui.draggable;
 72                 var dragIndicatorObj = this.__getIndicatorObject(ui.helper);
 73                 this.dropElement.addClass("rf-drp-hvr");
 74                 if (dragIndicatorObj) {
 75                     if (this.accept(draggable)) {
 76                         ui.helper.removeClass(dragIndicatorObj.getRejectClass());
 77                         ui.helper.addClass(dragIndicatorObj.getAcceptClass());
 78                         this.dropElement.addClass("rf-drp-hlight");
 79                     } else {
 80                         ui.helper.removeClass(dragIndicatorObj.getAcceptClass());
 81                         ui.helper.addClass(dragIndicatorObj.getRejectClass());
 82                         this.dropElement.removeClass("rf-drp-hlight");
 83                     }
 84                 } else {
 85                     if (this.accept(draggable)) {
 86                         ui.helper.removeClass(defaultIndicatorClasses.rejectClass);
 87                         ui.helper.addClass(defaultIndicatorClasses.acceptClass);
 88                         this.dropElement.addClass("rf-drp-hlight");
 89                     } else {
 90                         ui.helper.removeClass(defaultIndicatorClasses.acceptClass);
 91                         ui.helper.addClass(defaultIndicatorClasses.rejectClass);
 92                         this.dropElement.removeClass("rf-drp-hlight");
 93                     }
 94                 }
 95             },
 96 
 97             dropout : function(e) {
 98                 var ui = e.rf.data;
 99                 var draggable = ui.draggable;
100                 var dragIndicatorObj = this.__getIndicatorObject(ui.helper);
101                 this.dropElement.removeClass("rf-drp-hvr rf-drp-hlight");
102                 if (dragIndicatorObj) {
103                     ui.helper.removeClass(dragIndicatorObj.getAcceptClass());
104                     ui.helper.removeClass(dragIndicatorObj.getRejectClass());
105                 } else {
106                     ui.helper.removeClass(defaultIndicatorClasses.acceptClass);
107                     ui.helper.removeClass(defaultIndicatorClasses.rejectClass);
108                 }
109             },
110 
111             accept : function(draggable) {
112                 var accept = false;
113                 var acceptType = draggable.data("type");
114                 if (acceptType && this.options.acceptedTypes) {
115                     $.each(this.options.acceptedTypes, function() {
116                         if (this == "@none") {
117                             return false;
118                         }
119 
120                         if (this == acceptType || this == "@all") {
121                             accept = true;
122                             return false;
123                         }
124                     });
125                 }
126                 return accept;
127             },
128             
129             __getIndicatorObject: function(helper) {
130                 var indicatorCloneId = helper.attr('id');
131                 if (indicatorCloneId) {
132                     var indicatorId = indicatorCloneId.match(/(.*)Clone$/)[1];
133                     return rf.component(indicatorId);
134                 }
135             },
136 
137             __callAjax : function(e, ui) {
138                 if (ui.draggable) {
139                     var dragSource = ui.draggable.data("id");
140                     var ajaxFunc = this.options.ajaxFunction;
141                     if (ajaxFunc && typeof ajaxFunc == 'function') {
142                         ajaxFunc.call(this, e, dragSource);
143                     }
144                 }
145             },
146 
147             destroy : function() {
148                 // clean up code here
149                 this.detach(this.parentId);
150                 rf.Event.unbind(this.dropElement, this.namespace);
151 
152                 // call parent's destroy method
153                 $super.destroy.call(this);
154 
155             }
156 
157 
158         }
159     })());
160 
161 })(RichFaces.jQuery, window.RichFaces);