diff --git a/.gitignore b/.gitignore index 7bcf3a845be62cfeea00432a89238f691a725877..1e0769a5a38fa00943aaf27e6ae7d95182ea24f9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .idea *.iml *.log +*--xx* src/generated gradle.properties /out diff --git a/src/main/webapp/WEB-INF/tags/page/xnat.tag b/src/main/webapp/WEB-INF/tags/page/xnat.tag index ff50a8a2f87ac7fc4c18e399584766fffb9199e3..3172fa51765da68a48c0c2a406d241d49015afc1 100755 --- a/src/main/webapp/WEB-INF/tags/page/xnat.tag +++ b/src/main/webapp/WEB-INF/tags/page/xnat.tag @@ -196,11 +196,13 @@ <script src="${_siteRoot}/scripts/xnat/xhr.js"></script> <script src="${_siteRoot}/scripts/xnat/event.js"></script> <script src="${_siteRoot}/scripts/xnat/element.js"></script> + <script src="${_siteRoot}/scripts/xnat/ui/input.js"></script> <script src="${_siteRoot}/scripts/xnat/ui/table.js"></script> <script src="${_siteRoot}/scripts/xnat/ui/panel.js"></script> <script src="${_siteRoot}/scripts/xnat/ui/tabs.js"></script> <script src="${_siteRoot}/scripts/xnat/ui/popup.js"></script> <script src="${_siteRoot}/scripts/xnat/ui/dialog.js"></script> + <script src="${_siteRoot}/scripts/xnat/spawner.js"></script> <%--<script src="${_siteRoot}/scripts/timeLeft.js"></script>--%> diff --git a/src/main/webapp/page/admin/index.jsp b/src/main/webapp/page/admin/index.jsp index 98fb2ccdcc0b6d3a3b2ce161da90c1be09ceb55b..fcef2c3abf47adaf89b49fff5e75eda3580f60fb 100644 --- a/src/main/webapp/page/admin/index.jsp +++ b/src/main/webapp/page/admin/index.jsp @@ -7,7 +7,13 @@ <pg:wrapper> <pg:xnat> - <jsp:include page="content.jsp"/> + <c:set var="view" value="${param.view}"/> + + <c:if test="${empty view}"> + <c:set var="view" value="content"/> + </c:if> + + <jsp:include page="${view}.jsp"/> </pg:xnat> </pg:wrapper> diff --git a/src/main/webapp/page/admin/spawner/content.jsp b/src/main/webapp/page/admin/spawner/content.jsp index 125460e23f5dcced23d362b5a9b94da19bc9984f..f88970506132f6c8c0c1eb19fcea9edbe8ca4738 100644 --- a/src/main/webapp/page/admin/spawner/content.jsp +++ b/src/main/webapp/page/admin/spawner/content.jsp @@ -19,10 +19,10 @@ <c:set var="_siteRoot" value="${sessionScope.siteRoot}"/> - <c:import url="/xapi/spawner/resolve/siteAdmin/siteAdmin" var="siteAdmin"/> + <%--<c:import url="/xapi/spawner/resolve/siteAdmin/siteAdmin" var="siteAdmin"/>--%> <%--<button type="button" id="view-json">View JSON</button>--%> - <div class="hidden">${siteAdmin}</div> + <%--<div class="hidden">${siteAdmin}</div>--%> <!-- button element will be rendered in this span --> <span id="view-json"></span> diff --git a/src/main/webapp/page/content.jsp b/src/main/webapp/page/content.jsp index ac529c2154212cc08eb53f30197413ec3cc18fd5..e7deaccfcba687842739815e27ced60d4862dfe4 100755 --- a/src/main/webapp/page/content.jsp +++ b/src/main/webapp/page/content.jsp @@ -24,9 +24,9 @@ customPage.getPage('', $pageContent); - window.onhashchange = function(){ - customPage.getPage('', $pageContent); - } +// window.onhashchange = function(){ +// customPage.getPage('', $pageContent); +// } })(); </script> diff --git a/src/main/webapp/scripts/lib/spawn/spawn.js b/src/main/webapp/scripts/lib/spawn/spawn.js index 683d9f32ab9adaed3024e8cddc96be0adbdd6ef4..602acd0dd980d411827e041fbdf848806407a5a4 100644 --- a/src/main/webapp/scripts/lib/spawn/spawn.js +++ b/src/main/webapp/scripts/lib/spawn/spawn.js @@ -120,7 +120,7 @@ var el, $el, parts, id, classes, tagParts, attrs, isVoid, // property names to skip later skip = ['innerHTML', 'html', 'append', 'appendTo', - 'classes', 'attr', 'data', 'fn'], + 'classes', 'className', 'attr', 'data', 'fn'], errors = []; // collect errors // deal with passing an array as the only argument @@ -217,8 +217,8 @@ } // allow use of 'classes' property for classNames - if (opts.className || opts.classes){ - el.className = [].concat(opts.className||[], opts.classes||[]).join(' ').trim(); + if (opts.className || opts.classes || opts.addClass){ + el.className = [].concat(opts.className||[], opts.classes||[], opts.addClass||[]).join(' ').trim(); } // add attributes and properties to element diff --git a/src/main/webapp/scripts/xnat/spawner.js b/src/main/webapp/scripts/xnat/spawner.js index 49249c0f14abcd2f0a76b08491a26906e4900d6e..07c7709816f506864aa93c009d1c95dcd641e487 100644 --- a/src/main/webapp/scripts/xnat/spawner.js +++ b/src/main/webapp/scripts/xnat/spawner.js @@ -17,29 +17,138 @@ var XNAT = getObject(XNAT); }(function(){ var undefined, - spawner = getObject(XNAT.spawner||{}); + ui, spawner, + NAMESPACE = 'XNAT.ui', + $ = jQuery || null, // check and localize + hasConsole = console && console.log; - function Spawner(obj){ - extend(true, this, obj); - this.spawned = null; - this.children = {}; - } + XNAT.ui = + getObject(XNAT.ui||{}); + XNAT.spawner = spawner = + getObject(XNAT.spawner||{}); - Spawner.p = Spawner.prototype; + // keep track of items that spawned + spawner.spawnedElements = []; + + // keep track of items that didn't spawn + spawner.notSpawned = []; - Spawner.p.init = function(obj){ - }; + // ================================================== + // MAIN FUNCTION + spawner.spawn = function SPAWN(obj){ + + var frag = document.createDocumentFragment(), + $frag = $(frag); + + forOwn(obj, function(item, o){ + + var kind, method, spawned, + // save the config properties in a new object + config = o.config || o.element || {}; + + // use 'name' property in element or config + // then look for 'name' at object root + // lastly use the object name + config.name = config.name || o.name || item; + + // accept 'kind' or 'type' property name + // but 'kind' will take priority + // with a fallback to a generic div + kind = o.kind || o.type || 'div.spawned'; + + // do a raw spawn() if 'kind' is 'element' + // or if there's a tag property + if (kind === 'element' || o.tag){ + try { + spawned = window.spawn(o.tag||config.tag||'div', config); + // jQuery's .append() method is + // MUCH more robust and forgiving + // than element.appendChild() + $frag.append(spawned); + spawner.spawnedElements.push(spawned); + } + catch (e) { + if (hasConsole) console.log(e); + spawner.notSpawned.push(config); + } + } + else { + // check for a matching XNAT.ui method to call: + // XNAT.ui.kind() + method = eval(NAMESPACE+'.'+kind); + + // only spawn elements with defined methods + if (isFunction(method)) { + + // 'spawned' item will be an HTML element + spawned = method(config); + + // add the spawned element to the master frag + $frag.append(spawned); + + // save a reference to the spawned element + spawner.spawnedElements.push(spawned); + + } + else { + spawner.notSpawned.push(item); + } + } + + // spawn child elements from 'contents' + if (o.contents || o.content || o.children) { + o.contents = o.contents || o.content || o.children; + $frag.append(SPAWN(o.contents).spawned); + } + + }); + + SPAWN.spawned = frag; + + SPAWN.children = $frag.contents(); + + SPAWN.get = function(){ + return frag; + }; + + SPAWN.render = function(element, empty){ + var $el = $$(element); + // empty the container element before spawning? + if (empty){ + $el.empty(); + } + $el.append(frag); + return spawn; + }; + + SPAWN.foo = '(spawn.foo)'; + + return SPAWN; - Spawner.p.render = function($container){ - $$($container).append(this.spawned); - return this; }; + // ================================================== - spawner.spawn = function(obj){ - return new Spawner(obj); + + spawner.testSpawn = function(){ + var jsonUrl = + XNAT.url.rootUrl('/page/admin/data/config/site-admin-sample-new.json'); + return $.getJSON({ + url: jsonUrl, + success: function(data){ + spawner.spawn(data); + console.log('spawnedElements:'); + console.log(spawner.spawnedElements); + console.log('notSpawned:'); + console.log(spawner.notSpawned); + } + }); }; + + // this script has loaded + spawner.loaded = true; + return XNAT.spawner = spawner; })); diff --git a/src/main/webapp/scripts/xnat/ui/input.js b/src/main/webapp/scripts/xnat/ui/input.js new file mode 100644 index 0000000000000000000000000000000000000000..476768e3814e8669872c89be8b7cbab7e2c7cc94 --- /dev/null +++ b/src/main/webapp/scripts/xnat/ui/input.js @@ -0,0 +1,105 @@ +/*! + * Spawn UI elements using the Spawner service + */ + +var XNAT = getObject(XNAT); + +(function(factory){ + if (typeof define === 'function' && define.amd) { + define(factory); + } + else if (typeof exports === 'object') { + module.exports = factory(); + } + else { + return factory(); + } +}(function(){ + + var undefined, uiInput, textTypes, + numberTypes, otherTypes, + $ = jQuery || null, // check and localize + ui, input; + + XNAT.ui = getObject(XNAT.ui||{}); + + XNAT.ui.input = + input = XNAT.ui.input || {}; + + + // if XNAT.ui.input is already defined, + // save it and its properties to add later + // as methods and properties to the function + uiInput = input || null; + + + // ======================================== + // MAIN FUNCTION + input = function(type, config){ + // only one argument? + // could be a config object + if (!config && typeof type != 'string') { + config = type; + type = null; // it MUST contain a 'type' property + } + config = getObject(config); + config.type = type || config.type || 'text'; + return spawn('input', config) + }; + // ======================================== + + + function setupType(type, className, config){ + config = getObject(config); + config.addClass = className; + config.data = extend({ validate: type }, config.data); + if (!config.data.validate) delete config.data.validate; + return input(type, config); + } + + // methods for direct creation of specific input types + // some are 'real' element types, others are XNAT-specific + textTypes = [ + 'text', 'email', 'url', 'strict', + 'id', 'alpha', 'alphanum' + ]; + textTypes.forEach(function(type){ + input[type] = function(config){ + return setupType('text', type, config); + } + }); + + numberTypes = ['number', 'int', 'integer', 'float']; + numberTypes.forEach(function(type){ + input[type] = function(config){ + return setupType('number', type, config); + } + }); + + otherTypes = [ + 'password', 'date', 'checkbox', + 'radio', 'button', 'hidden' + ]; + otherTypes.forEach(function(type){ + input[type] = function(config){ + return setupType(type, type, config); + } + }); + + // save a list of all available input types + input.types = [].concat(textTypes, numberTypes, otherTypes); + + // add back items that may have been on + // a global XNAT.ui.input object + if (uiInput && isPlainObject(uiInput)) { + forOwn(uiInput, function(item, value){ + input[item] = value; + }) + } + + // this script has loaded + input.loaded = true; + + return XNAT.ui.input = input; + +})); diff --git a/src/main/webapp/scripts/xnat/ui/tab.js b/src/main/webapp/scripts/xnat/ui/tab.js new file mode 100644 index 0000000000000000000000000000000000000000..444eb93e2075c280a3710ce034379f5be8c73252 --- /dev/null +++ b/src/main/webapp/scripts/xnat/ui/tab.js @@ -0,0 +1,27 @@ +/*! + * Functions for creating XNAT tab UI elements + */ + +var XNAT = getObject(XNAT||{}); + +(function(factory){ + if (typeof define === 'function' && define.amd) { + define(factory); + } + else if (typeof exports === 'object') { + module.exports = factory(); + } + else { + return factory(); + } +}(function(){ + + var tab; + + // just one tab + XNAT.ui.tab = tab = + getObject(XNAT.ui.tab || {}); + + + +})); diff --git a/src/main/webapp/scripts/xnat/ui/tabs.js b/src/main/webapp/scripts/xnat/ui/tabs.js index f5c365b68c65f81371a4e0c47002520190079a79..8b5c40e711419ce340675a424f9d4f35bbacc35a 100755 --- a/src/main/webapp/scripts/xnat/ui/tabs.js +++ b/src/main/webapp/scripts/xnat/ui/tabs.js @@ -6,23 +6,33 @@ var XNAT = getObject(XNAT||{}); (function(XNAT, $, window, undefined){ - var ui, tabs, page, + var ui, tab, tabs, page, element = XNAT.element; var $body = $(document.body); - XNAT.ui = ui = getObject(XNAT.ui || {}); - XNAT.ui.tabs = XNAT.tabs = tabs = getObject(XNAT.ui.tabs || {}); - XNAT.page = page = getObject(XNAT.page || {}); + XNAT.ui = ui = + getObject(XNAT.ui || {}); + + // just one tab + XNAT.ui.tab = tab = + getObject(XNAT.ui.tab || {}); + + // a whole bunch of tabs + XNAT.ui.tabs = XNAT.tabs = tabs = + getObject(XNAT.ui.tabs || {}); + + XNAT.page = page = + getObject(XNAT.page || {}); /** * Initialize the tabs - * @param [tabsArray] {Array} array of tab config objects + * @param [tabItems] {Array} array of tab config objects * @param [container] {Element} parent element for tabs * @returns {{}} */ - function init(tabsArray, container){ + function init(tabItems, container){ // a place to store things locally var __ = {}; @@ -244,7 +254,7 @@ var XNAT = getObject(XNAT||{}); __.tabs.$panes.addClass('side pull-'+other); } - [].concat(config).forEach(function(item){ + $.each(config, function(name, item){ if (item.kind !== 'tab') { if (item.kind === 'meta'){ @@ -296,9 +306,9 @@ var XNAT = getObject(XNAT||{}); // expose globally __.setup = setupTabs; - // run setup on init() if 'tabsArray' is present - if (tabsArray && tabsArray.length){ - setupTabs(tabsArray); + // run setup on init() if 'tabItems' is present + if (tabItems){ + setupTabs(tabItems); } __.render = function(container){