Changeset 527


Ignore:
Timestamp:
Jun 4, 2010, 12:15:24 PM (13 years ago)
Author:
roberth
Message:

Adding of contacts is made possible in the study creation wizard.

Location:
trunk
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/studycapturing/PersonController.groovy

    r496 r527  
    4949    def possibleGenders = [ 'Male', 'Female' ]
    5050
     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
    5166    def index = {
    5267        redirect(action: "list", params: params)
     
    6681    def save = {
    6782        def personInstance = new Person(params)
     83        def extraparams = new LinkedHashMap();
     84
     85        if( params[ 'dialog' ] ) {
     86          extraparams[ 'dialog' ] = params[ 'dialog' ]
     87        }
     88
    6889        if (personInstance.save(flush: true)) {
    6990            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 )
    7193        }
    7294        else {
     
    99121    def update = {
    100122        def personInstance = Person.get(params.id)
     123
     124        def extraparams = new LinkedHashMap();
     125
     126        if( params[ 'dialog' ] ) {
     127          extraparams[ 'dialog' ] = params[ 'dialog' ]
     128        }
     129
    101130        if (personInstance) {
    102131            if (params.version) {
     
    112141            if (!personInstance.hasErrors() && personInstance.save(flush: true)) {
    113142                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)
    115144            }
    116145            else {
     
    120149        else {
    121150            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)
    123152        }
    124153    }
     
    127156        def personInstance = Person.get(params.id)
    128157
     158        def extraparams = new LinkedHashMap();
     159
     160        if( params[ 'dialog' ] ) {
     161          extraparams[ 'dialog' ] = params[ 'dialog' ]
     162        }
     163
    129164        if (personInstance) {
    130165            def personName = ( personInstance.firstName ? personInstance.firstName : "" ) + " " + ( personInstance.prefix ? personInstance.prefix : "" ) + " " + ( personInstance.lastName ? personInstance.lastName : "" );
     
    132167                personInstance.delete(flush: true)
    133168                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)
    135170            }
    136171            catch (org.springframework.dao.DataIntegrityViolationException e) {
    137172                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)
    139174            }
    140175        }
    141176        else {
    142177            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)
    144179        }
    145180    }
  • trunk/grails-app/controllers/dbnp/studycapturing/PersonRoleController.groovy

    r496 r527  
    4848    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
    4949
     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
    5065    def index = {
    5166        redirect(action: "list", params: params)
     
    6580    def save = {
    6681        def personRoleInstance = new PersonRole(params)
     82        def extraparams = new LinkedHashMap();
     83
     84        if( params[ 'dialog' ] ) {
     85          extraparams[ 'dialog' ] = params[ 'dialog' ]
     86        }
     87
    6788        if (personRoleInstance.save(flush: true)) {
    6889            flash.message = "${message(code: 'default.created.message', args: [message(code: 'personRole.label', default: 'Role'), personRoleInstance.name])}"
    6990            //redirect(action: "show", id: personRoleInstance.id)
    70             redirect(action: "list")
     91            redirect(action: "list", params: extraparams)
    7192        }
    7293        else {
     
    99120    def update = {
    100121        def personRoleInstance = PersonRole.get(params.id)
     122        def extraparams = new LinkedHashMap();
     123
     124        if( params[ 'dialog' ] ) {
     125          extraparams[ 'dialog' ] = params[ 'dialog' ]
     126        }
     127
    101128        if (personRoleInstance) {
    102129            if (params.version) {
     
    113140                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'personRole.label', default: 'Role'), personRoleInstance.name])}"
    114141                //redirect(action: "show", id: personRoleInstance.id)
    115                 redirect(action: "list")
     142                redirect(action: "list", params: extraparams)
    116143
    117144            }
     
    122149        else {
    123150            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)
    125152        }
    126153    }
     
    128155    def delete = {
    129156        def personRoleInstance = PersonRole.get(params.id)
     157        def extraparams = new LinkedHashMap();
     158
     159        if( params[ 'dialog' ] ) {
     160          extraparams[ 'dialog' ] = params[ 'dialog' ]
     161        }
     162
    130163
    131164        if (personRoleInstance) {
     
    134167                personRoleInstance.delete(flush: true)
    135168                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)
    137170            }
    138171            catch (org.springframework.dao.DataIntegrityViolationException e) {
    139172                flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'personRole.label', default: 'Role'), roleName])}"
    140173                // redirect(action: "show", id: params.id)
    141                 redirect(action: "list")
     174                redirect(action: "list", params: extraparams)
    142175            }
    143176        }
    144177        else {
    145178            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)
    147180        }
    148181    }
  • trunk/grails-app/controllers/dbnp/studycapturing/WizardController.groovy

    r526 r527  
    682682                }
    683683
    684                 // handle Publications
     684                // handle Publications and Contacts
    685685                handlePublications(flow, flash, params)
     686                handleContacts(flow, flash, params)
    686687
    687688                // validate study
     
    739740        }
    740741
    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        }
    742806        /**
    743807         * re-usable code for handling subject form data in a web flow
  • trunk/grails-app/domain/dbnp/studycapturing/Person.groovy

    r496 r527  
    4646 */
    4747
    48 class Person {
     48class Person implements java.io.Serializable {
    4949
    5050    String title
  • trunk/grails-app/domain/dbnp/studycapturing/PersonAffiliation.groovy

    r496 r527  
    4646 */
    4747
    48 class PersonAffiliation {
     48class PersonAffiliation implements java.io.Serializable {
    4949
    5050    String institute
  • trunk/grails-app/domain/dbnp/studycapturing/PersonRole.groovy

    r496 r527  
    4646 */
    4747
    48 class PersonRole {
     48class PersonRole implements java.io.Serializable {
    4949
    5050    String name
  • trunk/grails-app/domain/dbnp/studycapturing/StudyPerson.groovy

    r496 r527  
    4949 * Link table which couples studies with persons and the role they have within the study
    5050 */
    51 class StudyPerson {
     51class StudyPerson implements java.io.Serializable {
    5252    Person person
    5353    PersonRole role
  • trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy

    r519 r527  
    136136                // change form if a form attribute is present
    137137                if (attrs.get('form')) {
    138                         button = button.replaceFirst(/this\.form/,
     138                        // Old way
     139                        /*
     140                        button = button.replaceFirst(/this\.form/,
    139141                                "\\\$('" + attrs.get('form') + "')"
     142                        )
     143                        */
     144
     145                        button = button.replace("jQuery(this).parents('form:first')",
     146                                "\$('" + attrs.get('form') + "')"
    140147                        )
    141148                }
     
    10231030                out << '</form>';
    10241031                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 ); };'
    10251033                out << '  iField = $( "#' + attrs.get( 'name' ) + '" );';
    1026                 out << '  new PublicationChooser().initAutocomplete( iField );';
     1034                out << '  new PublicationChooser().initAutocomplete( iField, { "select" : onSelect } );';
    10271035                out << '</script>';
    10281036        }
     
    10671075                ids = '';
    10681076            }
    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">';
    10701078        }
    10711079
     
    10781086            out << '</div>';
    10791087            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 + '" );'
    10951089            out << '</script>';
    10961090
    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">';
    10981092        }
    10991093
     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        }
    11001224}
  • trunk/grails-app/views/person/create.gsp

    r496 r527  
    44    <head>
    55        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    6         <meta name="layout" content="main" />
     6        <meta name="layout" content="${layout}" />
    77        <g:set var="entityName" value="${message(code: 'person.label', default: 'Person')}" />
    88        <title><g:message code="default.create.label" args="[entityName]" /></title>
     
    114114                                </td>
    115115                            </tr>
    116                        
     116
    117117                            <tr class="prop">
    118118                                <td valign="top" class="name">
     
    123123                                </td>
    124124                            </tr>
    125                        
     125
    126126                        </tbody>
    127127                    </table>
    128128                </div>
    129129                <div class="buttons">
     130                   <g:each in="${extraparams}" var="param">
     131                     <input type="hidden" name="${param.key}" value="${param.value}">
     132                   </g:each>
    130133                   <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>
    132135                </div>
    133136            </g:form>
  • trunk/grails-app/views/person/edit.gsp

    r496 r527  
    44    <head>
    55        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    6         <meta name="layout" content="main" />
     6        <meta name="layout" content="${layout}" />
    77        <g:set var="entityName" value="${message(code: 'person.label', default: 'Person')}" />
    88        <title><g:message code="default.edit.label" args="[entityName]" /></title>
     
    3030                                  <label for="title"><g:message code="person.title.label" default="Title" /></label>
    3131                                </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')}">
    3333                                    <g:textField name="title" value="${personInstance?.title}" />
    3434                                </td>
     
    3939                                    <label for="gender"><g:message code="person.gender.label" default="Gender" /></label>
    4040                                </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')}">
    4242                                  <g:select name="gender" from="${possibleGenders}" noSelection="['' : 'Not specified']" value="${personInstance?.gender}" />
    4343                                </td>
     
    5151                                    <g:textField name="firstName" value="${personInstance?.firstName}" />
    5252                                </td>
    53                             </tr>
    54                        
    55                             <tr class="prop">
    5653                                <td valign="top" class="name">
    5754                                  <label for="initials"><g:message code="person.initials.label" default="Initials" /></label>
     
    6461                            <tr class="prop">
    6562                                <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">
    6669                                    <label for="prefix"><g:message code="person.prefix.label" default="Prefix" /></label>
    6770                                </td>
    6871                                <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'prefix', 'errors')}">
    6972                                    <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}" />
    8073                                </td>
    8174                            </tr>
     
    8578                                  <label for="address"><g:message code="person.address.label" default="Address" /></label>
    8679                                </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')}">
    8881                                    <g:textField name="address" value="${personInstance?.address}" />
    8982                                </td>
     
    9487                                    <label for="phone"><g:message code="person.phone.label" default="Work Phone" /></label>
    9588                                </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')}">
    9790                                    <g:textField name="phone" value="${personInstance?.phone}" />
    9891                                </td>
     
    10396                                    <label for="mobile"><g:message code="person.mobile.label" default="Mobile Phone" /></label>
    10497                                </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')}">
    10699                                    <g:textField name="mobile" value="${personInstance?.phone}" />
    107100                                </td>
     
    113106                                  <label for="fax"><g:message code="person.fax.label" default="Fax" /></label>
    114107                                </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')}">
    116109                                    <g:textField name="fax" value="${personInstance?.fax}" />
    117110                                </td>
     
    122115                                  <label for="email"><g:message code="person.email.label" default="Email" /></label>
    123116                                </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')}">
    125118                                    <g:textField name="email" value="${personInstance?.email}" />
    126119                                </td>
     
    131124                                  <label for="affiliations"><g:message code="person.affiliations.label" default="Affiliations" /></label>
    132125                                </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')}">
    134127                                    <g:select name="affiliations" from="${dbnp.studycapturing.PersonAffiliation.list()}" multiple="yes" optionKey="id" size="5" value="${personInstance?.affiliations}" />
    135128                                </td>
     
    140133                </div>
    141134                <div class="buttons">
     135                   <g:each in="${extraparams}" var="param">
     136                     <input type="hidden" name="${param.key}" value="${param.value}">
     137                   </g:each>
     138
    142139                    <span class="button"><g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" /></span>
    143140                    <span class="button"><g:actionSubmit class="cancel" action="show" value="Cancel" /></span>
  • trunk/grails-app/views/person/list.gsp

    r496 r527  
    44    <head>
    55        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    6         <meta name="layout" content="main" />
     6        <meta name="layout" content="${layout}" />
    77        <g:set var="entityName" value="${message(code: 'person.label', default: 'Person')}" />
    88        <title><g:message code="default.list.label" args="[entityName]" /></title>
     
    1919                        <tr>
    2020                       
    21                             <g:sortableColumn property="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')}" />
    2222                       
    23                             <g:sortableColumn property="prefix" title="${message(code: 'person.prefix.label', default: 'Prefix')}" />
     23                            <g:sortableColumn params="${extraparams}" property="prefix" title="${message(code: 'person.prefix.label', default: 'Prefix')}" />
    2424                       
    25                             <g:sortableColumn property="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')}" />
    2626
    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')}" />
    2829                       
    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>
    3032
    3133                            <th>Affiliations</th>
     
    4042                            <td>${fieldValue(bean: personInstance, field: "prefix")}</td>
    4143                       
    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>
    4345
    44                             <td>${fieldValue(bean: personInstance, field: "phone")}</td>
     46                            <g:if test="${layout!='dialog'}">
     47                              <td>${fieldValue(bean: personInstance, field: "phone")}</td>
    4548
    46                             <td>${fieldValue(bean: personInstance, field: "email")}</td>
     49                              <td>${fieldValue(bean: personInstance, field: "email")}</td>
     50                            </g:if>
    4751
    4852                            <td>
     
    5963            </div>
    6064            <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>
    6266            </div>
    6367            <div class="paginateButtons">
    64                 <g:paginate total="${personInstanceTotal}" prev="&laquo; Previous" next="&raquo; Next" />
     68                <g:paginate total="${personInstanceTotal}" prev="&laquo; Previous" next="&raquo; Next" params="${extraparams}" />
    6569            </div>
    6670
  • trunk/grails-app/views/person/show.gsp

    r496 r527  
    44    <head>
    55        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    6         <meta name="layout" content="main" />
     6        <meta name="layout" content="${layout}" />
    77        <g:set var="entityName" value="${message(code: 'person.label', default: 'Person')}" />
    88        <title><g:message code="default.show.label" args="[entityName]" /></title>
     
    110110                <g:form>
    111111                    <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>
    112115                    <span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span>
    113116                    <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>
    115118                </g:form>
    116119            </div>
  • trunk/grails-app/views/personRole/create.gsp

    r496 r527  
    44    <head>
    55        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    6         <meta name="layout" content="main" />
     6        <meta name="layout" content="${layout}" />
    77        <g:set var="entityName" value="${message(code: 'personRole.label', default: 'PersonRole')}" />
    88        <title><g:message code="default.create.label" args="['Role']" /></title>
     
    3838                </div>
    3939                <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>
    4245                </div>
    4346            </g:form>
  • trunk/grails-app/views/personRole/edit.gsp

    r496 r527  
    44    <head>
    55        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    6         <meta name="layout" content="main" />
     6        <meta name="layout" content="${layout}" />
    77        <g:set var="entityName" value="${message(code: 'personRole.label', default: 'PersonRole')}" />
    88        <title><g:message code="default.edit.label" args="['Role']" /></title>
     
    4040                </div>
    4141                <div class="buttons">
     42                     <g:each in="${extraparams}" var="param">
     43                       <input type="hidden" name="${param.key}" value="${param.value}">
     44                     </g:each>
    4245                    <span class="button"><g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" /></span>
    4346                    <span class="button"><g:actionSubmit class="cancel" action="list" value="Cancel" /></span>
  • trunk/grails-app/views/personRole/list.gsp

    r496 r527  
    44    <head>
    55        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    6         <meta name="layout" content="main" />
     6        <meta name="layout" content="${layout}" />
    77        <g:set var="entityName" value="${message(code: 'personRole.label', default: 'PersonRole')}" />
    88        <title><g:message code="default.list.label" args="['Role']" /></title>
     
    3030                            <td class="buttons">
    3131                              <g:form>
     32                                 <g:each in="${extraparams}" var="param">
     33                                   <input type="hidden" name="${param.key}" value="${param.value}">
     34                                 </g:each>
    3235                                  <g:hiddenField name="id" value="${personRoleInstance?.id}" />
    3336                                  <span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span>
     
    4144            </div>
    4245            <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>
    4447            </div>
    4548            <div class="paginateButtons">
    46                 <g:paginate total="${personRoleInstanceTotal}" prev="&laquo; Previous" next="&raquo; Next" />
     49                <g:paginate total="${personRoleInstanceTotal}" prev="&laquo; Previous" next="&raquo; Next" params="${extraparams}" />
    4750            </div>
    4851        </div>
  • trunk/grails-app/views/personRole/show.gsp

    r496 r527  
    44    <head>
    55        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    6         <meta name="layout" content="main" />
     6        <meta name="layout" content="${layout}" />
    77        <g:set var="entityName" value="${message(code: 'personRole.label', default: 'PersonRole')}" />
    88        <title><g:message code="default.show.label" args="['Role']" /></title>
     
    3232                <g:form>
    3333                    <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>
    3437                    <span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span>
    3538                    <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>
    3740                </g:form>
    3841            </div>
  • trunk/grails-app/views/wizard/common/_navigation.gsp

    r376 r527  
    2828// scriptable webflow action
    2929function 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" />
    3131}
    3232</script>
  • trunk/grails-app/views/wizard/pages/_study.gsp

    r526 r527  
    3030
    3131        <wizard:publicationSelectElement name="publication" value="${study?.publications}" />
     32        <wizard:contactSelectElement name="contacts" value="${study?.persons}" />
    3233
    3334</wizard:pageContent>
  • trunk/web-app/css/dialog.css

    r438 r527  
    2222}
    2323/* END :: ontology autocomplete */
     24
     25/* In a dialog, headers shoudn't be displayed, as the dialog itself has a title */
     26h1, 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 **/
     67table {
     68    border: 1px solid #ccc;
     69    width: 100%
     70}
     71tr {
     72    border: 0;
     73}
     74td, 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}
     81th {
     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}
     89th 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}
     96th.asc a, th.desc a {
     97    background-position: right;
     98    background-repeat: no-repeat;
     99}
     100th.asc a {
     101    background-image: url(../images/default_style/tables/sorted_asc.gif);
     102}
     103th.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
     114tr.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 */
     192td.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 */
     239option.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}
     247option.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}
     255option.locked {
     256    background: url(../images/icons/famfamfam/lock.png) no-repeat left top;
     257    padding-left: 18px;
     258}
     259option.unlocked {
     260    padding-left: 18px;
     261}
     262/* END :: special select option styles */
  • trunk/web-app/css/wizard.css

    r522 r527  
    349349}
    350350
    351 .wizard ul.publication_list {
     351.wizard ul.publication_list, .wizard ul.contact_list {
    352352    list-style-type: none;
    353353    margin: -10px 0 0 255px;
     
    355355}
    356356
    357 .wizard ul.publication_list li {
     357.wizard ul.publication_list li, .wizard ul.contact_list li {
    358358    margin-left: 0px;
    359359    padding: 4px 6px;
    360360}
    361361
    362 .wizard ul.publication_list li.even {
    363     background-color: #F0F0F0;
    364 }
    365 .wizard ul.publication_list li.odd {
    366     background-color: #F8F8F8;
    367 }
    368 
    369 .wizard ul.publication_list li .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; }
    370370.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  
    177177            var baseUrl = '..';
    178178        }
     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       
    179192        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();
    187203
    188204        // determine what database to use
     
    225241
    226242            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
    227254                var q = $.trim(request.term);
    228255
     
    230257                if ( that.cache[ that.database ][ q ]) {
    231258                    // yeah, lucky us! ;-P
    232                     response(that.cache[ that.database ][ q ]);
     259                    improvedResponse(that.cache[ that.database ][ q ]);
    233260                } else {
    234261                    if( that.database != "" && that.events[ 'source' ] ) {
    235                        that.events[ 'source' ]( that, q, response );
     262                       that.events[ 'source' ]( that, q, improvedResponse );
    236263                    }
    237264                }
     
    240267                that.selected = false;
    241268                $( '#' + inputElement.attr( 'id' ) + '_spinner' ).show();
     269                $( '#' + inputElement.attr( 'id' ) + '_notfound' ).hide();
    242270            },
    243271            open: function(event, ui ) {
    244272                $( '#' + inputElement.attr( 'id' ) + '_spinner' ).hide();
     273                $( '#' + inputElement.attr( 'id' ) + '_notfound' ).hide();
    245274            },
    246275            select: function(event, ui) {
  • trunk/web-app/js/publication-chooser.pubmed.js

    r518 r527  
    2525                        // Parse the response
    2626                        var parsedData = parsePubmedData( summaryResponse )
    27                        
     27
    2828                        // Save in cache
    2929                        chooserObject.cache[ chooserObject.database ][ searchterm ] = parsedData;
     
    8282 */
    8383function parsePubmedData(responseData) {
    84     var data = $("DocSum", responseData).map(function() {
     84    var data = [];
     85    data = $("DocSum", responseData).map(function() {
    8586            var title = $("Item[Name=Title]", this).text();
    8687            var authors = buildAuthorList( $("Item[Name=AuthorList]", this ) );
  • trunk/web-app/js/wizard.js

    r522 r527  
    6565        vars    : 'entity',
    6666        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...',
    6791        style   : 'modify',
    6892        onClose : function(scope) {
     
    287311}
    288312
     313
     314/*************************************************
     315 *
     316 * Functions for RelTime fields
     317 *
     318 ************************************************/
     319
    289320// Show example of parsed data next to RelTime fields
    290321function showExampleReltime(inputfield) {
     
    308339    });
    309340}
     341
     342/*************************************************
     343 *
     344 * Functions for file upload fields
     345 *
     346 ************************************************/
    310347
    311348// Create a file upload field
     
    352389}
    353390
     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 */
    354402function addPublication( element_id ) {
    355403  /* Find publication ID and add to form */
     
    378426}
    379427
     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 */
    380432function removePublication( element_id, id ) {
    381433    var ids = getPublicationIds( element_id );
     
    399451}
    400452
     453/**
     454 * Returns an array of publications IDs currently attached to the study
     455 * The array contains integers
     456 */
    401457function getPublicationIds( element_id ) {
    402458    var ids = $( '#' + element_id + '_ids' ).val();
     
    413469}
    414470
     471/**
     472 * Shows a publication on the screen
     473 */
    415474function showPublication( element_id, id, title, authors, nr ) {
    416475    var deletebutton = document.createElement( 'img' );
     
    437496    $( '#' + element_id + '_list' ).append( li );
    438497}
     498
     499/**
     500 * Creates the dialog for searching a publication
     501 */
     502function 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 */
     534function 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 */
     551function 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 */
     569function 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 */
     594function 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 */
     619function 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 */
     644function 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 */
     658function 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.