]> dev.renevier.net Git - syj.git/blobdiff - public/js/utils.js
general class for accout info toggler
[syj.git] / public / js / utils.js
index 3e10f5cc0bcca87c3d784319f64caebb5f9439df..f437d150d8f821000afa9adda7253547deb0c0eb 100644 (file)
@@ -21,11 +21,45 @@ var CloseBtn = Class.create({
         btn = new Element("input", { type: "image", src: imgsrc, alt: "X"}).setStyle(style);
         elt.insert({top: btn});
         btn.observe("click", function(evt) {
+            evt.stop();
+            if (typeof options.callback === "function") {
+                options.callback.call(elt);
+            }
             elt.hide();
         });
     }
 });
 
+var Toggler = Class.create({
+    initialize: function(target, options) {
+        options = Object.extend({}, options);
+        target = $(target).hide();
+
+        var openIcn = options.openIcn || 'icons/bullet_arrow_right.png',
+            closeIcn = options.closeIcn || 'icons/bullet_arrow_down.png';
+
+        this.element = new Element("img", { src: openIcn })
+                              .setStyle({ border: 'none',  // in firefox, in image inside an anchor has a border
+                                        verticalAlign: "middle"});
+
+        this.element.observe('click', function(evt) {
+            if (target.visible()) {
+                evt.target.src = openIcn;
+                target.hide();
+            } else {
+                evt.target.src = closeIcn;
+                target.show();
+            }
+            evt.stop();
+        });
+
+        if (options.initialShow) {
+            target.show();
+            this.element.src = closeIcn;
+        }
+    }
+});
+
 var Deck = Class.create({
     initialize: function(elt, options) {
         this.element = $(elt);
@@ -72,64 +106,121 @@ Element.addMethods({
     }
 });
 
-// wrapper around Form.request that sets up the submit listener, stops the
-// submit event, calls presubmit function, calls Form.request and calls a
-// postsubmit function
-Element.addMethods('form', {
-    ajaxize : function(form, options) {
-        var reqoptions, timeout;
+Ajax.TimedRequest = Class.create(Ajax.Request, {
+    timeout: null,
+    delay: null,
 
-        options = Object.clone(options);
-        reqoptions = Object.clone(options);
-        timeout = null;
+    abort: function() {
+        // see http://blog.pothoven.net/2007/12/aborting-ajax-requests-for-prototypejs.html
+        this.transport.onreadystatechange = Prototype.emptyFunction;
+        this.transport.abort();
+        Ajax.activeRequestCount--;
+    },
 
-        function onSuccess(transport, json) {
-            if (timeout) {
-                window.clearTimeout(timeout);
-                timeout = null;
+    initialize: function($super, url, delay, options) {
+        this.delay = delay;
+        if (!options) {
+            options = {};
+        }
+
+        options.onSuccess = options.onSuccess &&
+            options.onSuccess.wrap(function(proceed, transport, json) {
+            if (this.timeout) {
+                window.clearTimeout(this.timeout);
+                this.timeout = null;
             }
             if (transport.getStatus() === 0) {
-                options.onFailure(transport, json);
+                this.options.onFailure(transport, json);
             } else {
-                options.onSuccess(transport, json);
+                proceed(transport, json);
             }
-        }
+        }).bind(this);
 
-        function onFailure(transport, json) {
-            if (timeout) {
-                window.clearTimeout(timeout);
-                timeout = null;
+        options.onFailure = options.onFailure &&
+            options.onFailure.wrap(function(proceed, transport, json) {
+            if (this.timeout) {
+                window.clearTimeout(this.timeout);
+                this.timeout = null;
             }
-            options.onFailure(transport, json);
+            proceed(transport, json);
+        }).bind(this);
+
+        $super(url, options);
+    },
+
+    request: function($super, url) {
+        this.timeout = function() {
+            if (this.options.onFailure) {
+                this.options.onFailure(null);
+            }
+            this.abort();
+        }.bind(this).delay(this.delay);
+        $super(url);
+    }
+});
+
+Ajax.Responders.register({
+    // needed for Ajax.TimedRequest.abort to work: see
+    // http://blog.pothoven.net/2007/12/aborting-ajax-requests-for-prototypejs.html
+    // again
+    onComplete: function() {
+        Ajax.activeRequestCount--;
+        if (Ajax.activeRequestCount < 0) {
+            Ajax.activeRequestCount = 0;
         }
+    }
+});
+
+// wrapper around Form.request that sets up the submit listener, stops the
+// submit event, calls presubmit function, calls Form.request and calls a
+// postsubmit function
+Element.addMethods('form', {
+    ajaxize : function(form, options) {
+        var reqoptions;
 
-        delete(reqoptions.presubmit);
-        delete(reqoptions.postsubmit);
+        options = Object.clone(options || {});
 
         $(form).observe('submit', function(evt) {
-            var req;
-
             evt.stop(); // cancel form submission
+
+            reqoptions = Object.clone(options);
+            delete(reqoptions.presubmit);
+            delete(reqoptions.postsubmit);
+            delete(reqoptions.delay);
+
             if (Object.isFunction(options.presubmit)) {
                 if (options.presubmit(this) === false) {
                     return;
                 }
             }
-            req = this.request(Object.extend(reqoptions, {
-                onSuccess: onSuccess,
-                onFailure: onFailure
-            }));
-            timeout = (function() {
-                options.onFailure(null);
-                req.abort();
-            }).delay(options.timeout || 20);
+
+            var params = reqoptions.parameters, action = this.readAttribute('action') || '';
+
+            if (action.blank()) {
+                action = window.location.href;
+            }
+            reqoptions.parameters = this.serialize(true);
+
+            if (params) {
+                if (Object.isString(params)) {
+                    params = params.toQueryParams();
+                }
+                Object.extend(reqoptions.parameters, params);
+            }
+
+            if (this.hasAttribute('method') && !reqoptions.method) {
+                reqoptions.method = this.method;
+            }
+
+            new Ajax.TimedRequest(action, options.delay || 20, reqoptions);
+
             if (Object.isFunction(options.postsubmit)) {
                 options.postsubmit(this);
             }
         });
     },
 
-    focus: function(form) {
+    setfocus: function(form) {
         var tofocus, error;
 
         tofocus = null;
@@ -173,6 +264,52 @@ Element.addMethods(['input', 'textarea'], {
             after: new Element("div", {className: 'error'}).update(errorMessage)
         });
         return false;
+    },
+
+    observe : Element.Methods.observe.wrap(function(proceed, element, eventName, handler) {
+        if (eventName === "contentchange") {
+            proceed(element, 'keyup', function(evt) {
+                if (evt.keyCode === 13) {
+                    return;
+                }
+                handler.apply(null, arguments);
+            });
+            proceed(element, 'paste', handler);
+            return proceed(element, 'change', handler);
+        }
+        return proceed(element, eventName, handler);
+    }),
+
+    timedobserve: function(element, callback, delay) {
+        var timeout = null, initialvalue = element.value;
+
+        if (typeof delay !== "number") {
+            delay = 0.5;
+        }
+        delay = delay * 1000;
+
+        var canceltimer = function() {
+            if (timeout) {
+                clearTimeout(timeout);
+                timeout = null;
+            }
+        };
+        var resettimer = function() {
+            canceltimer();
+            timeout = setTimeout(triggercallback, delay);
+        };
+        var triggercallback = function() {
+            canceltimer();
+            if (initialvalue !== element.value) {
+                initialvalue = element.value;
+                callback.call(element);
+            }
+        };
+
+        element.observe('blur', triggercallback).
+             observe('keyup', resettimer).
+             observe('paste', resettimer);
+        return element;
     }
 });
 
@@ -204,9 +341,13 @@ Element.addMethods('div', {
 
     addMessage: function(div, message) {
         var node = (div.ownerDocument || document).createTextNode(message);
-        if (!div.empty()) {
+
+        if ($A(div.childNodes).filter(function(node) {
+                return (node.nodeType === 3 || node.tagName.toLowerCase() === 'br');
+             }).length) {
             div.insert(new Element('br'));
         }
+
         div.appendChild(node);
         return div.show();
     },