From 5584d58e656c5c09db20d15727d9387ed39f8cf2 Mon Sep 17 00:00:00 2001 From: "Stephen St. Martin" 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 (limited to 'railties/lib/generators/rails/app/templates') 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- 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