From f7e34a197d0f149f6ddc0c0c058637f7005aaff2 Mon Sep 17 00:00:00 2001 From: Sam Lown Date: Tue, 16 Feb 2010 18:24:28 +0100 Subject: [PATCH] Cleaning document processing and adding better AJAX error handling --- public/javascripts/admin.js | 92 ++++++--------------------- public/javascripts/application.js | 100 +++++++++++++++++++----------- 2 files changed, 82 insertions(+), 110 deletions(-) diff --git a/public/javascripts/admin.js b/public/javascripts/admin.js index 96eb2f2..d218c14 100644 --- a/public/javascripts/admin.js +++ b/public/javascripts/admin.js @@ -34,42 +34,8 @@ $(document).ready( function(){ return false; }); - /* Not convinced, I think its easier to show them all the time - $('.documentBody, .commentBody').hover( - function() { - $(this).find('.sideActions').show(); - }, - function() { - var doc = $(this); - setTimeout(function(){ doc.find('.sideActions').hide(250); }, 200); - } - ); - */ - }); -/* - * Send the provided form object using AJAX and parse the results provided as JSON. - * - * The following options are supported: - * params: Array of aditional name, value objects to append to serializeArray. - * - */ -function ajaxAndParse(form, options, callback) { - options = $.extend({params: [], method: 'get'}, options); - options.params = options.params.concat($(form).serializeArray()); - if (options.method == 'get') { - $.get($(form).attr('action'), options.params, callback, 'json'); - } else if (options.method == 'post') { - $.post($(form).attr('action'), options.params, callback, 'json'); - } -} - -function postAndParse(form, options, callback) { - options = $.extend({method: 'post'}, options); - ajaxAndParse(form, options, callback); -} - /* * Methods related to handling actions performed on documents while being viewed (not edited). */ @@ -89,25 +55,24 @@ $.documentActions = { }); }, - save: function(form, options) { - postAndParse(form, options, function(result) { + save: function(form) { + $.post(form.attr('action'), form.serializeArray(), function(result) { if (result.state == 'win') { window.location.reload(); } else { alert(result.msg); } - }); + }, 'json'); } }; + + /* * Methods for handling the document form, including loading the form itself. */ $.documentForm = { - // URL to redirect to, mainly when the slug has changed. - redirectToUrl: '', - bindings: function() { $('.documentFormAction').live('click', function() { $.documentForm.edit($(this)); return false; }); @@ -115,7 +80,7 @@ $.documentForm = { // save with the buttons name and value var options = { // provide button specific details - params: [ {name: $(this).attr('name'), value: $(this).attr('value')} ], + extraParams: [ {name: $(this).attr('name'), value: $(this).attr('value')} ], // Delay refresh for when form closed for drafts noRefresh: $(this).attr('value') == 'draft' }; @@ -128,7 +93,9 @@ $.documentForm = { return false; }); - // Handle auto generating the slug + /* + * Handle auto generating the slug + */ $('form .slugOrigin input').live('keyup', function() { if ($('form input.originalSlug').val() == '') { // DRY alert! See also models/document.rb @@ -138,8 +105,6 @@ $.documentForm = { $(this).parents('form').find('.slugUrlField input').val(slug); } }); - - $('form .slug .slugUrl a').live('click', function() { var slug = $(this).siblings('.slug').html(); $(this).parent().addClass('hidden').siblings('.slugUrlField').removeClass('hidden').find('input').val(slug); @@ -158,7 +123,6 @@ $.documentForm = { var title = link.attr('title'); $.stdDialog.show(title); $.get(link.attr('href'), '', function(result) { - // Lock the window scrolling $.stdDialog.html(result.view); }, 'json'); }, @@ -167,46 +131,28 @@ $.documentForm = { * Save the document, parse the result and either redraw dialog or refresh page. */ save: function(form, options) { - // Disable all the buttons first - form.find('button').attr('disabled', 'disabled'); - // $.stdDialog.loading(); - postAndParse(form, options, function(result) { - if (result.state == 'win') { - if (! options.noRefresh) { + $.stdDialog.submit(form, { + extraParams: options.extraParams, + success: function(result) { + if (!options.noRefresh) { if (result.redirect) window.location = result.url; else window.location.reload(); } else { if (result.redirect) { - $.documentForm.redirectToUrl = result.url; - } else { - $.stdDialog.html(result.view); - $('#dialog form').addClass('dirty'); - } + $('#dialog form').data('redirectOnClose', result.url); // When slug changes + } + $.stdDialog.html(result.view); + $('#dialog form').addClass('dirty'); } - } else { + }, + failure: function(result) { $.stdDialog.html(result.view); $('#dialog form').addClass('dirty'); - // alert(result.msg); } }); - }, - - /* - * Alias for save - */ - update: function(form, options) { - return $.documentForm(form, options); - }, - - /* - * Alias for save - */ - create: function(form, options) { - return $.documentForm(form, options); } - }; diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 1025151..bb10e4c 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -72,9 +72,6 @@ $.commentActions = { $.stdDialog = { - redirectToUrl: null, - formPostCallback: null, - bindings: function() { // Bind to generic dialog link (not live!) $('a.dialogLink, a[data-dialog]').live('click', function() { @@ -85,34 +82,9 @@ $.stdDialog = { return false; }); - $('#dialog form button[type=submit]').live('click', function() { - var form = $(this).parents('form'); - var hasFiles = form.find('input[type=file]').length > 0; - $.stdDialog.loading(); - form.ajaxSubmit({ - iframe: hasFiles, - dataType: 'json', - success: function(result) { - if ($.stdDialog.formPostCallback) { - $.stdDialog.formPostCallback(result); - $.stdDialog.formPostCallback = null; - } else { - if (result.state == 'win') { - if (result.view) { - $.stdDialog.html(result.view); - } else { - window.location.reload(); - } - } else { - if (result.msg) alert(result.msg); - $.stdDialog.html(result.view); - } - } - } - }); - return false; // ignore the button press + $('#dialog form').live('submit', function() { + $.stdDialog.submit($(this)); return false; }); - }, show: function(title, contents, options) { @@ -125,11 +97,12 @@ $.stdDialog = { width: 750, height: ($(window).height() - 50), dialogClass: 'simple', close: function() { - if ($('#dialog form').hasClass('dirty')) { - if ($.stdDialog.redirectToUrl == '') - window.location.reload(); + var form = $('#dialog form'); + if (form.hasClass('dirty')) { + if (form.data('redirectOnClose')) + window.location = form.data('redirectOnClose'); else - window.location = $.stdDialog.redirectToUrl; + window.location.reload(); } else { $('html,body').smoothScrollBack('stop'); $('#dialog').dialog('destroy'); @@ -145,7 +118,12 @@ $.stdDialog = { }, loading: function() { - $('#dialog').children().hide().after($('#dialogSpinner').html()); + $('#dialog').children().hide().after($('#dialogSpinner').clone().show()); + }, + // If there was an error loading, return the dialog back to how it was. + loadingFailed: function() { + $('#dialog').find('#dialogSpinner').remove(); + $('#dialog').children().show(); }, html: function(contents) { @@ -160,8 +138,56 @@ $.stdDialog = { hide: function() { $('html,body').smoothScrollBack('stop'); $('#dialog').dialog('close'); - } + }, + + submit: function(form, options) { + options = $.extend({ + success: function(result) { + if (result.view) { + $.stdDialog.html(result.view); + } else { + window.location.reload(); + } + }, + failure: function(result) { + if (result.msg) alert(result.msg); + $.stdDialog.html(result.view); + }, + error: function() { + // Setup ajax error handling + $.stdDialog.loadingFailed(); + alert('Unable to load page, check connection and try again!'); + }, + extraParams: null // in format: [ name: "foo", value: "bar" ] + }, options); + + // Do we need to include extra parameters? (button press details perhaps?) + var beforeSubmit = null; + if (options.extraParams) { + beforeSubmit = function(a) { + $.each(options.extraParams, function(i, item) { + a.push(item); + }); + return true; + } + } + var hasFiles = form.find('input[type=file]').length > 0; + $.stdDialog.loading(); + form.ajaxSubmit({ + iframe: hasFiles, + dataType: 'json', + beforeSubmit: beforeSubmit, + error: options.error, + success: function(result) { + if (result.state == 'win') { + options.success(result); + } else { + options.failure(result); + } + } + }); + } } $.fn.smoothScrollBack = function(command) { @@ -206,8 +232,8 @@ $.smoothScrollBack = { $(document).ready(function() { + $.stdDialog.bindings(); // This should always be first! $.commentActions.bindings(); - $.stdDialog.bindings(); $('a[data-confirm]').live('click', function() { if (confirm($(this).attr('data-confirm'))) {