Changeset 527
- Timestamp:
- Jun 4, 2010, 12:15:24 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/grails-app/controllers/dbnp/studycapturing/PersonController.groovy
r496 r527 49 49 def possibleGenders = [ 'Male', 'Female' ] 50 50 51 /** 52 * Fires after every action and determines the layout of the page 53 */ 54 def afterInterceptor = { model, modelAndView -> 55 println( params ); 56 57 if ( params['dialog'] ) { 58 model.layout = 'dialog'; 59 model.extraparams = [ 'dialog': 'true' ] ; 60 } else { 61 model.layout = 'main'; 62 model.extraparams = [] ; 63 } 64 } 65 51 66 def index = { 52 67 redirect(action: "list", params: params) … … 66 81 def save = { 67 82 def personInstance = new Person(params) 83 def extraparams = new LinkedHashMap(); 84 85 if( params[ 'dialog' ] ) { 86 extraparams[ 'dialog' ] = params[ 'dialog' ] 87 } 88 68 89 if (personInstance.save(flush: true)) { 69 90 flash.message = "${message(code: 'default.created.message', args: [message(code: 'person.label', default: 'Person'), ( personInstance.firstName ? personInstance.firstName : "" ) + " " + ( personInstance.prefix ? personInstance.prefix : "" ) + " " + ( personInstance.lastName ? personInstance.lastName : "" )])}" 70 redirect(action: "show", id: personInstance.id) 91 92 redirect(action: "show", id: personInstance.id, params: extraparams ) 71 93 } 72 94 else { … … 99 121 def update = { 100 122 def personInstance = Person.get(params.id) 123 124 def extraparams = new LinkedHashMap(); 125 126 if( params[ 'dialog' ] ) { 127 extraparams[ 'dialog' ] = params[ 'dialog' ] 128 } 129 101 130 if (personInstance) { 102 131 if (params.version) { … … 112 141 if (!personInstance.hasErrors() && personInstance.save(flush: true)) { 113 142 flash.message = "${message(code: 'default.updated.message', args: [message(code: 'person.label', default: 'Person'), ( personInstance.firstName ? personInstance.firstName : "" ) + " " + ( personInstance.prefix ? personInstance.prefix : "" ) + " " + ( personInstance.lastName ? personInstance.lastName : "" )])}" 114 redirect(action: "show", id: personInstance.id )143 redirect(action: "show", id: personInstance.id, params: extraparams) 115 144 } 116 145 else { … … 120 149 else { 121 150 flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'person.label', default: 'Person'), params.id])}" 122 redirect(action: "list" )151 redirect(action: "list", params: extraparams) 123 152 } 124 153 } … … 127 156 def personInstance = Person.get(params.id) 128 157 158 def extraparams = new LinkedHashMap(); 159 160 if( params[ 'dialog' ] ) { 161 extraparams[ 'dialog' ] = params[ 'dialog' ] 162 } 163 129 164 if (personInstance) { 130 165 def personName = ( personInstance.firstName ? personInstance.firstName : "" ) + " " + ( personInstance.prefix ? personInstance.prefix : "" ) + " " + ( personInstance.lastName ? personInstance.lastName : "" ); … … 132 167 personInstance.delete(flush: true) 133 168 flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'person.label', default: 'Person'), personName])}" 134 redirect(action: "list" )169 redirect(action: "list", params: extraparams) 135 170 } 136 171 catch (org.springframework.dao.DataIntegrityViolationException e) { 137 172 flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'person.label', default: 'Person'), personName])}" 138 redirect(action: "show", id: params.id )173 redirect(action: "show", id: params.id, params: extraparams) 139 174 } 140 175 } 141 176 else { 142 177 flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'person.label', default: 'Person'), params.id])}" 143 redirect(action: "list" )178 redirect(action: "list", params: extraparams) 144 179 } 145 180 } -
trunk/grails-app/controllers/dbnp/studycapturing/PersonRoleController.groovy
r496 r527 48 48 static allowedMethods = [save: "POST", update: "POST", delete: "POST"] 49 49 50 /** 51 * Fires after every action and determines the layout of the page 52 */ 53 def afterInterceptor = { model, modelAndView -> 54 println( params ); 55 56 if ( params['dialog'] ) { 57 model.layout = 'dialog'; 58 model.extraparams = [ 'dialog': 'true' ] ; 59 } else { 60 model.layout = 'main'; 61 model.extraparams = [] ; 62 } 63 } 64 50 65 def index = { 51 66 redirect(action: "list", params: params) … … 65 80 def save = { 66 81 def personRoleInstance = new PersonRole(params) 82 def extraparams = new LinkedHashMap(); 83 84 if( params[ 'dialog' ] ) { 85 extraparams[ 'dialog' ] = params[ 'dialog' ] 86 } 87 67 88 if (personRoleInstance.save(flush: true)) { 68 89 flash.message = "${message(code: 'default.created.message', args: [message(code: 'personRole.label', default: 'Role'), personRoleInstance.name])}" 69 90 //redirect(action: "show", id: personRoleInstance.id) 70 redirect(action: "list" )91 redirect(action: "list", params: extraparams) 71 92 } 72 93 else { … … 99 120 def update = { 100 121 def personRoleInstance = PersonRole.get(params.id) 122 def extraparams = new LinkedHashMap(); 123 124 if( params[ 'dialog' ] ) { 125 extraparams[ 'dialog' ] = params[ 'dialog' ] 126 } 127 101 128 if (personRoleInstance) { 102 129 if (params.version) { … … 113 140 flash.message = "${message(code: 'default.updated.message', args: [message(code: 'personRole.label', default: 'Role'), personRoleInstance.name])}" 114 141 //redirect(action: "show", id: personRoleInstance.id) 115 redirect(action: "list" )142 redirect(action: "list", params: extraparams) 116 143 117 144 } … … 122 149 else { 123 150 flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'personRole.label', default: 'Role'), params.id])}" 124 redirect(action: "list" )151 redirect(action: "list", params: extraparams) 125 152 } 126 153 } … … 128 155 def delete = { 129 156 def personRoleInstance = PersonRole.get(params.id) 157 def extraparams = new LinkedHashMap(); 158 159 if( params[ 'dialog' ] ) { 160 extraparams[ 'dialog' ] = params[ 'dialog' ] 161 } 162 130 163 131 164 if (personRoleInstance) { … … 134 167 personRoleInstance.delete(flush: true) 135 168 flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'personRole.label', default: 'Role'), roleName])}" 136 redirect(action: "list" )169 redirect(action: "list", params: extraparams) 137 170 } 138 171 catch (org.springframework.dao.DataIntegrityViolationException e) { 139 172 flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'personRole.label', default: 'Role'), roleName])}" 140 173 // redirect(action: "show", id: params.id) 141 redirect(action: "list" )174 redirect(action: "list", params: extraparams) 142 175 } 143 176 } 144 177 else { 145 178 flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'personRole.label', default: 'Role'), params.id])}" 146 redirect(action: "list" )179 redirect(action: "list", params: extraparams) 147 180 } 148 181 } -
trunk/grails-app/controllers/dbnp/studycapturing/WizardController.groovy
r526 r527 682 682 } 683 683 684 // handle Publications 684 // handle Publications and Contacts 685 685 handlePublications(flow, flash, params) 686 handleContacts(flow, flash, params) 686 687 687 688 // validate study … … 739 740 } 740 741 741 742 /** 743 * re-usable code for handling contacts form data in a web flow 744 * @param Map LocalAttributeMap (the flow scope) 745 * @param Map localAttributeMap (the flash scope) 746 * @param Map GrailsParameterMap (the flow parameters = form data) 747 * @returns boolean 748 */ 749 def handleContacts(flow, flash, params) { 750 // create study instance if we have none 751 if (!flow.study) flow.study = new Study(); 752 if (!flow.study.persons ) flow.study.persons = []; 753 754 // Check the ids of the contacts that should be attached 755 // to this study. If they are already attached, keep 'm. If 756 // studies are attached that are not in the selected (i.e. the 757 // user deleted them), remove them 758 759 // Contacts are saved as [person_id]-[role_id] 760 println( params ); 761 def contactIDs = params.get( 'contacts_ids' ); 762 println( contactIDs ); 763 if( contactIDs ) { 764 // Find the individual IDs and make integers 765 contactIDs = contactIDs.split(',').collect { 766 def parts = it.split( '-' ); 767 return [ person: Integer.parseInt( parts[0] ), role: Integer.parseInt( parts[1] ) ]; 768 }; 769 770 // First remove the contacts that are not present in the array 771 flow.study.persons.removeAll { 772 studyperson -> !contactIDs.find { ids -> ( ids.person == studyperson.person.id ) && ( ids.role == studyperson.role.id ) } 773 }; 774 775 // Add those contacts not yet present in the database 776 contactIDs.each { ids -> 777 if( !flow.study.persons.find { studyperson -> ( ids.person == studyperson.person.id ) && ( ids.role == studyperson.role.id ) } ) { 778 def person = Person.get( ids.person ); 779 def role = PersonRole.get( ids.role ); 780 if( person && role ) { 781 // Find a studyperson object with these parameters 782 def studyPerson = StudyPerson.findAll().find { studyperson -> studyperson.person.id == person.id && studyperson.role.id == role.id }; 783 784 // If if does not yet exist, save the example 785 if( !studyPerson ) { 786 studyPerson = new StudyPerson( 787 person: person, 788 role: role 789 ); 790 studyPerson.save( flush: true ); 791 } 792 793 flow.study.addToPersons( studyPerson ); 794 } else { 795 println( 'Person ' + ids.person + ' or Role ' + ids.role + ' not found in database.' ); 796 } 797 } 798 } 799 800 } else { 801 println( 'No persons selected.') 802 flow.study.persons.clear(); 803 } 804 805 } 742 806 /** 743 807 * re-usable code for handling subject form data in a web flow -
trunk/grails-app/domain/dbnp/studycapturing/Person.groovy
r496 r527 46 46 */ 47 47 48 class Person {48 class Person implements java.io.Serializable { 49 49 50 50 String title -
trunk/grails-app/domain/dbnp/studycapturing/PersonAffiliation.groovy
r496 r527 46 46 */ 47 47 48 class PersonAffiliation {48 class PersonAffiliation implements java.io.Serializable { 49 49 50 50 String institute -
trunk/grails-app/domain/dbnp/studycapturing/PersonRole.groovy
r496 r527 46 46 */ 47 47 48 class PersonRole {48 class PersonRole implements java.io.Serializable { 49 49 50 50 String name -
trunk/grails-app/domain/dbnp/studycapturing/StudyPerson.groovy
r496 r527 49 49 * Link table which couples studies with persons and the role they have within the study 50 50 */ 51 class StudyPerson {51 class StudyPerson implements java.io.Serializable { 52 52 Person person 53 53 PersonRole role -
trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy
r519 r527 136 136 // change form if a form attribute is present 137 137 if (attrs.get('form')) { 138 button = button.replaceFirst(/this\.form/, 138 // Old way 139 /* 140 button = button.replaceFirst(/this\.form/, 139 141 "\\\$('" + attrs.get('form') + "')" 142 ) 143 */ 144 145 button = button.replace("jQuery(this).parents('form:first')", 146 "\$('" + attrs.get('form') + "')" 140 147 ) 141 148 } … … 1023 1030 out << '</form>'; 1024 1031 out << '<script type="text/javascript">'; 1032 out << ' var onSelect = function( chooserObject, inputElement, event, ui ) { selectPubMedAdd( chooserObject, inputElement, event, ui ); enableButton( ".'+ attrs.name + '_publication_dialog", "Add", true ); };' 1025 1033 out << ' iField = $( "#' + attrs.get( 'name' ) + '" );'; 1026 out << ' new PublicationChooser().initAutocomplete( iField );';1034 out << ' new PublicationChooser().initAutocomplete( iField, { "select" : onSelect } );'; 1027 1035 out << '</script>'; 1028 1036 } … … 1067 1075 ids = ''; 1068 1076 } 1069 out << '<input type="hidden" name="' + attrs.name + '_ids" value="' + ids + '" id="' + attrs.name + '_ids" value="' + ids + '">';1077 out << '<input type="hidden" name="' + attrs.name + '_ids" value="' + ids + '" id="' + attrs.name + '_ids">'; 1070 1078 } 1071 1079 … … 1078 1086 out << '</div>'; 1079 1087 out << '<script type="text/javascript">'; 1080 out << ' $("#' + attrs.name + '_dialog").dialog({'; 1081 out << ' title : "Add publication",'; 1082 out << ' autoOpen: false,'; 1083 out << ' width : 800,'; 1084 out << ' height : 400,'; 1085 out << ' modal : true,'; 1086 out << ' position: "center",'; 1087 out << ' buttons : {'; 1088 out << ' Add : function() { addPublication( "' + attrs.name + '" ); $(this).dialog("close"); },'; 1089 out << ' Close : function() { $(this).dialog("close"); }'; 1090 out << ' },'; 1091 out << ' close : function() {'; 1092 out << ' /* closeFunc(this); */'; 1093 out << ' }'; 1094 out << ' }).width(790).height(400);'; 1088 out << ' createPublicationDialog( "' + attrs.name + '" );' 1095 1089 out << '</script>'; 1096 1090 1097 out << '<input type="button" onClick=" var field = $( \'#' + attrs.name + '\' ); field.autocomplete( \'close\' ); field.val( \'\' );$( \'#' + attrs.name + '_dialog\' ).dialog( \'open\' ); field.focus();" value="Add Publication">';1091 out << '<input type="button" onClick="openPublicationDialog(\'' + attrs.name + '\' );" value="Add Publication">'; 1098 1092 } 1099 1093 1094 def ContactSelectElement = { attrs, body -> 1095 1096 attrs.description = 'Contacts'; 1097 // render list with publications currently available 1098 baseElement.call( 1099 '_contactList', 1100 attrs, 1101 body 1102 ) 1103 1104 attrs.description = ''; 1105 1106 // render 'publications list' 1107 out << '<div id="' + attrs.name + '_dialog" class="contacts_dialog" style="display: none;">' 1108 baseElement.call( 1109 '_personSelect', 1110 attrs, 1111 body 1112 ) 1113 baseElement.call( 1114 '_roleSelect', 1115 attrs, 1116 body 1117 ) 1118 baseElement.call( 1119 '_contactAddButtonAddition', 1120 attrs, 1121 body 1122 ) 1123 out << '</div>'; 1124 1125 // render 'Add contact button' 1126 baseElement.call( 1127 '_contactAddDialogButton', 1128 attrs, 1129 body 1130 ) 1131 } 1132 1133 def _contactList = { attrs, body -> 1134 def display_none = 'none'; 1135 if( !attrs.get( 'value' ) || attrs.get( 'value' ).size() == 0 ) { 1136 display_none = 'inline'; 1137 } 1138 1139 // Add a unordered list 1140 out << '<ul class="contact_list" id="' + attrs.name + '_list">'; 1141 1142 out << '<li>'; 1143 out << '<span class="contacts_none" id="' + attrs.name + '_none" style="display: ' + display_none + ';">'; 1144 out << 'No contacts selected'; 1145 out << '</span>'; 1146 out << '</li>'; 1147 1148 out << '</ul>'; 1149 1150 // Add the contacts using javascript 1151 out << '<script type="text/javascript">' 1152 if( attrs.get( 'value' ) && attrs.get( 'value' ).size() > 0 ) { 1153 def i = 0; 1154 attrs.get( 'value' ).each { 1155 out << 'showContact( '; 1156 out << ' "' + attrs.name + '",'; 1157 out << ' "' + it.person.id + '-' + it.role.id + '",'; 1158 out << ' "' + it.person.lastName + ', ' + it.person.firstName + ( it.person.prefix ? ' ' + it.person.prefix : '' ) + '",'; 1159 out << ' "' + it.role.name + '",'; 1160 out << ' ' + i++; 1161 out << ');'; 1162 } 1163 } 1164 out << '</script>'; 1165 1166 def ids = ''; 1167 if( attrs.get( 'value' ) && attrs.get( 'value' ).size() > 0 ) { 1168 ids = attrs.get( 'value' ).collect { it.person.id + '-' + it.role.id } 1169 ids = ids.join( ',' ); 1170 } 1171 out << '<input type="hidden" name="' + attrs.name + '_ids" value="' + ids + '" id="' + attrs.name + '_ids">'; 1172 } 1173 1174 def _contactAddSelect = { attrs, body -> 1175 out << _personSelect( attrs ) + _roleSelect( attrs ); 1176 } 1177 1178 def _contactAddButtonAddition = { attrs, body -> 1179 out << '<input type="button" onClick="addContact ( \'' + attrs.name + '\' ); $(\'#' + attrs.name + '_dialog\').hide(); $( \'#' + attrs.name + '_dialogButton\' ).show();" value="Add">'; 1180 out << '<input type="button" onClick="$(\'#' + attrs.name + '_dialog\').hide(); $( \'#' + attrs.name + '_dialogButton\' ).show();" value="Close">'; 1181 } 1182 1183 def _contactAddDialogButton = { attrs, body -> 1184 out << '<input type="button" onClick="$( \'#' + attrs.name + '_dialog\' ).show(); $(this).hide();" id="' + attrs.name + '_dialogButton" value="Add Contact">'; 1185 } 1186 /** 1187 * Person select element 1188 * @param Map attributes 1189 */ 1190 def _personSelect = { attrs -> 1191 def selectAttrs = new LinkedHashMap(); 1192 1193 // define 'from' 1194 def persons = Person.findAll().sort( { a, b -> a.lastName == b.lastName ? ( a.firstName <=> b.firstName ) : ( a.lastName <=> b.lastName ) } as Comparator ); 1195 selectAttrs.from = persons.collect { it.lastName + ', ' + it.firstName + ( it.prefix ? ' ' + it.prefix : '' ) } 1196 selectAttrs.keys = persons.id; 1197 1198 // add 'rel' attribute 1199 selectAttrs.rel = 'person' 1200 selectAttrs.name = attrs.name + '_person'; 1201 1202 out << "Person: " + select(selectAttrs) 1203 } 1204 1205 /** 1206 * Role select element 1207 * @param Map attributes 1208 */ 1209 def _roleSelect = { attrs -> 1210 println( attrs ); 1211 def selectAttrs = new LinkedHashMap(); 1212 1213 // define 'from' 1214 def roles = PersonRole.findAll(); 1215 selectAttrs.from = roles.collect { it.name }; 1216 selectAttrs.keys = roles.id; 1217 1218 // add 'rel' attribute 1219 selectAttrs.rel = 'role' 1220 selectAttrs.name = attrs.name + '_role'; 1221 1222 out << "Role: " + select(selectAttrs) 1223 } 1100 1224 } -
trunk/grails-app/views/person/create.gsp
r496 r527 4 4 <head> 5 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <meta name="layout" content=" main" />6 <meta name="layout" content="${layout}" /> 7 7 <g:set var="entityName" value="${message(code: 'person.label', default: 'Person')}" /> 8 8 <title><g:message code="default.create.label" args="[entityName]" /></title> … … 114 114 </td> 115 115 </tr> 116 116 117 117 <tr class="prop"> 118 118 <td valign="top" class="name"> … … 123 123 </td> 124 124 </tr> 125 125 126 126 </tbody> 127 127 </table> 128 128 </div> 129 129 <div class="buttons"> 130 <g:each in="${extraparams}" var="param"> 131 <input type="hidden" name="${param.key}" value="${param.value}"> 132 </g:each> 130 133 <span class="button"><g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" /></span> 131 <span class="button"><g:link class="cancel" action="list" >Cancel</g:link></span>134 <span class="button"><g:link class="cancel" action="list" params="${extraparams}">Cancel</g:link></span> 132 135 </div> 133 136 </g:form> -
trunk/grails-app/views/person/edit.gsp
r496 r527 4 4 <head> 5 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <meta name="layout" content=" main" />6 <meta name="layout" content="${layout}" /> 7 7 <g:set var="entityName" value="${message(code: 'person.label', default: 'Person')}" /> 8 8 <title><g:message code="default.edit.label" args="[entityName]" /></title> … … 30 30 <label for="title"><g:message code="person.title.label" default="Title" /></label> 31 31 </td> 32 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'title', 'errors')}">32 <td colspan="3" valign="top" class="value ${hasErrors(bean: personInstance, field: 'title', 'errors')}"> 33 33 <g:textField name="title" value="${personInstance?.title}" /> 34 34 </td> … … 39 39 <label for="gender"><g:message code="person.gender.label" default="Gender" /></label> 40 40 </td> 41 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'gender', 'errors')}">41 <td colspan="3" valign="top" class="value ${hasErrors(bean: personInstance, field: 'gender', 'errors')}"> 42 42 <g:select name="gender" from="${possibleGenders}" noSelection="['' : 'Not specified']" value="${personInstance?.gender}" /> 43 43 </td> … … 51 51 <g:textField name="firstName" value="${personInstance?.firstName}" /> 52 52 </td> 53 </tr>54 55 <tr class="prop">56 53 <td valign="top" class="name"> 57 54 <label for="initials"><g:message code="person.initials.label" default="Initials" /></label> … … 64 61 <tr class="prop"> 65 62 <td valign="top" class="name"> 63 <label for="lastName"><g:message code="person.lastName.label" default="Last Name" /></label> 64 </td> 65 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'lastName', 'errors')}"> 66 <g:textField name="lastName" value="${personInstance?.lastName}" /> 67 </td> 68 <td valign="top" class="name"> 66 69 <label for="prefix"><g:message code="person.prefix.label" default="Prefix" /></label> 67 70 </td> 68 71 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'prefix', 'errors')}"> 69 72 <g:textField name="prefix" value="${personInstance?.prefix}" /> 70 </td>71 </tr>72 73 74 <tr class="prop">75 <td valign="top" class="name">76 <label for="lastName"><g:message code="person.lastName.label" default="Last Name" /></label>77 </td>78 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'lastName', 'errors')}">79 <g:textField name="lastName" value="${personInstance?.lastName}" />80 73 </td> 81 74 </tr> … … 85 78 <label for="address"><g:message code="person.address.label" default="Address" /></label> 86 79 </td> 87 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'address', 'errors')}">80 <td colspan="3" valign="top" class="value ${hasErrors(bean: personInstance, field: 'address', 'errors')}"> 88 81 <g:textField name="address" value="${personInstance?.address}" /> 89 82 </td> … … 94 87 <label for="phone"><g:message code="person.phone.label" default="Work Phone" /></label> 95 88 </td> 96 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'phone', 'errors')}">89 <td colspan="3" valign="top" class="value ${hasErrors(bean: personInstance, field: 'phone', 'errors')}"> 97 90 <g:textField name="phone" value="${personInstance?.phone}" /> 98 91 </td> … … 103 96 <label for="mobile"><g:message code="person.mobile.label" default="Mobile Phone" /></label> 104 97 </td> 105 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'mobile', 'errors')}">98 <td colspan="3" valign="top" class="value ${hasErrors(bean: personInstance, field: 'mobile', 'errors')}"> 106 99 <g:textField name="mobile" value="${personInstance?.phone}" /> 107 100 </td> … … 113 106 <label for="fax"><g:message code="person.fax.label" default="Fax" /></label> 114 107 </td> 115 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'fax', 'errors')}">108 <td colspan="3" valign="top" class="value ${hasErrors(bean: personInstance, field: 'fax', 'errors')}"> 116 109 <g:textField name="fax" value="${personInstance?.fax}" /> 117 110 </td> … … 122 115 <label for="email"><g:message code="person.email.label" default="Email" /></label> 123 116 </td> 124 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'email', 'errors')}">117 <td colspan="3" valign="top" class="value ${hasErrors(bean: personInstance, field: 'email', 'errors')}"> 125 118 <g:textField name="email" value="${personInstance?.email}" /> 126 119 </td> … … 131 124 <label for="affiliations"><g:message code="person.affiliations.label" default="Affiliations" /></label> 132 125 </td> 133 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'affiliations', 'errors')}">126 <td colspan="3" valign="top" class="value ${hasErrors(bean: personInstance, field: 'affiliations', 'errors')}"> 134 127 <g:select name="affiliations" from="${dbnp.studycapturing.PersonAffiliation.list()}" multiple="yes" optionKey="id" size="5" value="${personInstance?.affiliations}" /> 135 128 </td> … … 140 133 </div> 141 134 <div class="buttons"> 135 <g:each in="${extraparams}" var="param"> 136 <input type="hidden" name="${param.key}" value="${param.value}"> 137 </g:each> 138 142 139 <span class="button"><g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" /></span> 143 140 <span class="button"><g:actionSubmit class="cancel" action="show" value="Cancel" /></span> -
trunk/grails-app/views/person/list.gsp
r496 r527 4 4 <head> 5 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <meta name="layout" content=" main" />6 <meta name="layout" content="${layout}" /> 7 7 <g:set var="entityName" value="${message(code: 'person.label', default: 'Person')}" /> 8 8 <title><g:message code="default.list.label" args="[entityName]" /></title> … … 19 19 <tr> 20 20 21 <g:sortableColumn p roperty="firstName" title="${message(code: 'person.firstName.label', default: 'First Name')}" />21 <g:sortableColumn params="${extraparams}" property="firstName" title="${message(code: 'person.firstName.label', default: 'First Name')}" /> 22 22 23 <g:sortableColumn p roperty="prefix" title="${message(code: 'person.prefix.label', default: 'Prefix')}" />23 <g:sortableColumn params="${extraparams}" property="prefix" title="${message(code: 'person.prefix.label', default: 'Prefix')}" /> 24 24 25 <g:sortableColumn p roperty="lastName" title="${message(code: 'person.lasttName.label', default: 'Last Name')}" />25 <g:sortableColumn params="${extraparams}" property="lastName" title="${message(code: 'person.lasttName.label', default: 'Last Name')}" /> 26 26 27 <g:sortableColumn property="phone" title="${message(code: 'person.phone.label', default: 'Work Phone')}" /> 27 <g:if test="${layout!='dialog'}"> 28 <g:sortableColumn params="${extraparams}" property="phone" title="${message(code: 'person.phone.label', default: 'Work Phone')}" /> 28 29 29 <g:sortableColumn property="email" title="${message(code: 'person.email.label', default: 'Email')}" /> 30 <g:sortableColumn params="${extraparams}" property="email" title="${message(code: 'person.email.label', default: 'Email')}" /> 31 </g:if> 30 32 31 33 <th>Affiliations</th> … … 40 42 <td>${fieldValue(bean: personInstance, field: "prefix")}</td> 41 43 42 <td><g:link action="show" id="${personInstance.id}">${fieldValue(bean: personInstance, field: "lastName")}</g:link></td>44 <td><g:link params="${extraparams}" action="show" id="${personInstance.id}">${fieldValue(bean: personInstance, field: "lastName")}</g:link></td> 43 45 44 <td>${fieldValue(bean: personInstance, field: "phone")}</td> 46 <g:if test="${layout!='dialog'}"> 47 <td>${fieldValue(bean: personInstance, field: "phone")}</td> 45 48 46 <td>${fieldValue(bean: personInstance, field: "email")}</td> 49 <td>${fieldValue(bean: personInstance, field: "email")}</td> 50 </g:if> 47 51 48 52 <td> … … 59 63 </div> 60 64 <div class="buttons"> 61 <span class="button"><g:link class="create" action="create" ><g:message code="default.new.label" args="[entityName]" /></g:link></span>65 <span class="button"><g:link class="create" action="create" params="${extraparams}"><g:message code="default.new.label" args="[entityName]" /></g:link></span> 62 66 </div> 63 67 <div class="paginateButtons"> 64 <g:paginate total="${personInstanceTotal}" prev="« Previous" next="» Next" />68 <g:paginate total="${personInstanceTotal}" prev="« Previous" next="» Next" params="${extraparams}" /> 65 69 </div> 66 70 -
trunk/grails-app/views/person/show.gsp
r496 r527 4 4 <head> 5 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <meta name="layout" content=" main" />6 <meta name="layout" content="${layout}" /> 7 7 <g:set var="entityName" value="${message(code: 'person.label', default: 'Person')}" /> 8 8 <title><g:message code="default.show.label" args="[entityName]" /></title> … … 110 110 <g:form> 111 111 <g:hiddenField name="id" value="${personInstance?.id}" /> 112 <g:each in="${extraparams}" var="param"> 113 <input type="hidden" name="${param.key}" value="${param.value}"> 114 </g:each> 112 115 <span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span> 113 116 <span class="button"><g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" /></span> 114 <span class="button"><g:link class="backToList" action="list" >Back to list</g:link></span>117 <span class="button"><g:link class="backToList" action="list" params="${extraparams}">Back to list</g:link></span> 115 118 </g:form> 116 119 </div> -
trunk/grails-app/views/personRole/create.gsp
r496 r527 4 4 <head> 5 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <meta name="layout" content=" main" />6 <meta name="layout" content="${layout}" /> 7 7 <g:set var="entityName" value="${message(code: 'personRole.label', default: 'PersonRole')}" /> 8 8 <title><g:message code="default.create.label" args="['Role']" /></title> … … 38 38 </div> 39 39 <div class="buttons"> 40 <span class="button"><g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" /></span> 41 <span class="button"><g:link class="cancel" action="list">Cancel</g:link></span> 40 <g:each in="${extraparams}" var="param"> 41 <input type="hidden" name="${param.key}" value="${param.value}"> 42 </g:each> 43 <span class="button"><g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" /></span> 44 <span class="button"><g:link class="cancel" action="list" params="${extraparams}">Cancel</g:link></span> 42 45 </div> 43 46 </g:form> -
trunk/grails-app/views/personRole/edit.gsp
r496 r527 4 4 <head> 5 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <meta name="layout" content=" main" />6 <meta name="layout" content="${layout}" /> 7 7 <g:set var="entityName" value="${message(code: 'personRole.label', default: 'PersonRole')}" /> 8 8 <title><g:message code="default.edit.label" args="['Role']" /></title> … … 40 40 </div> 41 41 <div class="buttons"> 42 <g:each in="${extraparams}" var="param"> 43 <input type="hidden" name="${param.key}" value="${param.value}"> 44 </g:each> 42 45 <span class="button"><g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" /></span> 43 46 <span class="button"><g:actionSubmit class="cancel" action="list" value="Cancel" /></span> -
trunk/grails-app/views/personRole/list.gsp
r496 r527 4 4 <head> 5 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <meta name="layout" content=" main" />6 <meta name="layout" content="${layout}" /> 7 7 <g:set var="entityName" value="${message(code: 'personRole.label', default: 'PersonRole')}" /> 8 8 <title><g:message code="default.list.label" args="['Role']" /></title> … … 30 30 <td class="buttons"> 31 31 <g:form> 32 <g:each in="${extraparams}" var="param"> 33 <input type="hidden" name="${param.key}" value="${param.value}"> 34 </g:each> 32 35 <g:hiddenField name="id" value="${personRoleInstance?.id}" /> 33 36 <span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span> … … 41 44 </div> 42 45 <div class="buttons"> 43 <span class="button"><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></span>46 <span class="button"><g:link params="${extraparams}" class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></span> 44 47 </div> 45 48 <div class="paginateButtons"> 46 <g:paginate total="${personRoleInstanceTotal}" prev="« Previous" next="» Next" />49 <g:paginate total="${personRoleInstanceTotal}" prev="« Previous" next="» Next" params="${extraparams}" /> 47 50 </div> 48 51 </div> -
trunk/grails-app/views/personRole/show.gsp
r496 r527 4 4 <head> 5 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 <meta name="layout" content=" main" />6 <meta name="layout" content="${layout}" /> 7 7 <g:set var="entityName" value="${message(code: 'personRole.label', default: 'PersonRole')}" /> 8 8 <title><g:message code="default.show.label" args="['Role']" /></title> … … 32 32 <g:form> 33 33 <g:hiddenField name="id" value="${personRoleInstance?.id}" /> 34 <g:each in="${extraparams}" var="param"> 35 <input type="hidden" name="${param.key}" value="${param.value}"> 36 </g:each> 34 37 <span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span> 35 38 <span class="button"><g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" /></span> 36 <span class="button"><g:link class="backToList" action="list" >Back to list</g:link></span>39 <span class="button"><g:link class="backToList" action="list" params="${extraparams}">Back to list</g:link></span> 37 40 </g:form> 38 41 </div> -
trunk/grails-app/views/wizard/common/_navigation.gsp
r376 r527 28 28 // scriptable webflow action 29 29 function refreshWebFlow() { 30 <wizard:ajaxSubmitJs name="refresh" url="[controller:'wizard',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" class="prevnext" />30 <wizard:ajaxSubmitJs form="#wizardForm" name="refresh" url="[controller:'wizard',action:'pages']" update="[success:'wizardPage',failure:'wizardError']" afterSuccess="onWizardPage()" class="prevnext" /> 31 31 } 32 32 </script> -
trunk/grails-app/views/wizard/pages/_study.gsp
r526 r527 30 30 31 31 <wizard:publicationSelectElement name="publication" value="${study?.publications}" /> 32 <wizard:contactSelectElement name="contacts" value="${study?.persons}" /> 32 33 33 34 </wizard:pageContent> -
trunk/web-app/css/dialog.css
r438 r527 22 22 } 23 23 /* END :: ontology autocomplete */ 24 25 /* In a dialog, headers shoudn't be displayed, as the dialog itself has a title */ 26 h1, h2 { 27 display: none; 28 } 29 30 /** START :: content **/ 31 #content { 32 padding-top: 40px; 33 font-family: Verdana, Arial, Helvetica, sans-serif; 34 font-size: 10pt; 35 padding-bottom: 20px; 36 } 37 38 #content p { 39 text-align: justify; 40 } 41 #content a:link, #content a:visited, #content a:hover{ 42 color: #006dba; 43 text-decoration: none; 44 } 45 #content p img { 46 display: run-in; 47 float: right; 48 padding: 2px; 49 border: 1px solid #006dba; 50 margin-left: 10px; 51 margin-bottom: 10px; 52 height: 120px; 53 } 54 55 #content .message { 56 border: 1px solid #ccc; /* #006dba; */ 57 margin-bottom: 10px; 58 margin-top: 10px; 59 60 background: #f7f7f7 url(../images/icons/famfamfam/information.png) 10px 10px no-repeat; 61 padding: 10px 10px 10px 33px; 62 63 } 64 65 /** END :: content **/ 66 /** START :: TABLES **/ 67 table { 68 border: 1px solid #ccc; 69 width: 100% 70 } 71 tr { 72 border: 0; 73 } 74 td, th { 75 font: 11px verdana, arial, helvetica, sans-serif; 76 line-height: 12px; 77 padding: 5px 6px; 78 text-align: left; 79 vertical-align: top; 80 } 81 th { 82 background: #fff url(../images/default_style/tables/shadow.jpg); 83 color: #666; 84 font-size: 11px; 85 font-weight: bold; 86 line-height: 17px; 87 padding: 2px 6px; 88 } 89 th a:link, th a:visited, th a:hover { 90 color: #333; 91 display: block; 92 font-size: 10px; 93 text-decoration: none; 94 width: 100%; 95 } 96 th.asc a, th.desc a { 97 background-position: right; 98 background-repeat: no-repeat; 99 } 100 th.asc a { 101 background-image: url(../images/default_style/tables/sorted_asc.gif); 102 } 103 th.desc a { 104 background-image: url(../images/default_style/tables/sorted_desc.gif); 105 } 106 107 .odd { 108 background: #f7f7f7; 109 } 110 .even { 111 background: #fff; 112 } 113 114 tr.prop td { padding-top: 2px; padding-bottom: 2px; } 115 /** END :: TABLES **/ 116 117 /** START :: LIST **/ 118 .list table { 119 border-collapse: collapse; 120 } 121 .list th, .list td { 122 border-left: 1px solid #ddd; 123 } 124 .list th:hover, .list tr:hover { 125 background: #b2d1ff; 126 } 127 /** END :: LIST **/ 128 129 /** START :: buttons **/ 130 .buttons { 131 margin-top: 15px; 132 font-size: 10px; 133 } 134 135 /* Hides the default navigation bar that is added by the Grails scaffolding */ 136 /* .nav { display: none; } */ 137 138 /* Links in the buttons section should look just like buttons in the 139 same section */ 140 #content .button a { 141 color: #333; 142 } 143 .button a { 144 font-size: 10px; 145 font-weight: bold; 146 margin-left: 3px; 147 margin-right: 3px; 148 padding-top: 2px; 149 padding-bottom: 2px; 150 } 151 .buttons input { 152 background: #fff; 153 border: 0; 154 color: #333; 155 cursor: pointer; 156 font-size: 10px; 157 font-weight: bold; 158 margin-left: 3px; 159 margin-right: 3px; 160 overflow: visible; 161 padding: 2px 6px; 162 font-family: Verdana, Arial, Helvetica, sans-serif; 163 } 164 165 .buttons input.delete, .buttons a.delete { 166 background: transparent url(../images/icons/famfamfam/delete.png) 5px 50% no-repeat; 167 padding-left: 28px; 168 } 169 .buttons input.edit, .buttons a.edit { 170 background: transparent url(../images/icons/famfamfam/application_edit.png) 5px 50% no-repeat; 171 padding-left: 28px; 172 } 173 .buttons input.save, .buttons a.save { 174 background: transparent url(../images/icons/famfamfam/accept.png) 5px 50% no-repeat; 175 padding-left: 28px; 176 } 177 .buttons input.create, .buttons a.create { 178 background: transparent url(../images/icons/famfamfam/add.png) 5px 50% no-repeat; 179 padding-left: 28px; 180 } 181 .buttons input.backToList, .buttons a.backToList { 182 background: transparent url(../images/icons/famfamfam/application.png) 5px 50% no-repeat; 183 padding-left: 28px; 184 } 185 .buttons input.cancel, .buttons a.cancel { 186 background: transparent url(../images/icons/famfamfam/delete.png) 5px 50% no-repeat; 187 padding-left: 28px; 188 font-weight: normal; 189 } 190 191 /* Reset the font weight for buttons occurring within the table */ 192 td.buttons input { font-weight: normal; } 193 194 /** END :: buttons **/ 195 196 /** START :: pagination buttons **/ 197 .paginateButtons { 198 margin-top: 15px; 199 overflow: auto; 200 width: 100%; 201 } 202 203 .paginateButtons a, 204 .paginateButtons span.currentStep { 205 border:solid 1px #ccc; 206 margin-right:2px; 207 display:block; 208 float:left; 209 padding:1px 6px; 210 text-decoration:none; 211 } 212 213 .paginateButtons a { 214 color:#0e509e; 215 } 216 217 .paginateButtons span.currentStep { 218 background:#2e6ab1; 219 color:#FFFFFF; 220 } 221 222 /** END :: pagination buttons **/ 223 224 /* START :: ontology autocomplete */ 225 .ui-autocomplete .ui-menu-item { 226 font-size: 10px; 227 } 228 .ui-autocomplete .about { 229 font-size: 8px; 230 color: #006DBA; 231 } 232 .ui-autocomplete .from { 233 font-size: 8px; 234 color: #666; 235 } 236 /* END :: ontology autocomplete */ 237 238 /* START :: special select option styles */ 239 option.addMore { 240 background: url(../images/icons/famfamfam/add.png) no-repeat left top; 241 background-color: #333; 242 padding-left: 18px; 243 height: 16px; 244 color: #fff; 245 font-weight: bold; 246 } 247 option.modify { 248 background: url(../images/icons/famfamfam/layout_add.png) no-repeat left top; 249 background-color: #333; 250 padding-left: 18px; 251 height: 16px; 252 color: #fff; 253 font-weight: bold; 254 } 255 option.locked { 256 background: url(../images/icons/famfamfam/lock.png) no-repeat left top; 257 padding-left: 18px; 258 } 259 option.unlocked { 260 padding-left: 18px; 261 } 262 /* END :: special select option styles */ -
trunk/web-app/css/wizard.css
r522 r527 349 349 } 350 350 351 .wizard ul.publication_list {351 .wizard ul.publication_list, .wizard ul.contact_list { 352 352 list-style-type: none; 353 353 margin: -10px 0 0 255px; … … 355 355 } 356 356 357 .wizard ul.publication_list li {357 .wizard ul.publication_list li, .wizard ul.contact_list li { 358 358 margin-left: 0px; 359 359 padding: 4px 6px; 360 360 } 361 361 362 .wizard ul.publication_listli.even {363 background-color: #F 0F0F0;364 } 365 .wizard ul.publication_listli.odd {366 background-color: #F 8F8F8;367 } 368 369 .wizard ul.publication_listli .delete_button { float: right; margin-left: 10px; cursor: pointer; }362 .wizard li.even { 363 background-color: #F3F3F3; 364 } 365 .wizard li.odd { 366 background-color: #FAFAFA; 367 } 368 369 .wizard li .delete_button { float: right; margin-left: 10px; cursor: pointer; } 370 370 .wizard ul.publication_list li .authors { font-size: 10px; margin-top: 3px; color: #333; } 371 .wizard ul.contact_list li .person { display: inline; } 372 .wizard ul.contact_list li .role { color: #000099; display: inline; margin-left: 5px; } 373 .wizard ul.contact_list li .role:before { content: ' / '; color: #000099; } 374 .wizard .contacts_dialog { margin: 5px 0; } -
trunk/web-app/js/publication-chooser.js
r518 r527 177 177 var baseUrl = '..'; 178 178 } 179 var spinnerEl = document.createElement( 'img' ); 180 spinnerEl.setAttribute( 'id', inputElement.attr( 'id' ) + '_spinner' ); 181 spinnerEl.setAttribute( 'src', baseUrl + '/images/spinner.gif' ); 182 spinnerEl.setAttribute( 'style', 'margin-left: 5px;'); 183 184 // Add the element next to the input box 185 inputElement.after( spinnerEl ); 186 $( spinnerEl ).hide(); 187 188 // Also add a 'not found' message 189 var notfoundSpan = document.createElement( 'span' ); 190 notfoundSpan.setAttribute( 'id', inputElement.attr( 'id' ) + '_notfound' ); 191 179 192 var imgEl = document.createElement( 'img' ); 180 imgEl.setAttribute( 'id', inputElement.attr( 'id' ) + '_spinner' ); 181 imgEl.setAttribute( 'src', baseUrl + '/images/spinner.gif' ); 182 imgEl.setAttribute( 'style', 'margin-left: 5px;'); 183 184 // Add the element next to the input box 185 inputElement.after( imgEl ); 186 $( imgEl ).hide(); 193 imgEl.setAttribute( 'id', inputElement.attr( 'id' ) + '_delete' ); 194 imgEl.setAttribute( 'src', baseUrl + '/images/icons/famfamfam/delete.png' ); 195 imgEl.setAttribute( 'style', 'margin-left: 5px; margin-right: 5px; '); 196 197 notfoundSpan.appendChild( imgEl ); 198 notfoundSpan.appendChild( document.createTextNode( "No publications found." ) ); 199 200 // Add the element next to the spinner image 201 $( spinnerEl ).after( notfoundSpan ); 202 $( notfoundSpan ).hide(); 187 203 188 204 // determine what database to use … … 225 241 226 242 source: function(request, response) { 243 // Before the response function is executed, we have to 244 // check whether there are results or nog 245 var improvedResponse = function( objects ) { 246 if( objects.length == 0 ) { 247 $( '#' + inputElement.attr( 'id' ) + '_spinner' ).hide(); 248 $( '#' + inputElement.attr( 'id' ) + '_notfound' ).show(); 249 } 250 251 response( objects ); 252 } 253 227 254 var q = $.trim(request.term); 228 255 … … 230 257 if ( that.cache[ that.database ][ q ]) { 231 258 // yeah, lucky us! ;-P 232 response(that.cache[ that.database ][ q ]);259 improvedResponse(that.cache[ that.database ][ q ]); 233 260 } else { 234 261 if( that.database != "" && that.events[ 'source' ] ) { 235 that.events[ 'source' ]( that, q, response );262 that.events[ 'source' ]( that, q, improvedResponse ); 236 263 } 237 264 } … … 240 267 that.selected = false; 241 268 $( '#' + inputElement.attr( 'id' ) + '_spinner' ).show(); 269 $( '#' + inputElement.attr( 'id' ) + '_notfound' ).hide(); 242 270 }, 243 271 open: function(event, ui ) { 244 272 $( '#' + inputElement.attr( 'id' ) + '_spinner' ).hide(); 273 $( '#' + inputElement.attr( 'id' ) + '_notfound' ).hide(); 245 274 }, 246 275 select: function(event, ui) { -
trunk/web-app/js/publication-chooser.pubmed.js
r518 r527 25 25 // Parse the response 26 26 var parsedData = parsePubmedData( summaryResponse ) 27 27 28 28 // Save in cache 29 29 chooserObject.cache[ chooserObject.database ][ searchterm ] = parsedData; … … 82 82 */ 83 83 function parsePubmedData(responseData) { 84 var data = $("DocSum", responseData).map(function() { 84 var data = []; 85 data = $("DocSum", responseData).map(function() { 85 86 var title = $("Item[Name=Title]", this).text(); 86 87 var authors = buildAuthorList( $("Item[Name=AuthorList]", this ) ); -
trunk/web-app/js/wizard.js
r522 r527 65 65 vars : 'entity', 66 66 label : 'add / modify..', 67 style : 'modify', 68 onClose : function(scope) { 69 refreshWebFlow(); 70 } 71 }); 72 73 // Handle person selects 74 new SelectAddMore().init({ 75 rel : 'person', 76 url : baseUrl + '/person/list?dialog=true', 77 vars : 'person', 78 label : 'add / modify persons...', 79 style : 'modify', 80 onClose : function(scope) { 81 refreshWebFlow(); 82 } 83 }); 84 85 // Handle persoRole selects 86 new SelectAddMore().init({ 87 rel : 'role', 88 url : baseUrl + '/personRole/list?dialog=true', 89 vars : 'role', 90 label : 'add / modify roles...', 67 91 style : 'modify', 68 92 onClose : function(scope) { … … 287 311 } 288 312 313 314 /************************************************* 315 * 316 * Functions for RelTime fields 317 * 318 ************************************************/ 319 289 320 // Show example of parsed data next to RelTime fields 290 321 function showExampleReltime(inputfield) { … … 308 339 }); 309 340 } 341 342 /************************************************* 343 * 344 * Functions for file upload fields 345 * 346 ************************************************/ 310 347 311 348 // Create a file upload field … … 352 389 } 353 390 391 392 /************************************************* 393 * 394 * Functions for adding publications to the study 395 * 396 ************************************************/ 397 398 /** 399 * Adds a publication to the study using javascript 400 * N.B. The publication must be added in grails when the form is submitted 401 */ 354 402 function addPublication( element_id ) { 355 403 /* Find publication ID and add to form */ … … 378 426 } 379 427 428 /** 429 * Removes a publication from the study using javascript 430 * N.B. The deletion must be handled in grails when the form is submitted 431 */ 380 432 function removePublication( element_id, id ) { 381 433 var ids = getPublicationIds( element_id ); … … 399 451 } 400 452 453 /** 454 * Returns an array of publications IDs currently attached to the study 455 * The array contains integers 456 */ 401 457 function getPublicationIds( element_id ) { 402 458 var ids = $( '#' + element_id + '_ids' ).val(); … … 413 469 } 414 470 471 /** 472 * Shows a publication on the screen 473 */ 415 474 function showPublication( element_id, id, title, authors, nr ) { 416 475 var deletebutton = document.createElement( 'img' ); … … 437 496 $( '#' + element_id + '_list' ).append( li ); 438 497 } 498 499 /** 500 * Creates the dialog for searching a publication 501 */ 502 function createPublicationDialog( element_id ) { 503 /* Because of the AJAX loading of this page, the dialog will be created 504 * again, when the page is reloaded. This raises problems when reading the 505 * values of the selected publication. For that reason we check whether the 506 * dialog already exists 507 */ 508 if( $( "." + element_id + "_publication_dialog" ).length == 0 ) { 509 $("#" + element_id + "_dialog").dialog({ 510 title : "Add publication", 511 autoOpen: false, 512 width : 800, 513 height : 400, 514 modal : true, 515 dialogClass : element_id + "_publication_dialog", 516 position: "center", 517 buttons : { 518 Add : function() { addPublication( element_id ); $(this).dialog("close"); }, 519 Close : function() { $(this).dialog("close"); } 520 }, 521 close : function() { 522 /* closeFunc(this); */ 523 } 524 }).width(790).height(400); 525 } else { 526 /* If a dialog already exists, remove the new div */ 527 $("#" + element_id + "_dialog").remove(); 528 } 529 } 530 531 /** 532 * Opens the dialog for searching a publication 533 */ 534 function openPublicationDialog( element_id ) { 535 // Empty input field 536 var field = $( '#' + element_id ); 537 field.autocomplete( 'close' ); 538 field.val( '' ); 539 540 // Show the dialog 541 $( '#' + element_id + '_dialog' ).dialog( 'open' ); 542 field.focus(); 543 544 // Disable 'Add' button 545 enableButton( '.' + element_id + '_publication_dialog', 'Add', false ); 546 } 547 548 /** 549 * Finds a button in a jquery dialog by name 550 */ 551 function getDialogButton( dialog_selector, button_name ) 552 { 553 var buttons = $( dialog_selector + ' .ui-dialog-buttonpane button' ); 554 for ( var i = 0; i < buttons.length; ++i ) 555 { 556 var jButton = $( buttons[i] ); 557 if ( jButton.text() == button_name ) 558 { 559 return jButton; 560 } 561 } 562 563 return null; 564 } 565 566 /** 567 * Enables or disables a button in a selected dialog 568 */ 569 function enableButton(dialog_selector, button_name, enable) 570 { 571 var dlgButton = getDialogButton( dialog_selector, button_name ); 572 573 if( dlgButton ) { 574 if (enable) { 575 dlgButton.attr('disabled', ''); 576 dlgButton.removeClass('ui-state-disabled'); 577 } else { 578 dlgButton.attr('disabled', 'disabled'); 579 dlgButton.addClass('ui-state-disabled'); 580 } 581 } 582 } 583 584 /************************************************* 585 * 586 * Functions for adding contacts to the study 587 * 588 ************************************************/ 589 590 /** 591 * Adds a contact to the study using javascript 592 * N.B. The contact must be added in grails when the form is submitted 593 */ 594 function addContact( element_id ) { 595 // FInd person and role IDs 596 var person_id = $( '#' + element_id + '_person' ).val(); 597 var role_id = $( '#' + element_id + '_role' ).val(); 598 599 var combination = person_id + '-' + role_id; 600 601 // Put the ID in the array, but only if it does not yet exist 602 var ids = getContactIds( element_id ); 603 if( $.inArray(combination, ids ) == -1 ) { 604 ids[ ids.length ] = combination; 605 $( '#' + element_id + '_ids' ).val( ids.join( ',' ) ); 606 607 // Show the title and a remove button 608 showContact( element_id, combination, $("#" + element_id + "_person :selected").text(), $("#" + element_id + "_role :selected").text(), ids.length - 1 ); 609 610 // Hide the 'none box' 611 $( '#' + element_id + '_none' ).css( 'display', 'none' ); 612 } 613 } 614 615 /** 616 * Removes a contact from the study using javascript 617 * N.B. The deletion must be handled in grails when the form is submitted 618 */ 619 function removeContact( element_id, combination ) { 620 var ids = getContactIds( element_id ); 621 if( $.inArray(combination, ids ) != -1 ) { 622 // Remove the ID 623 ids.splice($.inArray(combination, ids ), 1); 624 $( '#' + element_id + '_ids' ).val( ids.join( ',' ) ); 625 626 // Remove the title from the list 627 var li = $( "#" + element_id + '_item_' + combination ); 628 if( li ) { 629 li.remove(); 630 } 631 632 // Show the 'none box' if needed 633 if( ids.length == 0 ) { 634 $( '#' + element_id + '_none' ).css( 'display', 'inline' ); 635 } 636 637 } 638 } 639 640 /** 641 * Returns an array of studyperson IDs currently attached to the study. 642 * The array contains string formatted like '[person_id]-[role_id]' 643 */ 644 function getContactIds( element_id ) { 645 var ids = $( '#' + element_id + '_ids' ).val(); 646 if( ids == "" ) { 647 return new Array(); 648 } else { 649 ids_array = ids.split( ',' ); 650 651 return ids_array; 652 } 653 } 654 655 /** 656 * Shows a contact on the screen 657 */ 658 function showContact( element_id, id, fullName, role, nr ) { 659 var deletebutton = document.createElement( 'img' ); 660 deletebutton.className = 'famfamfam delete_button'; 661 deletebutton.setAttribute( 'alt', 'remove this person' ); 662 deletebutton.setAttribute( 'src', baseUrl + '/images/icons/famfamfam/delete.png' ); 663 deletebutton.onclick = function() { removeContact( element_id, id ); return false; }; 664 665 var titleDiv = document.createElement( 'div' ); 666 titleDiv.className = 'person' ; 667 titleDiv.appendChild( document.createTextNode( fullName ) ); 668 669 var authorsDiv = document.createElement( 'div' ); 670 authorsDiv.className = 'role'; 671 authorsDiv.appendChild( document.createTextNode( role ) ); 672 673 var li = document.createElement( 'li' ); 674 li.setAttribute( 'id', element_id + '_item_' + id ); 675 li.className = nr % 2 == 0 ? 'even' : 'odd'; 676 li.appendChild( deletebutton ); 677 li.appendChild( titleDiv ); 678 li.appendChild( authorsDiv ); 679 680 $( '#' + element_id + '_list' ).append( li ); 681 } 682
Note: See TracChangeset
for help on using the changeset viewer.