Skip to content
Snippets Groups Projects
Commit 9d5cd9f5 authored by Mark M. Florida's avatar Mark M. Florida
Browse files

XNAT-4400: Changed checkboxes to switchboxes on initial setup page;...

XNAT-4400: Changed checkboxes to switchboxes on initial setup page; enhancements to XNAT.spawner for spawning via JS (will be documented); input value syntax that will get other data on submission (used to populate email recipients for notifications from admin email during initial setup); fixed comment syntax on 'xnat.tag' file (JSP template).
parent 7a14e762
No related branches found
No related tags found
No related merge requests found
...@@ -567,19 +567,19 @@ ${bodyTop} ...@@ -567,19 +567,19 @@ ${bodyTop}
jq('.main_header').height(hdr_logo_height + 10); jq('.main_header').height(hdr_logo_height + 10);
} }
## Commented out 2016/09/02 (XNAT-4501). I don't think we want to do this (See home page when this takes effect) //Commented out 2016/09/02 (XNAT-4501). I don't think we want to do this (See home page when this takes effect)
##// adjust width of main nav if logo is wider than 175px // adjust width of main nav if logo is wider than 175px
##var hdr_logo_width = header_logo$.width(); //var hdr_logo_width = header_logo$.width();
##if (hdr_logo_width > 175) { //if (hdr_logo_width > 175) {
## jq('#main_nav').width(932 - hdr_logo_width - 20); // jq('#main_nav').width(932 - hdr_logo_width - 20);
##} //}
// //
//var recent_proj_height = jq('#min_projects_list > div').height(); //var recent_proj_height = jq('#min_projects_list > div').height();
var recent_proj_height = 67; var recent_proj_height = 67;
//jq('#min_projects_list, #min_expt_list').height(recent_proj_height * 5).css({'min-width':349,'overflow-y':'scroll'}); //jq('#min_projects_list, #min_expt_list').height(recent_proj_height * 5).css({'min-width':349,'overflow-y':'scroll'});
} };
// initialize the advanced search method toggler // initialize the advanced search method toggler
XNAT.app.searchMethodToggler = function(parent$){ XNAT.app.searchMethodToggler = function(parent$){
...@@ -587,9 +587,9 @@ ${bodyTop} ...@@ -587,9 +587,9 @@ ${bodyTop}
parent$ = $$(parent$ || 'body'); parent$ = $$(parent$ || 'body');
var INPUTS = 'input, select, textarea, :input', var INPUTS = 'input, select, textarea, :input',
SEARCH_METHOD_CKBOXES = 'input.search-method', SEARCH_METHOD_CKBOXES = 'input.search-method',
searchGroups$ = parent$.find('div.search-group'), searchGroups$ = parent$.find('div.search-group'),
searchMethodInputs$ = parent$.find(SEARCH_METHOD_CKBOXES); searchMethodInputs$ = parent$.find(SEARCH_METHOD_CKBOXES);
// disable 'by-id' search groups by default // disable 'by-id' search groups by default
searchGroups$.filter('.by-id').addClass('disabled').find(INPUTS).not(SEARCH_METHOD_CKBOXES).changeVal('') searchGroups$.filter('.by-id').addClass('disabled').find(INPUTS).not(SEARCH_METHOD_CKBOXES).changeVal('')
......
...@@ -53,10 +53,20 @@ var XNAT = getObject(XNAT); ...@@ -53,10 +53,20 @@ var XNAT = getObject(XNAT);
forOwn(obj, function(item, prop){ forOwn(obj, function(item, prop){
var kind, methodName, method, spawnedElement, $spawnedElement; var kind, element, method, spawnedElement, $spawnedElement;
// save the config properties in a new object // 'prop' can be a new or existing DOM element
prop = cloneObject(prop); if (prop instanceof Element) {
element = prop;
prop = {
kind: 'element',
element: element
};
}
else {
// save the config properties in a new object
prop = cloneObject(prop);
}
prop.element = prop.element || prop.config || {}; prop.element = prop.element || prop.config || {};
...@@ -65,12 +75,12 @@ var XNAT = getObject(XNAT); ...@@ -65,12 +75,12 @@ var XNAT = getObject(XNAT);
// lastly use the object's own name // lastly use the object's own name
prop.name = prop.name || item; prop.name = prop.name || item;
prop.id = prop.id || prop.element.id || toDashed(prop.name); //prop.id = prop.id || prop.element.id || toDashed(prop.name);
// accept 'kind' or 'type' property name // accept 'kind' or 'type' property name
// but 'kind' will take priority // but 'kind' will take priority
// with a fallback to a generic div // with a fallback to a generic div
kind = prop.kind || prop.type || 'div.spawned'; kind = prop.kind || prop.type || null;
// make 'href' 'src' and 'action' properties // make 'href' 'src' and 'action' properties
// start at the site root if starting with '/' // start at the site root if starting with '/'
...@@ -93,8 +103,14 @@ var XNAT = getObject(XNAT); ...@@ -93,8 +103,14 @@ var XNAT = getObject(XNAT);
prop.content = prop.content || prop.children || ''; prop.content = prop.content || prop.children || '';
try { try {
spawnedElement = // if setting up Spawner elements in JS, allow a
spawn(prop.tag || prop.element.tag || 'div', prop.element, prop.content); // DOM element to be passed in the 'element' property
if (prop.element instanceof Element) {
spawnedElement = prop.element;
}
else {
spawnedElement = spawn(prop.tag || prop.element.tag || 'span', prop.element, prop.content);
}
// convert relative URIs for href, src, and action attributes // convert relative URIs for href, src, and action attributes
if (spawnedElement.href) { if (spawnedElement.href) {
...@@ -118,6 +134,9 @@ var XNAT = getObject(XNAT); ...@@ -118,6 +134,9 @@ var XNAT = getObject(XNAT);
spawner.notSpawned.push(prop); spawner.notSpawned.push(prop);
} }
} }
else if (/^(text|html)$/i.test(kind)) {
$frag.append(prop.content||prop.html||prop.text)
}
else { else {
// check for a matching XNAT.ui method to call: // check for a matching XNAT.ui method to call:
...@@ -135,6 +154,9 @@ var XNAT = getObject(XNAT); ...@@ -135,6 +154,9 @@ var XNAT = getObject(XNAT);
// XNAT.ui.kind() // XNAT.ui.kind()
lookupObjectValue(NAMESPACE + '.' + kind) || lookupObjectValue(NAMESPACE + '.' + kind) ||
// XNAT.element.kind()
lookupObjectValue(XNAT, 'element.' + kind) ||
// kind.init() // kind.init()
lookupObjectValue(kind + '.init') || lookupObjectValue(kind + '.init') ||
......
...@@ -512,11 +512,12 @@ var XNAT = getObject(XNAT || {}); ...@@ -512,11 +512,12 @@ var XNAT = getObject(XNAT || {});
$$(form).serializeArray().forEach(function(item) { $$(form).serializeArray().forEach(function(item) {
if (!item.name) return; if (!item.name) return;
var name = item.name.replace(/^:/,''); var name = item.name.replace(/^:/,'');
var val = firstDefined(item.value+'', '');
if (typeof json[name] == 'undefined') { if (typeof json[name] == 'undefined') {
json[name] = item.value || ''; json[name] = val;
} }
else { else {
json[name] = [].concat(json[name], item.value||[]) ; json[name] = [].concat(json[name], val||[]) ;
} }
}); });
return json; return json;
...@@ -909,7 +910,7 @@ var XNAT = getObject(XNAT || {}); ...@@ -909,7 +910,7 @@ var XNAT = getObject(XNAT || {});
className: opts.className || opts.classes || '', className: opts.className || opts.classes || '',
name: opts.name, name: opts.name,
id: opts.id || toDashed(opts.name), id: opts.id || toDashed(opts.name),
value: opts.value || '' value: firstDefined(opts.value+'', '')
}, opts.element); }, opts.element);
addClassName(opts.element, 'hidden'); addClassName(opts.element, 'hidden');
if (opts.validation || opts.validate) { if (opts.validation || opts.validate) {
...@@ -975,12 +976,17 @@ var XNAT = getObject(XNAT || {}); ...@@ -975,12 +976,17 @@ var XNAT = getObject(XNAT || {});
if (opts.id) opts.element.id = opts.id; if (opts.id) opts.element.id = opts.id;
if (opts.name) opts.element.name = opts.name; if (opts.name) opts.element.name = opts.name;
opts.element.html = var val1 = opts.element.value;
opts.element.html || var val2 = opts.value;
opts.element.value ||
opts.value || opts.element.value = firstDefined(val1, val2, '');
opts.text ||
opts.html || ''; opts.element.html = firstDefined(
opts.element.html+'',
opts.element.value+'',
opts.text+'',
opts.html+'',
'');
opts.element.html = lookupValue(opts.element.html); opts.element.html = lookupValue(opts.element.html);
opts.element.title = 'Double-click to open in code editor.'; opts.element.title = 'Double-click to open in code editor.';
...@@ -1033,7 +1039,7 @@ var XNAT = getObject(XNAT || {}); ...@@ -1033,7 +1039,7 @@ var XNAT = getObject(XNAT || {});
name: opts.name, name: opts.name,
className: opts.className||'', className: opts.className||'',
title: opts.title||opts.name||opts.id||'', title: opts.title||opts.name||opts.id||'',
value: opts.value||'' value: firstDefined(opts.value+'', '')
}, opts.element); }, opts.element);
if (multi) { if (multi) {
......
...@@ -456,6 +456,13 @@ var XNAT = getObject(XNAT||{}), ...@@ -456,6 +456,13 @@ var XNAT = getObject(XNAT||{}),
var $this = $(this); var $this = $(this);
var val = lookupObjectValue(dataObj, this.name||this.title); var val = lookupObjectValue(dataObj, this.name||this.title);
// don't set values of inputs with EXISTING
// values that start with "@?"
// -- those get parsed on submission
if (!val && this.value && /^(@\?)/.test(this.value)) {
return;
}
if (Array.isArray(val)) { if (Array.isArray(val)) {
val = val.join(', '); val = val.join(', ');
$this.addClass('array-list') $this.addClass('array-list')
...@@ -536,7 +543,16 @@ var XNAT = getObject(XNAT||{}), ...@@ -536,7 +543,16 @@ var XNAT = getObject(XNAT||{}),
// don't pass 'callback' property into the AJAX request // don't pass 'callback' property into the AJAX request
delete opts.callback; delete opts.callback;
var inputs = $form.find(':input').not('button, [type="submit"]').toArray(); var $inputs = $form.find(':input').not('button, [type="submit"]');
// inputs with a value that starts with
// @? will get values from another source
$inputs.filter('[value^="@?"]').each(function(){
var source = this.value.replace(/^@\?[:=\s]*/, '');
this.value = eval(source);
});
var inputs = $inputs.toArray();
if (/POST|PUT/i.test(opts.method)) { if (/POST|PUT/i.test(opts.method)) {
if ($form.hasClass('json') || /json/i.test(opts.contentType||'')){ if ($form.hasClass('json') || /json/i.test(opts.contentType||'')){
...@@ -545,6 +561,9 @@ var XNAT = getObject(XNAT||{}), ...@@ -545,6 +561,9 @@ var XNAT = getObject(XNAT||{}),
opts.processData = false; opts.processData = false;
opts.contentType = 'application/json'; opts.contentType = 'application/json';
} }
else {
opts.data = $form.find(':input').not('.ignore').serialize();
}
opts.success = function(data){ opts.success = function(data){
callback.apply($form, arguments); callback.apply($form, arguments);
// repopulate 'real' data after success // repopulate 'real' data after success
......
...@@ -23,11 +23,16 @@ ...@@ -23,11 +23,16 @@
<pg:restricted msg="${message}"> <pg:restricted msg="${message}">
<c:import url="/xapi/siteConfig" var="siteConfig"/> <c:import url="/xapi/siteConfig" var="siteConfig"/>
<c:import url="/xapi/notifications" var="notifications"/>
<script> <script>
var XNAT = getObject(XNAT);
XNAT.data = extend({}, XNAT.data, { XNAT.data = extend({}, XNAT.data, {
siteConfig: ${siteConfig} siteConfig: ${siteConfig},
notifications: ${notifications}
}); });
XNAT.data['/xapi/siteConfig'] = XNAT.data.siteConfig;
XNAT.data['/xapi/notifications'] = XNAT.data.notifications;
// get rid of the 'targetSource' property // get rid of the 'targetSource' property
delete XNAT.data.siteConfig.targetSource; delete XNAT.data.siteConfig.targetSource;
</script> </script>
...@@ -57,9 +62,9 @@ ...@@ -57,9 +62,9 @@
<script> <script>
// XNAT.app.setupComplete = function(){ //XNAT.app.setupComplete = function(){
// XNAT.xhr.form('#site-setup', {}); // XNAT.xhr.form('#site-setup', {});
// }; //};
XNAT.xhr.get({ XNAT.xhr.get({
url: XNAT.url.rootUrl('/setup/site-setup.yaml'), url: XNAT.url.rootUrl('/setup/site-setup.yaml'),
...@@ -68,8 +73,12 @@ ...@@ -68,8 +73,12 @@
if (typeof data === 'string') { if (typeof data === 'string') {
data = YAML.parse(data); data = YAML.parse(data);
} }
var setupPanels = XNAT.spawner.spawn(data);
setupPanels.render('#site-setup-panels'); console.log(data);
XNAT.spawner
.spawn(data)
.render('#site-setup-panels');
} }
}); });
......
...@@ -25,7 +25,6 @@ siteSetup: ...@@ -25,7 +25,6 @@ siteSetup:
method: POST method: POST
url: /xapi/siteConfig url: /xapi/siteConfig
contentType: json contentType: json
load: XNAT.data.siteConfig
contents: contents:
siteId: siteId:
...@@ -38,7 +37,7 @@ siteSetup: ...@@ -38,7 +37,7 @@ siteSetup:
The id used to refer to this site (also used to generate ids). The Site ID must start The id used to refer to this site (also used to generate ids). The Site ID must start
with a letter and contain only letters, numbers and underscores. It should be a short, with a letter and contain only letters, numbers and underscores. It should be a short,
one-word name or acronym which describes your site. one-word name or acronym which describes your site.
validation: required id validation: required id-strict
siteUrl: siteUrl:
kind: panel.input.text kind: panel.input.text
...@@ -63,30 +62,44 @@ siteSetup: ...@@ -63,30 +62,44 @@ siteSetup:
description: Email address for site administrator. description: Email address for site administrator.
validation: required email validation: required email
# this is buggy - disabling for now # this seems to work now...
# notificationRecipients: # copy values from admin email to recipient list
# type: panel.form # =========================
# classes: hidden # EMAIL RECIPIENTS
# header: false notificationRecipients:
# footer: false type: panel.form
# method: POST classes: hidden
# url: /xapi/notifications header: false
# contentType: json footer: false
# contents: method: POST
# adminEmail: url: /xapi/notifications
# tag: input.disabled | disabled, type=hidden, data-value-from=#site-admin-email, name=adminEmail contentType: json
# value: !? $('#site-admin-email').val() contents:
# # copy adminEmail value to these properties: vars:
# help: tag: script
# tag: input| type=hidden, data-value-from=#site-admin-email, name=notifications.helpContactInfo content: >
# errorMessages: window.siteAdminEmailInput = $('#site-admin-email')[0]
# tag: input| type=hidden, data-value-from=#site-admin-email, name=notifications.emailRecipientErrorMessages # copy adminEmail value to these properties:
# issueReports: helpContactInfo:
# tag: input| type=hidden, data-value-from=#site-admin-email, name=notifications.emailRecipientIssueReports kind: input.hidden
# newUserAlert: name: helpContactInfo
# tag: input| type=hidden, data-value-from=#site-admin-email, name=notifications.emailRecipientNewUserAlert value: @?=window.siteAdminEmailInput.value
# update: errorMessages:
# tag: input| type=hidden, data-value-from=#site-admin-email, name=notifications.emailRecipientUpdate kind: input.hidden
name: emailRecipientErrorMessages
value: @?=window.siteAdminEmailInput.value
issueReports:
kind: input.hidden
name: emailRecipientIssueReports
value: @?=window.siteAdminEmailInput.value
newUserAlert:
kind: input.hidden
name: emailRecipientNewUserAlert
value: @?=window.siteAdminEmailInput.value
update:
kind: input.hidden
name: emailRecipientUpdate
value: @?=window.siteAdminEmailInput.value
# ========================= # =========================
# DATA STORAGE # DATA STORAGE
...@@ -194,12 +207,12 @@ siteSetup: ...@@ -194,12 +207,12 @@ siteSetup:
text: Mail Server Settings text: Mail Server Settings
smtpAuth: smtpAuth:
kind: panel.input.checkbox kind: panel.input.switchbox
name: mail.smtp.auth name: mail.smtp.auth
label: SMTP Auth? label: SMTP Auth?
smtpStartTls: smtpStartTls:
kind: panel.input.checkbox kind: panel.input.switchbox
name: mail.smtp.starttls.enable name: mail.smtp.starttls.enable
label: Start TLS? label: Start TLS?
...@@ -220,15 +233,15 @@ siteSetup: ...@@ -220,15 +233,15 @@ siteSetup:
contentType: json contentType: json
contents: contents:
requireLogin: requireLogin:
kind: panel.input.checkbox kind: panel.input.switchbox
id: requireLogin id: requireLogin
name: requireLogin name: requireLogin
label: Require User Login label: Require User Login
description: "If checked, then only registered users will be able to access your site. If false, anyone visiting your site will automatically be logged in as 'guest' with access to public data." description: "If checked, then only registered users will be able to access your site. If false, anyone visiting your site will automatically be logged in as 'guest' with access to public data."
autoEnableUserRegistration: autoEnableUserRegistration:
kind: panel.input.checkbox kind: panel.input.switchbox
id: autoEnableUserRegistration id: autoEnableUserRegistration
name: userRegistration name: userRegistration
label: "Auto-enable User Registration?" label: "Auto-enable User Registration?"
...@@ -237,8 +250,8 @@ siteSetup: ...@@ -237,8 +250,8 @@ siteSetup:
projects immediately. If false, the site administrator will be required to manually enable user accounts. Either way the administrator projects immediately. If false, the site administrator will be required to manually enable user accounts. Either way the administrator
receives an email notification when a user registers. receives an email notification when a user registers.
enableCsrfToken: enableCsrfToken:
kind: panel.input.checkbox kind: panel.input.switchbox
id: enableCsrfToken id: enableCsrfToken
name: enableCsrfToken name: enableCsrfToken
label: Require CSRF Token? label: Require CSRF Token?
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment