Changeset 527 for trunk/web-app


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

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

Location:
trunk/web-app
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • 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.