diff --git a/src/main/webapp/page/admin/content.jsp b/src/main/webapp/page/admin/content.jsp
index eb1e2e49acbb2d318c4f0b8448a1fc967f8b5938..084adbec7d63612ab5af33437498baf6d1a10813 100755
--- a/src/main/webapp/page/admin/content.jsp
+++ b/src/main/webapp/page/admin/content.jsp
@@ -3,7 +3,7 @@
 <%@ taglib prefix="pg" tagdir="/WEB-INF/tags/page" %>
 
 <c:set var="redirect">
-    <p>Not authorized. Redirecting...</p>
+    <div class="error">Not authorized. Redirecting...</div>
     <script> window.location.href = XNAT.url.rootUrl('/') </script>
 </c:set>
 
@@ -48,7 +48,10 @@
                 <script>
                     (function(){
 
-                        XNAT.data = getObject(XNAT.data);
+                        XNAT.data = extend(true, {
+                            siteConfig: {},
+                            notifications: {}
+                        }, XNAT.data);
 
                         <%-- safety check --%>
                         <c:if test="${not empty siteConfig}">
@@ -68,7 +71,7 @@
                             url: jsonUrl,
                             success: function(data){
 
-                                // these properties need to be set before spawning 'tabs' widgets
+                                // these properties MUST be set before spawning 'tabs' widgets
                                 XNAT.tabs.container = $('#admin-config-tabs').find('div.content-tabs');
                                 XNAT.tabs.layout = 'left';
 
@@ -76,9 +79,9 @@
                                 var adminTabs = XNAT.spawner.spawn(data);
 
                                 adminTabs.render(XNAT.tabs.container, 500, function(){
-                                    if (window.location.hash) {
-                                        XNAT.ui.tab.select(getUrlHashValue(), XNAT.tabs.container);
-                                    }
+                                    //if (window.location.hash) {
+                                    //    XNAT.ui.tab.select(getUrlHashValue());
+                                    //}
                                 });
 
                                 // SAVE THE UI JSON
diff --git a/src/main/webapp/scripts/xnat/spawner.js b/src/main/webapp/scripts/xnat/spawner.js
index ad383ccef165fd3ce3c536bfedb6df343b3ad80d..afae05a62ca7b230b6253734f8c7d4e64a8a327e 100644
--- a/src/main/webapp/scripts/xnat/spawner.js
+++ b/src/main/webapp/scripts/xnat/spawner.js
@@ -46,6 +46,7 @@ var XNAT = getObject(XNAT);
 
         var frag  = document.createDocumentFragment(),
             $frag = $(frag),
+            callbacks = [],
             undefined;
 
         spawner.counter++;
@@ -132,8 +133,9 @@ var XNAT = getObject(XNAT);
                 if (isFunction(method)) {
 
                     // 'spawnedElement' item will be an
-                    // object with a .get() method that
-                    // will retrieve the spawned item
+                    // object with an 'element' property 
+                    // or a .get() method that will retrieve 
+                    // the spawned item
                     spawnedElement = method(prop);
 
                     // add spawnedElement to the master frag
@@ -200,7 +202,16 @@ var XNAT = getObject(XNAT);
 
             // if there's a .load() method, fire that
             if (isFunction(spawnedElement.load||null)) {
-                spawnedElement.load();
+                spawnedElement.load.call(spawnedElement);
+            }
+            
+            // if there's an .onRender() method, queue it
+            if (isFunction(spawnedElement.onRender||null)) {
+                callbacks.push({
+                    onRender: spawnedElement.onRender,
+                    spawned: spawnedElement,
+                    $element: $spawnedElement
+                });
             }
 
         });
@@ -235,11 +246,21 @@ var XNAT = getObject(XNAT);
             $container.append(frag);
             $container.fadeIn(wait);
 
-            //setTimeout(function(){
+            // fire collected callbacks
+            callbacks.forEach(function(obj){
+                try {
+                    obj.onRender.call(obj.spawned, obj.$element, obj);
+                }
+                catch(e) {
+                    console.log(e)
+                }
+            });
+
+            setTimeout(function(){
                 if (isFunction(callback)) {
                     callback()
                 }
-            //}, wait);
+            }, wait/2);
 
             return _spawn;
 
diff --git a/src/main/webapp/scripts/xnat/ui/input.js b/src/main/webapp/scripts/xnat/ui/input.js
index 0b9476a75af73e486d84ab22c780c237e7263af2..d96838c4d2779e1efe2de61ae732c6adb504e788 100644
--- a/src/main/webapp/scripts/xnat/ui/input.js
+++ b/src/main/webapp/scripts/xnat/ui/input.js
@@ -133,7 +133,7 @@ var XNAT = getObject(XNAT);
 
     // after the page is finished loading, set empty
     // input values from [data-lookup] attribute
-    $(window).load(function(){
+    $(window).on('load', function(){
         $(':input[data-lookup]').each(function(){
             var $input = $(this);
             var val = lookupValue($input.dataAttr('lookup'));
diff --git a/src/main/webapp/scripts/xnat/ui/panel.js b/src/main/webapp/scripts/xnat/ui/panel.js
index e96705007fca95dd9a75140ab278010f281c6356..d08f8cc8454b745093a4a9a305e07b1f5e650a40 100644
--- a/src/main/webapp/scripts/xnat/ui/panel.js
+++ b/src/main/webapp/scripts/xnat/ui/panel.js
@@ -120,6 +120,10 @@ var XNAT = getObject(XNAT || {});
         opts.title = opts.title || opts.label || opts.header;
         opts.name = opts.name || opts.element.name || opts.id || opts.element.id || randomID('form-', false);
 
+        addDataObjects(opts, {
+            panel: toDashed(opts.name)
+        });
+
         var _target = spawn('div.panel-body', opts.element),
 
             hideHeader = (isDefined(opts.header) && (opts.header === false || /^-/.test(opts.title))),
@@ -138,10 +142,12 @@ var XNAT = getObject(XNAT || {});
             ],
 
             _formPanel = spawn('form.validate.xnat-form-panel.panel.panel-default', {
+                id: toDashed(opts.id || opts.element.id || opts.name) + '-panel',
                 name: opts.name,
                 method: opts.method || 'POST',
                 action: opts.action ? XNAT.url.rootUrl(opts.action) : '#!',
-                addClass: opts.classes || ''
+                addClass: opts.classes || '',
+                data: opts.data
             }, [
 
                 (hideHeader ? ['div.hidden'] : ['div.panel-heading', [
@@ -151,16 +157,10 @@ var XNAT = getObject(XNAT || {});
                 // target is where this form's "contents" will be inserted
                 _target,
 
-                
                 (hideFooter ? ['div.hidden'] : ['div.panel-footer', opts.footer || _footer])
 
             ]);
-
-        // add an id to the outer panel element if present
-        if (opts.id || opts.element.id) {
-            _formPanel.id = (opts.id || opts.element.id) + '-panel';
-        }
-
+        
         // cache a jQuery-wrapped element
         var $formPanel = $(_formPanel);
 
@@ -587,6 +587,11 @@ var XNAT = getObject(XNAT || {});
             }
         }
     };
+    
+    // setup a dialog box that contains stuff
+    panel.dialogForm = panel.formDialog = function(opts){
+        var dialog = new xmodal.Modal    
+    };
 
     // create a single generic panel element
     panel.element = function(opts){
diff --git a/src/main/webapp/scripts/xnat/ui/tabs.js b/src/main/webapp/scripts/xnat/ui/tabs.js
index 205cda4afe6e38727475056eebd8c61264f7039c..61bec657552be5fde90b963b8a7246cf0d4bf80d 100755
--- a/src/main/webapp/scripts/xnat/ui/tabs.js
+++ b/src/main/webapp/scripts/xnat/ui/tabs.js
@@ -16,7 +16,8 @@ var XNAT = getObject(XNAT || {});
     }
 }(function(){
 
-    var ui, tab, tabs, page;
+    var ui, tab, tabs, page,
+        urlHashValue = getUrlHashValue('#',':');
     
     XNAT.ui = ui =
         getObject(XNAT.ui || {});
@@ -61,7 +62,7 @@ var XNAT = getObject(XNAT || {});
 
 
     // save the id of the active tab
-    XNAT.ui.tab.active = '';
+    tab.active = '';
 
 
     // ==================================================
@@ -77,12 +78,12 @@ var XNAT = getObject(XNAT || {});
     // CREATE A SINGLE TAB
     tab.init = function _tab(obj){
 
-        var $group, groupId, tabId, _flipper, _pane;
+        var $group, groupId, tabId, tabIdHash, _flipper, _pane;
 
         obj = cloneObject(obj);
         obj.config = cloneObject(obj.config);
 
-        tabId = toDashed(obj.id || obj.name || '');
+        tabId = toDashed(obj.id || obj.name || randomID('t', false));
 
         _flipper = spawn('li.tab', {
             data: { tab: tabId }
@@ -115,10 +116,18 @@ var XNAT = getObject(XNAT || {});
 
         _pane = spawn('div.tab-pane', obj.config);
 
-        if (obj.active) {
-            $(_flipper).addClass('active');
-            $(_pane).addClass('active');
-            tab.active = _pane.id;
+        // if 'active' is explicitly set, use the tabId value
+        obj.active = (obj.active) ? tabId : '';
+
+        // set active tab on page load if tabId matches url hash
+        if (urlHashValue && urlHashValue === tabId) {
+            tabIdHash = tabId;
+        }
+
+        if ((tabIdHash||obj.active) === tabId) {
+            //$(_flipper).addClass('active');
+            //$(_pane).addClass('active');
+            tabs.active = tab.active = tabId;
         }
 
         groupId = toDashed(obj.group||'other');
@@ -132,12 +141,8 @@ var XNAT = getObject(XNAT || {});
         // add all the flippers
         $group.append(_flipper);
 
-        // console.log($group[0]);
-
-        function render(element){
-            $$(element).append(_pane);
-            $$(element).append(paneFooter());
-            return _pane;
+        function onRender(){
+            console.log('tab: ' + tabId)
         }
 
         function get(){
@@ -150,7 +155,7 @@ var XNAT = getObject(XNAT || {});
             pane: _pane,
             element: _pane,
             spawned: _pane,
-            render: render,
+            onRender: onRender,
             get: get
         }
     };
@@ -178,7 +183,7 @@ var XNAT = getObject(XNAT || {});
             tabContent.className += ' side pull-right';
         }
 
-        $container = $$(container);
+        $container = $$(container).hide();
 
         $container.append(navTabs);
         $container.append(tabContent);
@@ -199,9 +204,11 @@ var XNAT = getObject(XNAT || {});
             window.location.replace('#' + clicked);
         });
 
-        function render(element){
-            $$(element).append(tabContent);
-            return tabContent;
+        function onRender($element){
+            $container.find('li.tab, div.tab-pane').removeClass('active');
+            $container.find('[data-tab="' + tabs.active + '"]').addClass('active');
+            // console.log($element);
+            // $container.find('li.tab.active').last().trigger('click');
         }
 
         function get(){
@@ -212,13 +219,20 @@ var XNAT = getObject(XNAT || {});
             // contents: obj.tabs||obj.contents||obj.content||'',
             element: tabContent,
             spawned: tabContent,
-            render: render,
+            onRender: onRender,
             get: get
         };
 
     };
     // ==================================================
 
+    // activate tab indicated in url hash
+    // $(function(){
+    //     if (window.location.hash) {
+    //         tab.activate(getUrlHashValue())
+    //     }
+    // });
+    
     tabs.tab = tab;
 
     return tabs;