From 5584d58e656c5c09db20d15727d9387ed39f8cf2 Mon Sep 17 00:00:00 2001
From: "Stephen St. Martin" <kuprishuz@gmail.com>
Date: Tue, 26 Jan 2010 15:20:23 -0500
Subject: refactored to be more dry, data-update-failure now correctly works,
 combine compat and driver, namespaced events, and support for
 periodically_call_remote

---
 .../templates/public/javascripts/jquery.compat.js  |  33 ----
 .../templates/public/javascripts/jquery.driver.js  | 214 ++++++++++++++-------
 2 files changed, 145 insertions(+), 102 deletions(-)
 delete mode 100644 railties/lib/generators/rails/app/templates/public/javascripts/jquery.compat.js

diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/jquery.compat.js b/railties/lib/generators/rails/app/templates/public/javascripts/jquery.compat.js
deleted file mode 100644
index 6f5427fbce..0000000000
--- a/railties/lib/generators/rails/app/templates/public/javascripts/jquery.compat.js
+++ /dev/null
@@ -1,33 +0,0 @@
-jQuery(function ($) {
-    function evalAttribute(element, attribute) {
-        var el = $(element); 
-        var attr = el.attr('data-' + attribute);
-        if(attr) {
-            eval(attr);
-        }
-    }
-
-    $('form[data-remote="true"],a[data-remote="true"],input[data-remote="true"]')
-        .live('before', function (e) {
-            evalAttribute(this, 'onbefore'); 
-        })
-        .live('after', function (e, xhr) {
-            evalAttribute(this, 'onafter'); 
-        })
-        .live('loading', function (e, xhr) {
-            evalAttribute(this, 'onloading'); 
-        })
-        .live('loaded', function (e, xhr) {
-            evalAttribute(this, 'onloaded'); 
-        })
-        .live('complete', function (e, xhr) {
-            evalAttribute(this, 'oncomplete'); 
-            evalAttribute(this, 'on' + xhr.status); 
-        })
-        .live('success', function (e, data, status, xhr) {
-            evalAttribute(this, 'onsuccess'); 
-        })
-        .live('failure', function (e, xhr, status, error) {
-            evalAttribute(this, 'onfailure'); 
-        });
-});
diff --git a/railties/lib/generators/rails/app/templates/public/javascripts/jquery.driver.js b/railties/lib/generators/rails/app/templates/public/javascripts/jquery.driver.js
index 1fa993cbb0..849b571558 100644
--- a/railties/lib/generators/rails/app/templates/public/javascripts/jquery.driver.js
+++ b/railties/lib/generators/rails/app/templates/public/javascripts/jquery.driver.js
@@ -1,78 +1,154 @@
+// TODO: confirm
+// TODO: popup
+// TODO: disable_with
 jQuery(function ($) {
+    var rails = {
+        update: function (selector, content, position) {
+            var element = selector.charAt(0) == '#' ? selector : '#' + selector;
+            if (position) {
+                switch (position) {
+                    case "before":
+                        $(element).before(content); 
+                        break;
+                    case "after":
+                        $(element).after(content); 
+                        break;
+                    case "top":
+                        $(element).prepend(content); 
+                        break;
+                    case "bottom":
+                        $(element).append(content); 
+                        break;
+                    default:
+                        $(element).append(content); 
+                        break;
+                }
+            } else {
+                $(element).html(content); 
+            }
+        },
+        remote: function (e) {
+            var el          = $(this),
+                data        = [],
+                condition   = el.attr('data-condition') ? eval(el.attr('data-condition')) : true,
+                method      = el.attr('method') || el.attr('data-method') || 'GET',
+                url         = el.attr('action') || el.attr('data-url') || '#',
+                async       = el.attr('data-remote-type') === 'synchronous' ? false : true;
 
-    function handleRemote (e) {
-        var el          = $(this),
-            data        = [],
-            condition   = el.attr('data-condition') ? eval(el.attr('data-condition')) : true,
-            method      = el.attr('method') || el.attr('data-method') || 'GET',
-            url         = el.attr('action') || el.attr('data-url') || '#',
-            async       = el.attr('data-remote-type') === 'synchronous' ? false : true,
-            update      = el.attr('data-update-success'),
-            position    = el.attr('data-update-position');
-
-        if (el.attr('data-submit')) {
-            data = $('#' + el.attr('data-submit')).serializeArray();
-        } else if (el.attr('data-with')) {
-            data = el.attr('data-with');
-        } else if(e.target.tagName.toUpperCase() == 'FORM') {
-            data = el.serializeArray();
-        } else if(e.target.tagName.toUpperCase() == 'INPUT') {
-            data = el.closest('form').serializeArray();
-        }
-
-        if(condition) {
-            el.trigger('before');
+            if (el.attr('data-submit')) {
+                data = $('#' + el.attr('data-submit')).serializeArray();
+            } else if (el.attr('data-with')) {
+                data = el.attr('data-with');
+            } else if (e && e.target.tagName.toUpperCase() == 'FORM') {
+                data = el.serializeArray();
+            } else if (e && e.target.tagName.toUpperCase() == 'INPUT') {
+                data = el.closest('form').serializeArray();
+            }
 
-            $.ajax({
-                async: async,
-                url: url,
-                data: data,
-                type: method.toUpperCase(),
-                beforeSend: function (xhr) {
-                    el.trigger('after', xhr);
-                    el.trigger('loading', xhr);
-                },
-                success: function (data, status, xhr) {
-                    el.trigger('success', [data, status, xhr]);
-                    
-                    if (update) {
-                        var element = update.charAt(0) == '#' ? update : '#' + update;
-                        if(position) {
-                            switch(el.attr('data-update-position')) {
-                                case "before":
-                                    $(element).before(data); 
-                                    break;
-                                case "after":
-                                    $(element).after(data); 
-                                    break;
-                                case "top":
-                                    $(element).prepend(data); 
-                                    break;
-                                case "bottom":
-                                    $(element).append(data); 
-                                    break;
-                                default:
-                                    $(element).append(data); 
-                                    break;
-                            }
-                        } else {
-                            $(element).html(data); 
+            if (condition) {
+                el.trigger('rails:before');
+                
+                $.ajax({
+                    async: async,
+                    url: url,
+                    data: data,
+                    type: method.toUpperCase(),
+                    beforeSend: function (xhr) {
+                        el.trigger('rails:after', xhr);
+                        el.trigger('rails:loading', xhr);
+                    },
+                    success: function (data, status, xhr) {
+                        el.trigger('rails:success', [data, status, xhr]);
+                        if (el.attr('data-update-success')) {
+                           rails.update(el.attr('data-update-success'), data, el.attr('data-update-position')); 
+                        }
+                    },
+                    complete: function (xhr) {
+                        el.trigger('rails:complete', xhr);
+                        el.trigger('rails:loaded', xhr);
+                    },
+                    error: function (xhr, status, error) {
+                        el.trigger('rails:failure', [xhr, status, error]);
+                        if (el.attr('data-update-failure')) {
+                           rails.update(el.attr('data-update-failure'), data, el.attr('data-update-position')); 
                         }
                     }
-                },
-                complete: function (xhr) {
-                    el.trigger('complete', xhr);
-                    el.trigger('loaded', xhr);
-                },
-                error: function (xhr, status, error) {
-                    el.trigger('failure', [xhr, status, error]);
-                }
-            });
+                });
+            }
+            e.preventDefault();
         }
-
-        e.preventDefault();
     }
 
-    $('form[data-remote="true"]').live('submit', handleRemote);
-    $('a[data-remote="true"],input[data-remote="true"],input[data-remote-submit="true"]').live('click', handleRemote);
+    /**
+     * observe_form, and observe_field
+     */
+    $('script[data-observe="true"]').each(function (index, el) {
+        // TODO: hook to onchange event of field or form being observed
+    });
+
+    /**
+     * periodically_call_remote
+     */
+    $('script[data-periodical="true"]').each(function (index, e) {
+        var el          = $(e),
+            frequency   = el.attr('data-frequency') ? el.attr('data-frequency') : 10,
+            remote      = function() {
+                var event = new jQuery.Event('periodical');
+                event.target = e;
+
+                rails.remote.call(el, event);
+            };
+
+        setInterval(remote, frequency * 1000);
+    });
+
+    /**
+     * remote_form_tag, and remote_form_for
+     */
+    $('form[data-remote="true"]').live('submit', rails.remote);
+
+    /**
+     * link_to_remote, button_to_remote, and submit_to_remote
+     */
+    $('a[data-remote="true"],input[data-remote="true"],input[data-remote-submit="true"]').live('click', rails.remote);
+   
+
+    /**
+     *
+     * Rails 2.x Helper / Event Handlers
+     * By default we listen to all callbacks, and status code callbacks and
+     * check the element for data-<callback> attribute and eval it.
+     *
+     */
+    rails.compat = {
+        evalAttribute: function (element, attribute) {
+            var el = $(element),
+                attr = el.attr('data-' + attribute);
+            return (attr) ? eval(attr) : true;
+        }
+    };
+
+    $('form[data-remote="true"],a[data-remote="true"],input[data-remote="true"]')
+        .live('rails:before', function (e) {
+            rails.compat.evalAttribute(this, 'onbefore'); 
+        })
+        .live('rails:after', function (e, xhr) {
+            rails.compat.evalAttribute(this, 'onafter'); 
+        })
+        .live('rails:loading', function (e, xhr) {
+            rails.compat.evalAttribute(this, 'onloading'); 
+        })
+        .live('rails:loaded', function (e, xhr) {
+            rails.compat.evalAttribute(this, 'onloaded'); 
+        })
+        .live('rails:complete', function (e, xhr) {
+            rails.compat.evalAttribute(this, 'oncomplete'); 
+            rails.compat.evalAttribute(this, 'on' + xhr.status); 
+        })
+        .live('rails:success', function (e, data, status, xhr) {
+            rails.compat.evalAttribute(this, 'onsuccess'); 
+        })
+        .live('rails:failure', function (e, xhr, status, error) {
+            rails.compat.evalAttribute(this, 'onfailure'); 
+        });
 });
-- 
cgit v1.2.3