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 (function($, rf) {
 23 
 24     var getGlobalStatusNameVariable = function() {
 25         return rf.statusName;
 26     }
 27 
 28     var RICHFACES_AJAX_STATUS = "richfaces:ajaxStatus";
 29 
 30     var getStatusDataAttributeName = function(statusName) {
 31         return statusName ? (RICHFACES_AJAX_STATUS + "@" + statusName) : RICHFACES_AJAX_STATUS;
 32     };
 33 
 34     var statusAjaxEventHandler = function(data, methodName) {
 35         if (methodName) {
 36             //global status name
 37             var statusName = getGlobalStatusNameVariable();
 38             var source = data.source;
 39 
 40             var statusApplied = false;
 41             var statusDataAttribute = getStatusDataAttributeName(statusName);
 42 
 43             var statusContainers;
 44             if (statusName) {
 45                 statusContainers = [$(document)];
 46             } else {
 47                 statusContainers = [$(source).parents('form'), $(document)];
 48             }
 49 
 50             for (var containerIdx = 0; containerIdx < statusContainers.length && !statusApplied;
 51                  containerIdx++) {
 52 
 53                 var statusContainer = statusContainers[containerIdx];
 54                 var statuses = statusContainer.data(statusDataAttribute);
 55                 if (statuses) {
 56                     for (var statusId in statuses) {
 57                         var status = statuses[statusId];
 58                         var result = status[methodName].apply(status, arguments);
 59                         if (result) {
 60                             statusApplied = true;
 61                         } else {
 62                             delete statuses[statusId];
 63                         }
 64                     }
 65 
 66                     if (!statusApplied) {
 67                         statusContainer.removeData(statusDataAttribute);
 68                     }
 69                 }
 70             }
 71         }
 72     };
 73 
 74     var initializeStatuses = function() {
 75         var thisFunction = arguments.callee;
 76         if (!thisFunction.initialized) {
 77             thisFunction.initialized = true;
 78 
 79             var jsfEventsListener = rf.createJSFEventsAdapter({
 80                     begin: function(event) {
 81                         statusAjaxEventHandler(event, 'start');
 82                     },
 83                     error: function(event) {
 84                         statusAjaxEventHandler(event, 'error');
 85                     },
 86                     success: function(event) {
 87                         statusAjaxEventHandler(event, 'success');
 88                     },
 89                     complete: function() {
 90                         rf.setGlobalStatusNameVariable(null);
 91                     }
 92                 });
 93 
 94             jsf.ajax.addOnEvent(jsfEventsListener);
 95             //TODO blocks default alert error handler
 96             jsf.ajax.addOnError(jsfEventsListener);
 97         }
 98     };
 99 
100     rf.ui = rf.ui || {};
101 
102     rf.ui.Status = rf.BaseComponent.extendClass({
103 
104             name: "Status",
105 
106             //TODO - support for parallel requests
107             init: function(id, options) {
108                 this.id = id;
109                 this.attachToDom();
110                 this.options = options || {};
111                 this.register();
112             },
113 
114             register: function() {
115                 initializeStatuses();
116 
117                 var statusName = this.options.statusName;
118                 var dataStatusAttribute = getStatusDataAttributeName(statusName);
119 
120                 var container;
121                 if (statusName) {
122                     container = $(document);
123                 } else {
124                     container = $(rf.getDomElement(this.id)).parents('form');
125                     if (container.length == 0) {
126                         container = $(document);
127                     }
128                     ;
129                 }
130 
131                 var statuses = container.data(dataStatusAttribute);
132                 if (!statuses) {
133                     statuses = {};
134                     container.data(dataStatusAttribute, statuses);
135                 }
136 
137                 statuses[this.id] = this;
138             },
139 
140             start: function() {
141                 if (this.options.onstart) {
142                     this.options.onstart.apply(this, arguments);
143                 }
144 
145                 return this.__showHide('.rf-st-start');
146             },
147 
148             stop: function() {
149                 this.__stop();
150                 return this.__showHide('.rf-st-stop');
151             },
152 
153             success: function() {
154                 if (this.options.onsuccess) {
155                     this.options.onsuccess.apply(this, arguments);
156                 }
157                 return this.stop();
158             },
159 
160             error: function() {
161                 if (this.options.onerror) {
162                     this.options.onerror.apply(this, arguments);
163                 }
164                 this.__stop();
165 
166                 return this.__showHide(':not(.rf-st-error) + .rf-st-stop, .rf-st-error');
167             },
168 
169             __showHide: function(selector) {
170                 var element = $(rf.getDomElement(this.id));
171                 if (element) {
172                     var statusElts = element.children();
173                     statusElts.each(function() {
174                         var t = $(this);
175                         t.css('display', t.is(selector) ? '' : 'none');
176                     });
177 
178                     return true;
179                 }
180                 return false;
181             },
182 
183             __stop: function () {
184                 if (this.options.onstop) {
185                     this.options.onstop.apply(this, arguments);
186                 }
187             }
188         });
189 }(RichFaces.jQuery, window.RichFaces));
190