Index: trunk/web-app/js/application.js
===================================================================
--- trunk/web-app/js/application.js	(revision 857)
+++ trunk/web-app/js/application.js	(revision 859)
@@ -19,5 +19,52 @@
 }
 
-function errorIndication() {
-    return jQuery('#jQueryAjaxDefaultError').clone();
+function errorIndication(jqXHR, textStatus, errorThrown) {
+    return jQuery('#jQueryAjaxDefaultError').clone().append('Status:'+jqXHR.status+', '+textStatus+'.');
 }
+
+// Apply updates to multiple page elements.
+// @json JSON response object from an ajax request.
+// @json.updates Array of element updates to apply.
+// @element.mode The update mode: execute or replace, prepend, append.
+// @element.script Script to execute, if execute mode.
+// @element.target jQuery target selector, if update mode.
+// @element.content Content to update target with, if update mode.
+function applyElementUpdates(json) {
+    var updates;
+    var script;
+
+    if(json.updates) {
+        updates = json.updates;
+        var element;
+        var scripts = new Array();
+
+        for(element in updates) {
+            element = updates[element];
+
+            switch(element.mode) {
+                case 'execute':
+                    scripts.push(element.script);
+                    break;
+                case 'replace':
+                    jQuery(element.target).html(element.content);
+                    break;
+                case 'prepend':
+                    jQuery(element.target).prepend(element.content);
+                    break;
+                case 'append':
+                    jQuery(element.target).append(element.content);
+                    break;
+            }
+        }
+
+        // Run scripts.
+        for(script in scripts) {
+            script = scripts[script];
+            eval(script);
+        }
+
+    } // if(json.updates)
+} // applyElementUpdates
+
+
+
Index: trunk/web-app/js/taskShow.js
===================================================================
--- trunk/web-app/js/taskShow.js	(revision 857)
+++ trunk/web-app/js/taskShow.js	(revision 859)
@@ -1,28 +1,33 @@
 
-// Load data into createContainer and register events.
-function loadCreateContainer(data, createContainer, listContainer, button) {
-        // Load the response data and show container.
-        createContainer.html(data).slideDown(800);
-        // Scroll the window.
-        jQuery('html,body').animate({scrollTop: createContainer.offset().top - 70}, 900, function() {
-            createContainer.find(':input[name="comment"]').focus();
-        });
-        // Register 'submit_*' input button click handlers.
-        createContainer.find('input[name^="submit_"]').click(function(){
-            createContainer.find(':input[name="submitAction"]').val(jQuery(this).attr('name'));
-            createContainer.find('form:first').submit();
-        });
-        // Hijack form submit to use our function.
-        var eventData = {listContainer:listContainer, createContainer:createContainer, button:button};
-        createContainer.find('form:first').submit(eventData, submitCreateEntryForm);
-        // Register the close img click handler.
-        createContainer.find('.pane_close img').click(function(){
-            createContainer.slideUp(600);
-            button.show(600, function() {
-                if(jQuery.browser.msie) {
-                    jQuery(this).get(0).style.removeAttribute('filter'); // Remove blur/fuzzy text in IE.
-                }
-            });
-        });
+function showButton(button) {
+    button.show(600, function() {
+        if(jQuery.browser.msie) {
+            jQuery(this).get(0).style.removeAttribute('filter'); // Remove blur/fuzzy text in IE.
+        }
+    });
+}
+
+function createEntryFormInit(target, listContainer, button) {
+
+    // Show.
+    target.slideDown(800);
+    // Scroll the window.
+    jQuery('html,body').animate({scrollTop: target.offset().top - 70}, 900, function() {
+        target.find(':input[name="comment"]').focus();
+    });
+    // Register 'submit_*' input button click handlers.
+    target.find('input[name^="submit_"]').click(function(){
+        target.find(':input[name="submitAction"]').val(jQuery(this).attr('name'));
+        target.find('form:first').submit();
+    });
+    // Redirect form submit to use our function.
+    var eventData = {listContainer:listContainer, source:target, button:button};
+    target.find('form:first').submit(eventData, submitCreateEntryForm);
+    // Register the close img click handler.
+    target.find('.pane_close img').click(function(){
+        target.slideUp(600);
+        showButton(button);
+    });
+
 }
 
@@ -34,30 +39,27 @@
     event.preventDefault();
     var listContainer = event.data.listContainer;
-    var createContainer = event.data.createContainer;
+    var source = event.data.source;
     var button = event.data.button;
-    var form = createContainer.find('form:first');
+    var form = source.find('form:first');
 
     // On success reload listContainer.
-    function success(data, textStatus, jqXHR){
-        createContainer.hide();
-        listContainer.html(data);
-        button.show(600, function() {
-            if(jQuery.browser.msie) {
-                jQuery(this).get(0).style.removeAttribute('filter'); // Remove blur/fuzzy text in IE.
-            }
-        });
+    function success(data, textStatus, jqXHR) {
+        source.hide();
+        applyElementUpdates(data);
+        showButton(button);
     }
 
     // On create failure controller sets 403 and returns the form template.
-    function error(jqXHR, textStatus, errorThrown){
-        if(jqXHR.status == 403 && jqXHR.responseText){
-            loadCreateContainer(jqXHR.responseText, createContainer, listContainer, button);
+    function error(jqXHR, textStatus, errorThrown) {
+        if(jqXHR.status == 403 && jqXHR.responseText) {
+            source.html(jqXHR.responseText);
+            createEntryFormInit(source, listContainer, button);
         }
         else {
-            createContainer.html(savedHtml);
-            createContainer.prepend(errorIndication().show()).slideDown(600);
+            source.html(savedHtml);
+            source.prepend(errorIndication(jqXHR, textStatus, errorThrown).show()).slideDown(600);
             // Scroll the window.
-            jQuery('html,body').animate({scrollTop: createContainer.offset().top - 70}, 900, function() {
-                createContainer.find(':input[name="comment"]').focus();
+            jQuery('html,body').animate({scrollTop: source.offset().top - 70}, 900, function() {
+                source.find(':input[name="comment"]').focus();
             });
         }
@@ -65,10 +67,14 @@
 
     // Start.
-    var savedHtml = createContainer.children().detach();
-    createContainer.html(loadingIndication().show()).slideDown(600);
+    var savedHtml = source.children().detach();
+    var params = form.serializeArray();
+    params.push({name:'target', value:listContainer.selector});
+    source.html(loadingIndication().show()).slideDown(600);
 
     jQuery.ajax({
         url: actionUrl,
-        data: form.serializeArray(),
+        data: params,
+        type: 'POST',
+        dataType: 'json',
         success: success,
         error: error
@@ -78,38 +84,38 @@
 // Get a create Entry form via AJAX.
 // @listContainer Container object to reload list into.
-// @createContainer Container object to load response into.
 // @button Button object used to trigger this function.
 // @params Params map to pass to actionUrl.
-function getCreateEntryForm(listContainer, createContainer, button, params) {
+// @params.target Selector indicating target to load response into.
+function getCreateEntryForm(listContainer, button, params) {
 
     var actionUrl = getContextPath()+"/entryDetailed/ajaxCreate/";
+    var target = jQuery(params.target);
 
-    // On success load createContainer.
-    function success(data, textStatus, jqXHR){
-        loadCreateContainer(data, createContainer, listContainer, button);
+    // On success load target.
+    function success(data, textStatus, jqXHR) {
+        applyElementUpdates(data);
+        createEntryFormInit(target, listContainer, button);
     }
 
     // On error show controller responseText or show default error.
-    function error(jqXHR, textStatus, errorThrown){
-        if(jqXHR.status == 403 && jqXHR.responseText){
-            loadCreateContainer(jqXHR.responseText, createContainer, listContainer, button);
+    function error(jqXHR, textStatus, errorThrown) {
+        if(jqXHR.status == 403 && jqXHR.responseText) {
+            target.html(jqXHR.responseText);
         }
         else {
-            createContainer.html(errorIndication().show()).slideDown(600);
+            target.html(errorIndication(jqXHR, textStatus, errorThrown).show());
         }
-        button.show(600, function() {
-            if(jQuery.browser.msie) {
-                jQuery(this).get(0).style.removeAttribute('filter'); // Remove blur/fuzzy text in IE.
-            }
-        });
+        showButton(button);
     }
 
     // Start.
     button.hide(600);
-    createContainer.html(loadingIndication().show()).slideDown(600);
+    target.html(loadingIndication().show()).slideDown(600);
 
     jQuery.ajax({
         url: actionUrl,
         data: params,
+        type: 'POST',
+        dataType: 'json',
         success: success,
         error: error
