From 7a14e762be17bf012cae922f493a88e1223eab3a Mon Sep 17 00:00:00 2001 From: "Mark M. Florida" <markflorida@wustl.edu> Date: Fri, 9 Sep 2016 01:06:23 -0500 Subject: [PATCH] XNAT-4505, XNAT-4500, XNAT-3869, XNAT-1365, XNAT-277 (partial): Major refactoring of Investigators UI on project add/edit pages. --- src/main/webapp/scripts/globals.js | 9 +- .../webapp/scripts/xnat/app/investigators.js | 94 ++- src/main/webapp/scripts/xnat/validate.js | 1 + .../XDATScreen_add_xnat_projectData.vm | 140 ++-- .../XDATScreen_edit_xnat_projectData.vm | 146 ++-- .../screens/xnat_projectData/edit/details.vm | 631 +++++++----------- 6 files changed, 501 insertions(+), 520 deletions(-) diff --git a/src/main/webapp/scripts/globals.js b/src/main/webapp/scripts/globals.js index 4ac56bc8..e909ea26 100644 --- a/src/main/webapp/scripts/globals.js +++ b/src/main/webapp/scripts/globals.js @@ -65,13 +65,14 @@ function getUrlHashValue(start, end){ } function firstDefined() { - var undefined, i = -1; + var undef, i = -1, val; while (++i < arguments.length) { - if (arguments[i] !== undefined) { - return arguments[i]; + val = arguments[i]; + if (val !== undef && val !== 'undefined') { + return val; } } - return undefined; + return undef; } function isDefined( x ){ return typeof x != 'undefined' diff --git a/src/main/webapp/scripts/xnat/app/investigators.js b/src/main/webapp/scripts/xnat/app/investigators.js index 1a3f74a7..dc237a1e 100644 --- a/src/main/webapp/scripts/xnat/app/investigators.js +++ b/src/main/webapp/scripts/xnat/app/investigators.js @@ -112,12 +112,14 @@ var XNAT = getObject(XNAT); Investigators.fn.setMenu = function(menu){ this.menu$ = $$(menu); this.menu = this.menu$[0]; + this.isMulti = this.menu.multiple; return this; }; // sets the selected menu item and updates the .chosen() stuff Investigators.fn.setSelected = function(selected){ var self = this; + selected = selected || self.selected; [].concat(selected).forEach(function(id){ self.menu$.filter('[value="' + id + '"]').each(function(){ this.selected = true; @@ -128,30 +130,55 @@ var XNAT = getObject(XNAT); return this; }; + // return array of ids of selected investigators + Investigators.fn.getSelected = function(){ + var self = this; + this.selected = []; + this.menu$.find(':selected').each(function(){ + self.selected.push(this.value) + }); + return this.selected; + }; + // renders the <option> elements Investigators.fn.createMenuItems = function(selected){ var self = this; + // retain current selection, if nothing specified + selected = selected || this.getSelected(); selected = [].concat(selected).map(function(item){ - return item+''; + if (isDefined(item)) { + return item+''; + } }); + console.log('selected: ' + selected.join('; ')); this.getAll(); this.xhr.done(function(data){ - self.selected = []; + var _selected = [], + options = []; + + if (!self.isMulti) { + if (!selected.length) { + options.push(spawn('option|disabled|selected', 'Select...')); + } + options.push(spawn('option|value=NULL', 'None')); + } - var options = data.map(function(item){ + data.forEach(function(item){ var id = item.xnatInvestigatordataId+''; var menuOption = spawn('option', { value: id, html: item.lastname + ', ' + item.firstname }); if (selected.indexOf(id) > -1) { - self.selected.push(id); + _selected.push(id); menuOption.selected = true; } - return menuOption; + options.push(menuOption); }); + self.selected = _selected; + // empty the options, then add the updated options self.menu$.empty().append(options); @@ -183,6 +210,8 @@ var XNAT = getObject(XNAT); Investigators.fn.updateMenu = function(selected){ var self = this; + // save currently selected items, if 'selected' is undefined + selected = selected || this.getSelected(); this.createMenuItems(selected); this.xhr.done(function(){ //self.menu$.val(selected).change(); @@ -193,10 +222,12 @@ var XNAT = getObject(XNAT); // putting the .dialog() method on the prototype // ties it to the associated menu - Investigators.fn.dialog = function(id, menuInstance){ + Investigators.fn.dialog = function(id, menus){ // the menu that gets updated on save - menuInstance = menuInstance || this; + menus = menus || null; + + var self = this; function createInput(label, name, validate){ return { @@ -207,7 +238,9 @@ var XNAT = getObject(XNAT); } } - function createPanel(){ + var isPrimary = self.menu.value == investigators.primary; + + function investigatorForm(){ return { investigatorForm: { kind: 'panel.form', @@ -224,7 +257,16 @@ var XNAT = getObject(XNAT); institution: createInput('Institution', 'institution'), department: createInput('Department', 'department'), email: createInput('Email', 'email', 'email'), - phone: createInput('Phone', 'phone', 'numeric-dash') + phone: createInput('Phone', 'phone', 'numeric-dash'), + primary: { + kind: 'panel.element', + label: false, + contents: + '<label>' + + '<input type="checkbox" class="set-primary">' + + ' Set as Primary' + + '</label>' + } // ID: createInput('ID', 'ID'), // invId: { // kind: 'panel.input.hidden', @@ -236,7 +278,7 @@ var XNAT = getObject(XNAT); } } - var invForm = XNAT.spawner.spawn(createPanel()); + var invForm = XNAT.spawner.spawn(investigatorForm()); var dialog = xmodal.open({ @@ -245,10 +287,15 @@ var XNAT = getObject(XNAT); beforeShow: function(obj){ invForm.render(obj.$modal.find('div.add-edit-investigator')); }, + afterShow: function(obj){ + obj.$modal.find('input.set-primary').prop('checked', isPrimary); + }, okLabel: 'Submit', okClose: false, okAction: function(obj){ - $(obj.$modal.find('form[name="editInvestigator"]')).submitJSON({ + var _form = obj.$modal.find('form[name="editInvestigator"]'), + setPrimary = _form.find('input.set-primary')[0].checked; + $(_form).submitJSON({ delim: '!', validate: function(){ var $form = $(this); @@ -269,11 +316,16 @@ var XNAT = getObject(XNAT); return errors === 0; }, success: function(data){ - ui.banner.top(2000, 'New investigator created.', 'success'); - // update a menu, if specified - if (menuInstance instanceof Investigators) { - menuInstance.updateMenu(data.xnatInvestigatordataId); + var selected = data.xnatInvestigatordataId; + ui.banner.top(2000, 'Investigator data saved.', 'success'); + // update other menus, if specified + if (menus) { + [].concat(menus).forEach(function(menu){ + menu.updateMenu(setPrimary ? selected : ''); + }) } + // update the menu associated with the dialog + self.updateMenu([].concat(self.getSelected(), (!setPrimary ? selected : []))); dialog.close(); } }); @@ -281,10 +333,11 @@ var XNAT = getObject(XNAT); }, width: 500, height: 500, - padding: '0px' + padding: '0px', + scroll: false }); - return dialog + return this; }; @@ -312,6 +365,13 @@ var XNAT = getObject(XNAT); // }; + investigators.updateMenus = function(selected){ + if (investigators.menus && !investigators.menus.length) { + investigators.menus.forEach(function(menu){ + menu.updateMenu(selected); + }) + } + }; investigators.delete = function(id, opts){ if (!id) return false; diff --git a/src/main/webapp/scripts/xnat/validate.js b/src/main/webapp/scripts/xnat/validate.js index 999b5bae..7e4030c8 100644 --- a/src/main/webapp/scripts/xnat/validate.js +++ b/src/main/webapp/scripts/xnat/validate.js @@ -91,6 +91,7 @@ var XNAT = getObject(XNAT); alphaNum: /^[a-z0-9]+$/i, // ONLY letters and numbers alphaNumSafe: /^[a-z0-9_]+$/i, // ONLY letters, numbers, and underscore alphaNumDash: /^[a-z0-9_\-]+$/i, // ONLY letters, numbers, underscore, and dash + alphaNumDashSpace: /^[a-z0-9_\- ]+$/i, // ONLY letters, numbers, underscore, dash, and space idSafe: /^[a-z][a-z0-9_\-]+$/i, // safe to use as an ID - alphasafe and must start with a letter idStrict: /^[a-z][a-z0-9_]+$/i, // 'idSafe' without hyphens ip: /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/i, diff --git a/src/main/webapp/xnat-templates/screens/XDATScreen_add_xnat_projectData.vm b/src/main/webapp/xnat-templates/screens/XDATScreen_add_xnat_projectData.vm index dea74428..5335faa6 100644 --- a/src/main/webapp/xnat-templates/screens/XDATScreen_add_xnat_projectData.vm +++ b/src/main/webapp/xnat-templates/screens/XDATScreen_add_xnat_projectData.vm @@ -1,75 +1,85 @@ -<script type="text/javascript" src="$content.getURI("scripts/project/accessibility.js")"></script> - $page.setTitle("XDAT") $page.setLinkColor($ui.alink) $page.setVlinkColor($ui.vlink) #set($months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]) #set($days = [ 1..31 ]) #set($years = [ $!turbineUtils.getYear()..1900]) +#set($PROJECT_DISPLAY_NAME = $displayManager.getSingularDisplayNameForProject()) +#set($PROJECT_DISPLAY_LOWER = $PROJECT_DISPLAY_NAME.toLowerCase()) #if ($data.message) <div class="alert">$data.message</div> #end - -<form id="new-project-form" name="form1" method="post" action="$link.setAction("AddProject")" ONSUBMIT="return validateProjectForm(this);"> - +<form class="optOutOfXnatDefaultFormValidation" id="new-project-form" name="form1" method="post" action="$link.setAction("AddProject")" onsubmit="return processProjectForm()"> #if($vr) - <div class="error">Invalid parameters:<BR>$vr.toHTML()</div> - <HR> + <div class="error">Invalid parameters:<br>$vr.toHTML()</div> + <hr> #end - <DIV class="edit_title">$page_title</DIV> + <div class="edit_title">$page_title</div> - <DIV class="container"> - <DIV class="withColor containerTitle" style="font-weight:700;"> Step 1: Enter $displayManager.getSingularDisplayNameForProject().toLowerCase() details</DIV> - <DIV class="containerBody"> - <DIV class="containerItem"> - #set( $parentTemplate = 'add' ) + <div class="container"> + <div class="withColor containerTitle">Step 1: Enter ${PROJECT_DISPLAY_LOWER} details</div> + <div class="containerBody"> + <div class="containerItem"> + #set($parentTemplate='add') #parse("/screens/xnat_projectData/edit/details.vm") - </DIV> - </DIV> - </DIV> + </div> + </div> + </div> <br> - <div class="container"> - <div class="withColor containerTitle"> Step 2: Define $displayManager.getSingularDisplayNameForProject() Accessibility</div> - <div class="containerBody"> + <style type="text/css"> + #project-accessibility .panel .panel-subhead { margin-top: 0; } + #access-selector { margin: 15px; padding: 0; background: #f0f0f0; border: 1px solid #ccc; } + #access-buttons, + #access-description { float: left; padding: 15px; } + #access-buttons { max-width: 24%; border-right: 1px solid #ccc; } + #access-buttons .access-label { display: block; margin-bottom: 5px; white-space: nowrap; } + #access-description { max-width: 74%; } + </style> + + ## this div will eventually be created by Spawner + <div id="project-accessibility" class="container"> + <div class="withColor containerTitle">Step 2: Define ${PROJECT_DISPLAY_NAME} Accessibility</div> + <div> <div class="containerItem"> - Select the accessibility of your $displayManager.getSingularDisplayNameForProject().toLowerCase(). + Select the accessibility of your ${PROJECT_DISPLAY_LOWER}. </div> <hr class="h20"> - <div class="containerItem"> - <table width="100%"> - <tr> - <td class="highlighted" valign="top"> - <table cellpadding="0" cellspacing="0"> - <tr> - <td valign="top" style="padding:10px 20px 10px 10px;border-right:1px solid #ccc;"> - <label id="private_access_div" title="Only you and study members will be able to access study data." style="display:block;white-space:nowrap;padding-bottom:5px;" onclick="checkAccessibilityRadioButton(this, 'private_access');"> - <input type="radio" id="private_access" name="accessibility" value="private" checked/> Private - </label> - - <label id="protected_access_div" title="All users will be able to see your study title and description, but only collaborators you approve will be able to analyze and download data." style="display:block;white-space:nowrap;padding-bottom:5px;" onclick="checkAccessibilityRadioButton(this, 'protected_access');"> - <input type="radio" id="protected_access" name="accessibility" value="protected"/> Protected - </label> - - <label id="public_access_div" title="All users will be able to access study data for analysis and download." style="display:block;white-space:nowrap;" onclick="checkAccessibilityRadioButton(this, 'public_access');"> - <input type="radio" id="public_access" name="accessibility" value="public"/> Public - </label> - </td> - <td valign="top" style="padding:10px 160px 10px 20px;"> - <div id="balloon" style="border:none;">Only you and study members will be able to access study data.</div> - </td> - </tr> - </table> - </td> - </tr> - </table> - <br/> + <div id="access-selector" class="containerItem"> + + <div id="access-buttons" class="radio-toggle"> + <label class="access-label" title="Only you and study members will be able to access study data."> + <input type="radio" id="private_access" name="accessibility" value="private"/> Private + </label> + <label class="access-label" title="All users will be able to see your study title and description, but only collaborators you approve will be able to analyze and download data."> + <input type="radio" id="protected_access" name="accessibility" value="protected"/> Protected + </label> + <label class="access-label" style="margin-bottom:0" title="All users will be able to access study data for analysis and download."> + <input type="radio" id="public_access" name="accessibility" value="public"/> Public + </label> + </div> + + <div id="access-description"></div> + + <br class="clear"> + </div> </div> </div> + <script> + + $('#project-accessibility').on('click', 'input[name=accessibility]', function(){ + $('#access-description').html(this.parentElement.title) + }); + + // set to 'Private' by default when adding a project + $('#private_access').click(); + + </script> + #xdatEditProps($item $edit_screen) <div class="submit-right"> @@ -79,25 +89,37 @@ $page.setVlinkColor($ui.vlink) </form> -<SCRIPT type="text/javascript"> +<script> - function validateProjectForm(_form) { + function processProjectForm() { - var __form = jq(_form); + var __form = $('#new-project-form'); __form.find('.invalid').removeClass('invalid'); - var Project = XNAT.app.displayNames.singular.project; + var i = 1; + + // add hidden inputs for 'other' investigators + XNAT.app.investigators.otherMenu.getSelected().forEach(function(inv){ + if (inv != XNAT.app.investigators.primary) { + __form.spawn('input|type=hidden', { + name: 'xnat:projectData/investigators/investigator[' + (i++) + ']/xnat_investigatordata_id', + value: inv + }); + } + }); + + var PROJECT = XNAT.app.displayNames.singular.project.toLowerCase(); var __projID = jq(document.getElementById("xnat:projectData/ID")); var __projTitle = jq(document.getElementById("xnat:projectData/name")); var __projRunningTitle = jq(document.getElementById("xnat:projectData/secondary_ID")); - var projIDVal = jQuery.trim(__projID.val()); - var projTitleVal = jQuery.trim(__projTitle.val()); - var projRunningTitleVal = jQuery.trim(__projRunningTitle.val()); + var projIDVal = (__projID.val()+'').trim(); + var projTitleVal = (__projTitle.val()+'').trim(); + var projRunningTitleVal = (__projRunningTitle.val()+'').trim(); var invalid_count = 0; if (projIDVal == '') { - xmodal.message('Validation', 'Please enter a ' + Project.toLowerCase() + ' abbreviation (ID).'); + xmodal.message('Validation', 'Please enter a ' + PROJECT + ' abbreviation (ID).'); __projID.addClass('invalid'); invalid_count++; } @@ -112,12 +134,12 @@ $page.setVlinkColor($ui.vlink) invalid_count++; } if (projTitleVal == '') { - xmodal.message('Validation', 'Please enter a ' + Project.toLowerCase() + ' title.'); + xmodal.message('Validation', 'Please enter a ' + PROJECT + ' title.'); __projTitle.addClass('invalid'); invalid_count++; } if (projTitleVal.length > 199) { - xmodal.message('Validation', 'Please enter a ' + Project.toLowerCase() + ' title of 199 characters or less.'); + xmodal.message('Validation', 'Please enter a ' + PROJECT + ' title of 199 characters or less.'); __projTitle.addClass('invalid'); invalid_count++; } @@ -133,4 +155,4 @@ $page.setVlinkColor($ui.vlink) } } -</SCRIPT> +</script> diff --git a/src/main/webapp/xnat-templates/screens/XDATScreen_edit_xnat_projectData.vm b/src/main/webapp/xnat-templates/screens/XDATScreen_edit_xnat_projectData.vm index 760bd8bb..ff023399 100644 --- a/src/main/webapp/xnat-templates/screens/XDATScreen_edit_xnat_projectData.vm +++ b/src/main/webapp/xnat-templates/screens/XDATScreen_edit_xnat_projectData.vm @@ -1,83 +1,98 @@ -<script type="text/javascript" src="$content.getURI("scripts/project/accessibility.js")"></script> - $page.setTitle("XDAT") $page.setLinkColor($ui.alink) $page.setVlinkColor($ui.vlink) #set($months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]) #set($days = [ 1..31 ]) #set($years = [ $!turbineUtils.getYear()..1900]) +#set($PROJECT_DISPLAY_NAME = $displayManager.getSingularDisplayNameForProject()) +#set($PROJECT_DISPLAY_LOWER = $PROJECT_DISPLAY_NAME.toLowerCase()) #if ($data.message) <div class="alert">$data.message</div> #end -<form id="edit-project-form" name="form1" method="post" action="$link.setAction("ModifyProject")" onsubmit="return validateProjectForm(this)"> +<form class="optOutOfXnatDefaultFormValidation" id="edit-project-form" name="form1" method="post" action="$link.setAction("ModifyProject")" onsubmit="return processProjectForm()"> #if($vr) <div class="error">Invalid parameters:<br>$vr.toHTML()</div> <hr> #end + <div class="edit_title">$page_title</div> <div class="container"> - <div class="withColor containerTitle"> Step 1: Enter $displayManager.getSingularDisplayNameForProject().toLowerCase() details</div> + <div class="withColor containerTitle">Step 1: Enter ${PROJECT_DISPLAY_LOWER} details</div> <div class="containerBody"> <div class="containerItem"> - Define the details of this $displayManager.getSingularDisplayNameForProject().toLowerCase(). The '$displayManager.getSingularDisplayNameForProject() ID' should be a - single word or acronym which will identify your $displayManager.getSingularDisplayNameForProject().toLowerCase(). It will be + Define the details of this ${PROJECT_DISPLAY_LOWER}. The '${PROJECT_DISPLAY_NAME} ID' should be a + single word or acronym which will identify your ${PROJECT_DISPLAY_LOWER}. It will be used on the file system to name directories and files, so it shouldn't contain any wild characters or spaces. The 'Running Title' - will be used throughout the website to identify your $displayManager.getSingularDisplayNameForProject().toLowerCase().<br> + will be used throughout the website to identify your ${PROJECT_DISPLAY_LOWER}.<br> </div> <hr> <div class="containerItem"> #set($parentTemplate='edit') - #parse("/screens/xnat_projectData/edit/details.vm") + #parse("/screens/xnat_projectData/edit/details.vm") </div> </div> </div> <br> - #set($guest=$om.getPublicAccessibility()) - <div class="container"> - <div class="withColor containerTitle"> Step 2: Define $displayManager.getSingularDisplayNameForProject() Accessibility</div> - <div class="containerBody"> + <style type="text/css"> + #project-accessibility .panel .panel-subhead { margin-top: 0; } + #access-selector { margin: 15px; padding: 0; background: #f0f0f0; border: 1px solid #ccc; } + #access-buttons, + #access-description { float: left; padding: 15px; } + #access-buttons { max-width: 24%; border-right: 1px solid #ccc; } + #access-buttons .access-label { display: block; margin-bottom: 5px; white-space: nowrap; } + #access-description { max-width: 74%; } + </style> + + ## this div will eventually be created by Spawner + <div id="project-accessibility" class="container"> + <div class="withColor containerTitle">Step 2: Define ${PROJECT_DISPLAY_NAME} Accessibility</div> + <div> <div class="containerItem"> - Select the accessibility of your $displayManager.getSingularDisplayNameForProject().toLowerCase(). + Select the accessibility of your ${PROJECT_DISPLAY_LOWER}. </div> - <hr style="margin:4px 0;"> - <div class="containerItem"> - <table width="100%"> - <tr> - <td class="highlighted" valign="top"> - <table cellpadding="0" cellspacing="0"> - <tr> - <td valign="top" style="padding:10px 20px 10px 10px;border-right:1px solid #ccc;"> - <label id="private_access_div" title="Only you and study members will be able to access study data." style="display:block;white-space:nowrap;padding-bottom:5px;" onclick="checkAccessibilityRadioButton(this, 'private_access');"> - <input type="radio" id="private_access" name="accessibility" value="private" #if($guest=="private")checked#end/> Private - </label> - - <label id="protected_access_div" title="All users will be able to see your study title and description, but only collaborators you approve will be able to analyze and download data." style="display:block;white-space:nowrap;padding-bottom:5px;" onclick="checkAccessibilityRadioButton(this, 'protected_access');"> - <input type="radio" id="protected_access" name="accessibility" value="protected" #if($guest=="protected")checked#end/> Protected - </label> - - <label id="public_access_div" title="All users will be able to access study data for analysis and download." style="display:block;white-space:nowrap;" onclick="checkAccessibilityRadioButton(this, 'public_access');"> - <input type="radio" id="public_access" name="accessibility" value="public" #if($guest=="public")checked#end/> Public - </label> - </td> - <td valign="top" style="padding:10px 160px 10px 20px;"> - <div id="balloon" style="border:none;">Only you and study members will be able to access study data.</div> - </td> - </tr> - </table> - </td> - </tr> - </table> - <br/> + <hr class="h20"> + <div id="access-selector" class="containerItem"> + + <div id="access-buttons" class="radio-toggle"> + <label class="access-label" title="Only you and study members will be able to access study data."> + <input type="radio" id="private_access" name="accessibility" value="private"/> Private + </label> + <label class="access-label" title="All users will be able to see your study title and description, but only collaborators you approve will be able to analyze and download data."> + <input type="radio" id="protected_access" name="accessibility" value="protected"/> Protected + </label> + <label class="access-label" style="margin-bottom:0" title="All users will be able to access study data for analysis and download."> + <input type="radio" id="public_access" name="accessibility" value="public"/> Public + </label> + </div> + + <div id="access-description"></div> + + <br class="clear"> + </div> </div> </div> + #set ($guest=$om.getPublicAccessibility()) + + <script> + + $('#project-accessibility').on('click', 'input[name=accessibility]', function(){ + $('#access-description').html(this.parentElement.title) + }); + + // set to 'Private' by default when adding a project + $('#${guest}_access').click(); + + </script> + #xdatEditProps($item $edit_screen) + <table> - #auditBoxes("2" "" "" "Modified $displayManager.getSingularDisplayNameForProject().toLowerCase()") + #auditBoxes("2" "" "" "Modified ${PROJECT_DISPLAY_LOWER}") </table> <div class="submit-right"> @@ -89,26 +104,38 @@ $page.setVlinkColor($ui.vlink) <script> - function validateProjectForm(_form) { + function processProjectForm() { - var __form = jq(_form); + var __form = $('#edit-project-form'); __form.find('.invalid').removeClass('invalid'); - var Project = XNAT.app.displayNames.singular.project ; - //var __projID = jq(document.getElementById("xnat:projectData/ID")); + var i = 1; + + // add hidden inputs for 'other' investigators + XNAT.app.investigators.otherMenu.getSelected().forEach(function(inv){ + if (inv != XNAT.app.investigators.primary) { + __form.spawn('input|type=hidden', { + name: 'xnat:projectData/investigators/investigator[' + (i++) + ']/xnat_investigatordata_id', + value: inv + }); + } + }); + + var PROJECT = XNAT.app.displayNames.singular.project.toLowerCase(); + var __projID = jq(document.getElementById("xnat:projectData/ID")); var __projTitle = jq(document.getElementById("xnat:projectData/name")); var __projRunningTitle = jq(document.getElementById("xnat:projectData/secondary_ID")); - //var projIDVal = jQuery.trim(__projID.val())); - var projTitleVal = jQuery.trim(__projTitle.val()); - var projRunningTitleVal = jQuery.trim(__projRunningTitle.val()); + var projIDVal = (__projID.val()+'').trim(); + var projTitleVal = (__projTitle.val()+'').trim(); + var projRunningTitleVal = (__projRunningTitle.val()+'').trim(); - var invalid_count = 0 ; - //if (projIDVal == '') { - // xmodal.message('Validation', 'Please enter a ' + Project.toLowerCase() + ' abbreviation.'); - // __projID.addClass('invalid'); - // invalid_count++; - //} + var invalid_count = 0; + if (projIDVal == '') { + xmodal.message('Validation', 'Please enter a ' + PROJECT + ' abbreviation (ID).'); + __projID.addClass('invalid'); + invalid_count++; + } if (projRunningTitleVal == '') { xmodal.message('Validation', 'Please enter a running title.'); __projRunningTitle.addClass('invalid'); @@ -120,20 +147,21 @@ $page.setVlinkColor($ui.vlink) invalid_count++; } if (projTitleVal == '') { - xmodal.message('Validation', 'Please enter a ' + Project.toLowerCase() + ' title.'); + xmodal.message('Validation', 'Please enter a ' + PROJECT + ' title.'); __projTitle.addClass('invalid'); invalid_count++; } if (projTitleVal.length > 199) { - xmodal.message('Validation', 'Please enter a ' + Project.toLowerCase() + ' title of 199 characters or less.'); + xmodal.message('Validation', 'Please enter a ' + PROJECT + ' title of 199 characters or less.'); __projTitle.addClass('invalid'); invalid_count++; } if (invalid_count > 0) { __form.find('.invalid').first().focus(); - return false ; + return false; } else { + __projID.val(projIDVal); __projTitle.val(projTitleVal); __projRunningTitle.val(projRunningTitleVal); return true; diff --git a/src/main/webapp/xnat-templates/screens/xnat_projectData/edit/details.vm b/src/main/webapp/xnat-templates/screens/xnat_projectData/edit/details.vm index 82db2207..ca93b436 100644 --- a/src/main/webapp/xnat-templates/screens/xnat_projectData/edit/details.vm +++ b/src/main/webapp/xnat-templates/screens/xnat_projectData/edit/details.vm @@ -1,166 +1,189 @@ -<TABLE id="project_data_form"> - <TR> - <TH align="left">$displayManager.getSingularDisplayNameForProject() Title</TH> - <TD> - #if( $parentTemplate != 'add' ) - <input class="project_title" id="xnat:projectData/name" type="text" name="xnat:projectData/name" value="$!item.getStringProperty("xnat:projectData/name")" size="95" maxlength="199"/> - #else - <input class="requiredField project_title title" id="xnat:projectData/name" type="text" name="xnat:projectData/name" value="$!item.getStringProperty("xnat:projectData/name")" size="95" maxlength="199"/> - #end - </TD> - </TR> - #if( $parentTemplate == 'add' ) - <TR class="requirementStatement"> - <TD></TD> - <TD id="projectTitle_requirementStatement" class="requirementStatement"> +## YAML for spawning project details +<script id="project-data-form" type="text/yaml"> + + panels: + kind: panel.form + contents: + projectTitle: + kind: panel.input.text + name: "xnat:projectData/name" + label: Project Title + validate: required text + description: > + <span class="noteRequired">REQUIRED: </span> + <span class="formLabelRequiredStatement">Enter the full name of your project here. This will show up on + project listings.</span> + element: + size: 60 + runningTitle: + kind: panel.input.text + name: "xnat:projectData/secondary_ID" + label: Running Title + validate: required alphaNumDashSpace max-length=24 + description: > + <span class="noteRequired">REQUIRED: </span> + <span class="formLabelRequiredStatement">Create a simple abbreviation of your project name, using 24 + characters or less. Spaces are allowed. This will be commonly used in menus and UI elements.</span> + element: + size: 24 + projectID: + kind: panel.input.text + name: "xnat:projectData/ID" + label: Project ID + validate: required text id-strict max-length=24 + description: > + <span class="noteRequired">REQUIRED: </span> + <span class="formLabelRequiredStatement">Create a one word project identifier. This is used in the + database and <b>cannot be changed</b>.</span> + element: + size: 24 + + # more to come...? + +</script> + +<script> +// (function(){ +// +// var _yaml = $$('!#project-data-form').innerText; +// var parsed = YAML.parse(_yaml) +// +// console.log(parsed); +// +// XNAT.app.projectInfoPanels = parsed; +// +// XNAT.spawner +// .spawn(parsed) +// .render('#layout_content'); +// +// })(); +</script> + +<style> + #project_details th, + #project_details td { padding-bottom: 15px; } + #project_details th { padding-top: 8px; padding-right: 8px; text-align: right; vertical-align: top; white-space: nowrap; } + #project_details div.requirementStatement { padding: 5px 2px 0; } + #project_details.edit-project input.requiredField { border: 1px solid #c0c0c0; } + #project_details.edit-project div.requirementStatement { display: none; } + #project_details .read-only { font-weight: bold; background: #f0f0f0; border-color: #f0f0f0; } + #project_details #investigatorBox { margin-top: 2px; } +</style> + +#set ($PROJECT_DISPLAY_NAME = $displayManager.getSingularDisplayNameForProject()) +#set ($PROJECT_DISPLAY_LOWER = $PROJECT_DISPLAY_NAME.toLowerCase()) + +<table id="project_details"> + + <tr> + <th>${PROJECT_DISPLAY_NAME} Title</th> + <td> + <input class="requiredField project_title title" id="xnat:projectData/name" type="text" name="xnat:projectData/name" value="$!item.getStringProperty("xnat:projectData/name")" size="95" maxlength="199"> + <div class="requirementStatement"> <span class="noteRequired">REQUIRED: </span><span class="formLabelRequiredStatement">Enter the full name of your project here. This will show up on project listings.</span> - </TD> - </TR> - <TR> - <TD colspan="2" class="newProjectSpacer"></TD> - </TR> - #end - - <TR> - <TH align="left">Running Title</TH> - <TD> - #if( $parentTemplate != 'add' ) - <input class="abbreviation" id="xnat:projectData/secondary_ID" type="text" name="xnat:projectData/secondary_ID" value="$!item.getStringProperty("xnat:projectData/secondary_ID")" size="24" maxlength="24"/> - #else - <input class="requiredField abbreviation" id="xnat:projectData/secondary_ID" type="text" name="xnat:projectData/secondary_ID" value="$!item.getStringProperty("xnat:projectData/secondary_ID")" size="24" maxlength="24"/> - #end - </TD> - - </TR> - #if( $parentTemplate == 'add' ) - <TR class="requirementStatement"> - <TD></TD> - <TD id="runningTitle_requirementStatement" class="requirementStatement"> - <span class="noteRequired">REQUIRED: </span><span class="formLabelRequiredStatement">Create a simple abbreviation of your project name, using 24 characters or less. Spaces are allowed.<br/>This will be commonly used in menus and UI elements.</span> - </TD> - </TR> - <TR> - <TD colspan="2" class="newProjectSpacer"></TD> - </TR> - #end - - <TR> - <TH align="left" NOWRAP>$displayManager.getSingularDisplayNameForProject() ID</TH> - <TD> + </div> + </td> + </tr> + + <tr> + <th>Running Title</th> + <td> + <input class="requiredField abbreviation" id="xnat:projectData/secondary_ID" type="text" name="xnat:projectData/secondary_ID" value="$!item.getStringProperty("xnat:projectData/secondary_ID")" size="24" maxlength="24"> + <div class="requirementStatement"> + <span class="noteRequired">REQUIRED: </span><span class="formLabelRequiredStatement">Create a simple abbreviation of your project name, using 24 characters or less. Spaces are allowed.<br>This will be commonly used in menus and UI elements.</span> + </div> + </td> + </tr> + + <tr> + <th>${PROJECT_DISPLAY_NAME} ID</th> + <td> #if( $parentTemplate != 'add' ) - <input class="abbreviation" id="xnat:projectData/ID" type="hidden" name="xnat:projectData/ID" value="$item.getStringProperty("xnat:projectData/ID")"/> - $item.getProperty("xnat:projectData/ID") + <input readonly class="read-only" id="project-id" type="text" name="xnat:projectData/ID" size="14" value="$item.getStringProperty("xnat:projectData/ID")"> + ##<input class="abbreviation" id="xnat:projectData/ID" type="hidden" name="xnat:projectData/ID" value="$item.getStringProperty("xnat:projectData/ID")"> + ##<p class="project-id">$item.getProperty("xnat:projectData/ID")</p> #else - <input class="requiredField abbreviation" id="xnat:projectData/ID" type="text" name="xnat:projectData/ID" value="$!item.getStringProperty("xnat:projectData/ID")" size="20" maxlength="14" ONCHANGE="this.value=stringCamelCaps(this.value);"/> + <input class="requiredField abbreviation" id="xnat:projectData/ID" type="text" name="xnat:projectData/ID" value="$!item.getStringProperty("xnat:projectData/ID")" size="14" maxlength="14" onchange="this.value=stringCamelCaps(this.value);"> #end - </TD> - </TR> - #if( $parentTemplate == 'add' ) - <TR class="requirementStatement"> - <TD></TD> - <TD id="projectId_requirementStatement" class="requirementStatement"> + <div class="requirementStatement"> <span class="noteRequired">REQUIRED: </span><span class="formLabelRequiredStatement">Create a one word project identifier. This is used in the database and <b>cannot be changed.</b></span> - </TD> - </TR> - <TR> - <TD colspan="2" class="newProjectSpacer"></TD> - </TR> - #end - - <TR> - <TH align="left"> - <span class="nobr">$displayManager.getSingularDisplayNameForProject() Description</span> - </TH> - <TD> + </div> + </td> + </tr> + + <tr> + <th> + <span class="nobr">${PROJECT_DISPLAY_NAME} Description</span> + </th> + <td> <textarea id="xnat:projectData/description" name="xnat:projectData/description" rows="4" cols="70">$!item.getStringProperty("xnat:projectData/description")</textarea> - </TD> - </TR> - #if( $parentTemplate == 'add' ) - <TR class="requirementStatement"> - <TD></TD> - <TD id="projectDescription_requirementStatement" class="requirementStatement"> + <div class="requirementStatement"> <span class="noteOptional">Optional: </span><span class="formLabelRequiredStatement">Provide a description of your project. This is for reference only and is not searchable.</span> - </TD> - </TR> - <TR> - <TD colspan="2" class="newProjectSpacer"></TD> - </TR> - #end - - <TR> - <TH align="left">Keywords</TH> - <TD> - <input id="xnat:projectData/keywords" type="text" name="xnat:projectData/keywords" value="$!item.getStringProperty("xnat:projectData/keywords")" size="95" maxlength="255"/> - </TD> - </TR> - #if( $parentTemplate == 'add' ) - <TR class="requirementStatement"> - <TD></TD> - <TD id="keywords_requirementStatement" class="requirementStatement"> + </div> + </td> + </tr> + + <tr> + <th>Keywords</th> + <td> + <input id="xnat:projectData/keywords" type="text" name="xnat:projectData/keywords" value="$!item.getStringProperty("xnat:projectData/keywords")" size="95" maxlength="255"> + <div class="requirementStatement"> <span class="noteOptional">Optional: </span><span class="formLabelRequiredStatement">Enter searchable keywords. Each word, separated by a space, can be used independently as a search string.</span> - </TD> - </TR> - <TR> - <TD colspan="2" class="newProjectSpacer"></TD> - </TR> - #end + </div> + </td> + </tr> #addCustomScreens($om.getXSIType() "edit/details") #set($pathInfo = $arcP.getPaths()) - <INPUT TYPE="hidden" NAME="arc:project/current_arc" VALUE="arc001"/> - <TR> - <TH align="left">Alias(es)</TH> - <TD> + <input type="hidden" name="arc:project/current_arc" value="arc001"> + + <tr> + <th>Alias(es)</th> + <td> #set($numAliases = $om.getAliases_alias().size()) #if(!$numAliases || $numAliases < 3) #set($numAliases = 3) #end #foreach($aliasCounter in [0..$numAliases]) - <input type="text" size="17" maxlength="99" class="project_alias" id="xnat:projectData/aliases/alias[$aliasCounter]/alias" name="xnat:projectData/aliases/alias[$aliasCounter]/alias" value="$!item.getStringProperty("xnat:projectData/aliases/alias[$aliasCounter]/alias")"/> + <input type="text" size="17" maxlength="99" class="project_alias" id="xnat:projectData/aliases/alias[$aliasCounter]/alias" name="xnat:projectData/aliases/alias[$aliasCounter]/alias" value="$!item.getStringProperty("xnat:projectData/aliases/alias[$aliasCounter]/alias")"> #end - </TD> - </TR> - #if( $parentTemplate == 'add' ) - <TR class="requirementStatement"> - <TD></TD> - <TD id="aliases_requirementStatement" class="requirementStatement"> + <div class="requirementStatement"> <span class="noteOptional">Optional: </span><span class="formLabelRequiredStatement">Enter alternate aliases (for example: charge codes) that this project can be identified by.</span> - </TD> - </TR> - <TR> - <TD colspan="2" class="newProjectSpacer"></TD> - </TR> - #end - - <TR> - <TH align="left">Investigator(s)</TH> - <TD> + </div> + </td> + </tr> + + <tr> + <th>Investigator(s)</th> + <td> + <!-- #investigatorBox gets replaced via JS --> <div id="investigatorBox">Loading...</div> - </TD> - </TR> - #if( $parentTemplate == 'add' ) - <TR class="requirementStatement"> - <TD></TD> - <TD id="investigators_requirementStatement" class="requirementStatement"> + + <div class="requirementStatement"> <span class="noteOptional">Optional: </span><span class="formLabelRequiredStatement">List investigators associated with this project. This is for reference only and <b>does not provide access</b> to this project for the listed investigators.</span> - </TD> - </TR> - <TR> - <TD colspan="2" class="newProjectSpacer"></TD> - </TR> - #end - -</TABLE> + </div> + </td> + </tr> + +</table> + <script type="text/javascript" src="$content.getURI("scripts/generated/xnat_investigatorData.js")"></script> -##<script type="text/javascript" src="$content.getURI("scripts/xnat_investigatorData/investigatorManager.js")"></script> -<script type="text/javascript" src="$content.getURI("scripts/xnat/app/investigators.js")"></script> -<script> +<script> + (function(){ - var investigators = getObject(XNAT.app.investigators); + var projectDetails$ = $('#project_details'); + + #if ( $parentTemplate == 'add' ) + projectDetails$.addClass('add-project'); + #elseif ( $parentTemplate == 'edit' ) + projectDetails$.addClass('edit-project'); + #end + + var investigators = XNAT.app.investigators = getObject(XNAT.app.investigators); var projectID = XNAT.data.context.projectID; investigators.project = projectID; @@ -184,258 +207,18 @@ #end #end - console.log(investigators.primary); - - var iBox = $('#investigatorBox'); - var piBox = spawn('span#primary-investigator-menu'); - - var piMenu = investigators.init(); - - // creates <select> - piMenu.createMenu({ - name: 'xnat:projectData/pi_xnat_investigatordata_id' - }); - - // creates <option> elements with PI selected - piMenu.createMenuItems(investigators.primary); - - // puts the menu in the box - piMenu.render(piBox, 300); - - // button for creating new investigators - var creator = spawn('button#create-investigator|type=button', 'Create Investigator'); - - creator.onclick = function(){ - piMenu.dialog(); - }; - - iBox.html('<b>PI:</b> ') - .append(piBox) - .append(' ') - .append(creator); - - - // TODO: 'OTHER' INVESTIGATORS -// -// function othersMenu(){ -// var iMenu = XNAT.app.investigators.init(inv); -// -// iMenu.setMenu(spawn('select|multiple', {name: iMenuName()} )); -// iMenu.getAll({ -// success: function(){ -// iBox.empty() -// .append([ -// '<b>PI:</b>', -// ' ', -// iContainer, -// ' ', -// iButton -// ]); -// } -// }); -// -// iMenu.renderMenu(iContainer); -// -// } - - - //var iDialog = XNAT.app.investigators.dialog(); - - + investigators.primary = investigators.primary || 'NULL'; + console.log(investigators.primary); })(); - //var removeInvestigatorIcon = 'url($content.getURI("scripts/yui/build/assets/skins/images/xnat-sprite.png"))'; - -## window.refreshInvestigators = function () { -## var div = document.getElementById("investigatorBox"); -## div.innerHTML = ""; -## -## var table = document.createElement("table"); -## var tbody = document.createElement("tbody"); -## var tr = document.createElement("tr"); -## -## tbody.appendChild(tr); -## table.appendChild(tbody); -## div.appendChild(table); -## var th = document.createElement("th"); -## th.innerHTML = "PI"; -## tr.appendChild(th); -## -## var td = document.createElement("td"); -## var piSelect = document.createElement("select"); -## piSelect.id='primaryInvestigator_0'; -## piSelect.name = "xnat:projectData/pi_xnat_investigatordata_id"; -## piSelect.onchange=changeOtherInvestigator; -## window.invest_manager.populateSelect(piSelect, window.primary_investigator, true); -## td.appendChild(piSelect); -## tr.appendChild(td); -## td = document.createElement("td"); -## var remInvestButton = document.createElement("div"); -## remInvestButton.className = "icon-cancel"; -## remInvestButton.style.backgroundImage = removeInvestigatorIcon; -## remInvestButton.id = "remInvestBut_" + (tbody.rows.length); -## remInvestButton.title = "Remove Investigator"; -## remInvestButton.onclick = function () { -## $(piSelect).val("NULL"); -## }; -## td.appendChild(remInvestButton); -## tr.appendChild(td); -## -## //MORE INVESTIGATORS -## var td = document.createElement("td"); -## td.valign = "bottom"; -## var button = document.createElement("input"); -## button.type = "button"; -## button.value = "More Investigators"; -## button.tbody = tbody; -## button.onclick = function () { -## tr = document.createElement("tr"); -## tr.id = "Investigator_" + (tbody.rows.length); -## var th = document.createElement("th"); -##// th.innerHTML="Investigator "+(tbody.rows.length); -## tr.appendChild(th); -## var td = document.createElement("td"); -## var pSelect = document.createElement("select"); -## pSelect.id = "otherInvestigator_"+(tbody.rows.length); -## pSelect.name = "xnat:projectData/investigators/investigator[" + (tbody.rows.length) + "]/xnat_investigatordata_id"; -## pSelect.onchange=changeOtherInvestigator; -## window.invest_manager.populateSelect(pSelect, window.other_investigators[otherCounter], false); -## td.appendChild(pSelect); -## tr.appendChild(td); -## td = document.createElement("td"); -## var remInvestButton = document.createElement("div"); -## remInvestButton.className = "icon-cancel"; -## remInvestButton.style.backgroundImage = removeInvestigatorIcon; -## remInvestButton.id = "remInvestBut_" + (tbody.rows.length); -## remInvestButton.title = "Remove Investigator"; -## remInvestButton.onclick = function () { -## var idx = this.id.substr(this.id.indexOf('_') + 1); -## removeInvestigator(idx); -## }; -## td.appendChild(remInvestButton); -## tr.appendChild(td); -## tbody.appendChild(tr); -## return false; -## } -## td.appendChild(button); -## tr.appendChild(td); -## -## //CREATE INVESTIGATOR -## var td = document.createElement("td"); -## td.valign = "bottom"; -## var button = document.createElement("input"); -## button.type = "button"; -## button.value = "Create Investigator"; -## button.tbody = tbody; -## button.onclick = function () { -## if (window.investigatorForm != undefined) { -## window.investigatorForm.close(); -## window.investigatorForm = null; -## } -## -## window.create_investigator_link = "$link.setPage('XDATScreen_edit_xnat_investigatorData.vm').addPathInfo('popup','true')"; -## window.create_investigator_link += "/project/$project/destination/JS_Parent_Return.vm"; -## -## window.investigatorForm = window.open(window.create_investigator_link, '', 'width=500,height=550,status=yes,resizable=yes,scrollbars=yes,toolbar=no'); -## if (window.investigatorForm.opener == null) window.investigatorForm.opener = self; -## } -## td.appendChild(button); -## tr.appendChild(td); -## -## for (var otherCounter = 0; otherCounter < window.other_investigators.length; otherCounter++) { -## createOtherInvestigator(otherCounter, tbody, tr); -## } -## if(window.unsavedInvestigators){ -## for(var unsavedCounter=0;unsavedCounter<window.unsavedInvestigators.length;unsavedCounter++){ -## if(typeof window.unsavedInvestigators[unsavedCounter] === 'string'){ -## $(window.unsavedInvestigators[unsavedCounter]).remove(); -## } else if(unsavedCounter == 0 && window.unsavedInvestigators[unsavedCounter]){ -## $('#primaryInvestigator_0').val(window.unsavedInvestigators[unsavedCounter]); -## } else if(window.unsavedInvestigators[unsavedCounter]){ -## if(unsavedCounter > otherCounter){ -## createOtherInvestigator(unsavedCounter-1, tbody, tr); -## } -## $('#otherInvestigator_'+unsavedCounter).val(window.unsavedInvestigators[unsavedCounter]); -## } -## } -## } -## }; -## -## function createOtherInvestigator(index, tbody, tr){ -## tr=document.createElement("tr"); -## tr.id="Investigator_" + (index+1); -## var th= document.createElement("th"); -## tr.appendChild(th); -## var td= document.createElement("td"); -## var pSelect=document.createElement("select"); -## pSelect.id = "otherInvestigator_"+(index+1); -## pSelect.name="xnat:projectData/investigators/investigator["+ (index+1) + "]/xnat_investigatordata_id"; -## pSelect.onchange=changeOtherInvestigator; -## window.invest_manager.populateSelect(pSelect,window.other_investigators[index],false); -## td.appendChild(pSelect); -## tr.appendChild(td); -## td= document.createElement("td"); -## var remInvestButton = document.createElement("div"); -## remInvestButton.className="icon-cancel"; -## remInvestButton.style.backgroundImage=removeInvestigatorIcon; -## remInvestButton.id="remInvestBut_"+(tbody.rows.length); -## remInvestButton.title="Remove Investigator"; -## remInvestButton.onclick=function(){ -## var idx = this.id.substr(this.id.indexOf('_')+1); -## removeInvestigator(idx); -## }; -## td.appendChild(remInvestButton); -## tr.appendChild(td); -## tbody.appendChild(tr); -## }; -## -## var changeOtherInvestigator = function(event){ -## if(!window.unsavedInvestigators){ -## window.unsavedInvestigators = []; -## } -## var invNum = parseInt($(event.target).val()) -## var selId= $(event.target)[0].id; -## var idx = selId.substring((selId.indexOf('_')+1)); -## window.unsavedInvestigators[idx] = invNum; -## }; -## -## window.success = function (subject_id) { -## if (window.investigatorForm != undefined) { -## window.investigatorForm.close(); -## window.investigatorForm = null; -## } -## xmodal.message('Saved Investigator', 'The investigator you entered was stored.'); -## document.getElementById("investigatorBox").innerHTML = "Loading..."; -## window.invest_manager.init(); -## } -## window.failure = function (msg) { -## xmodal.message('Save Failed', msg); -## if (window.investigatorForm != undefined) { -## window.investigatorForm.close(); -## window.investigatorForm = null; -## } -## } -## -## window.invest_manager.investigatorsLoaded.subscribe(window.refreshInvestigators, this); -## window.invest_manager.init(); -## -## function removeInvestigator(index) { -## var id = '#Investigator_'+index; -## $(id).remove(); -## if(!window.unsavedInvestigators){ -## window.unsavedInvestigators = []; -## } -## window.unsavedInvestigators[index] = id; -## } - function stringCamelCaps(val) { if (val == "")return ""; var temp = val; var regex = /^[0-9A-Za-z_-]+$/g; if (!(regex.test(temp))) { - xmodal.message('Validation Error', 'No special characters allowed in $displayManager.getSingularDisplayNameForProject().toLowerCase() abbreviation.'); + xmodal.message('Validation Error', 'No special characters allowed in ${PROJECT_DISPLAY_LOWER} ( abbreviation.'); return ""; } var newVal = ''; @@ -451,4 +234,90 @@ return newVal; } -</script> \ No newline at end of file +</script> + +<script type="text/javascript" src="$content.getURI("scripts/xnat/app/investigators.js")"></script> + +<script> + (function(){ + + var investigators = XNAT.app.investigators = getObject(XNAT.app.investigators); + var projectID = XNAT.data.context.projectID; + + // existing container for ALL investigator elements + var iBox = $('#investigatorBox'); + + // xnat:projectData/pi_xnat_investigatordata_id + // PRIMARY INVESTIGATOR + var primaryBox = spawn('span#primary-investigator-menu', [['b', 'Primary Investigator: ']]); + + var primaryMenu = investigators.init(); + var otherMenu = investigators.init(); // new menu instance + + investigators.menus = [primaryMenu, otherMenu]; + + investigators.primaryMenu = primaryMenu; + investigators.otherMenu = otherMenu; + + // creates <select> + primaryMenu.createMenu({ + name: 'xnat:projectData/pi_xnat_investigatordata_id', + className: 'primary' + }); + + // creates <option> elements with PI selected + primaryMenu.createMenuItems(investigators.primary); + + // puts the menu in the box + primaryMenu.render(primaryBox, 300); + + // when the Primary menu changes, disable that option in the 'Other' menu + primaryMenu.menu.onchange = function(){ + console.log(this.value); + investigators.primary = this.value; + otherMenu.updateMenu(); + } + + // button for creating new (other) investigators + var createPrimary = spawn('button#create-primary|type=button', 'Create New'); + + createPrimary.onclick = function(){ + primaryMenu.dialog(); + }; + + var editPrimary = spawn('a#edit-primary|href=#!', 'Edit Selected'); + + editPrimary.onclick = function(){ + if (investigators.primary !== 'NULL') { + primaryMenu.dialog(investigators.primary) + } + } + + // xnat:projectData/investigators/investigator[1]/xnat_investigatordata_id + // OTHER INVESTIGATORS + var otherBox = spawn('div#other-investigators', { + style: { margin: '15px 0' } + }, [ ['b', 'Other Investigators: '], ['br'] ]); + + otherMenu.createMenu({ + id: 'others-menu', + value: '', + className: 'other', + multiple: true + }); + + otherMenu.createMenuItems(investigators.others); + + otherMenu.render(otherBox, 600); + + // button for creating new (other) investigators + var createOther = spawn('button#create-investigator|type=button', 'Create Investigator'); + + createOther.onclick = function(){ + otherMenu.dialog('', primaryMenu); + }; + + iBox.empty().append([primaryBox, ' ', editPrimary, otherBox, createOther]); + + })(); +</script> -- GitLab