Changeset 483


Ignore:
Timestamp:
May 27, 2010, 10:55:53 AM (7 years ago)
Author:
roberth
Message:

Improved flexibility of the publication chooser and added comments

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/views/publication/add.gsp

    r479 r483  
    2121  <script type="text/javascript" src="${resource(dir: 'js', file: 'publication-chooser.js')}"></script>
    2222  <script type="text/javascript" src="${resource(dir: 'js', file: 'publication-chooser.pubmed.js')}"></script>
     23  <script type="text/javascript" src="${resource(dir: 'js', file: 'publication-chooser.programminglanguages.js')}"></script>
    2324
    2425 </head>
     
    2627
    2728 <g:form action="createFromPubmed">
    28   <g:textField name="publication" rel="publication-pubmed" />
     29  <g:textField name="publication" rel="publication-pubmed" style="width:300px;"/>
    2930  <g:submitButton name="add" value="Add publication" />
    3031 </g:form>
    31  
     32
     33
     34
    3235 ${errors}
    3336 ${message}
    3437
    3538 <script type="text/javascript">
    36         $(document).ready(function() {
    37           // initialize the ontology chooser
    38           var chooser = new PublicationChooser();
    39 
    40           chooser.init();
    41         });
     39$(document).ready(function() {
     40  // initialize the ontology chooser
     41  PublicationChooser.init();
     42});
    4243 </script>
    4344 </body>
  • trunk/web-app/js/publication-chooser.js

    r479 r483  
    1414 *
    1515 * Where the 'rel' value has the name 'publication' in the beginning. The text
    16  * after the dash is used for selecting the database to use. Currently, only
    17  * Pubmed is supported, that is also the default.
     16 * after the dash is used for selecting the database to use. Multiple textboxes
     17 * can be used on one page, also textboxes that search different databases.
     18 *
     19 * To initialize the textboxes, put the following javascript on the page.
     20 *
     21 *    PublicationChooser.init();
     22 *
     23 * The script must be executed AFTER all textboxes have been loaded. A good way
     24 * to achieve that is to run the init function in the document.ready event:
     25 *
     26 *    $(document).ready(function() {
     27 *        // initialize the publication chooser(s)
     28 *        PublicationChooser.init();
     29 *    });
     30 *
     31 * Supporting different databases:
     32 * ---------------------------
     33 * The databases that can be used are stored in the availableDBs arraymap. This
     34 * map consists of a key that describes the database to be used, and a value that
     35 * points to a function to be called when searching for the publications.
     36 *
     37 * As such, this class is not able to search any database. In order to make an
     38 * interface for a database, a new method has to be created that searches for
     39 * publications, and calls another method with  an array with strings or an
     40 * object array with label/value properties. This is described on
     41 * http://jqueryui.com/demos/autocomplete/#option-source
     42 *
     43 * The function for searching has the following form:
     44 *
     45 *     sourceExample = function( chooserObject, searchterm, response ) {
     46 *          response( [ 'result1', 'result2' ] );
     47 *     }
     48 *
     49 * The method takes the following parameters
     50 *
     51 *     chooserObject:  reference to the publicationChooser object itself
     52 *     searchterm:     string with the text that is entered in the textfield
     53 *     response:       reference to the function to be called when the results
     54 *                     have been fetched. The parameters are described above
     55 *
     56 * After the function has been created, it must be told to the publicationChooser
     57 * class.
     58 *
     59 *     PublicationChooser.prototype.availableDBs[ "example" ] = {
     60 *         'source': sourceExample
     61 *     };
     62 *
     63 * This line will provide the PublicationChooser class with the possibility to
     64 * search in the example database (<input rel="publication-example">), using the
     65 * function sourceExample. N.B. You can't use a dash in the name of the database
     66 * since that is used to separate different parts of the rel="" value.
     67 *
     68 * In order to do something with the selected result, two other methods can be
     69 * written;
     70 *
     71 *     selectExample = function( chooserObject, inputElement, event, ui ) {}
     72 *     closeExample = function( chooserObject, inputElement, event, ui ) {}
     73 *
     74 * The select method is calles when a user selects an item. The close method is
     75 * called when a user closes the dropdown, but did not select an item. The parameters
     76 * are:
     77 *
     78 *     chooserObject:  reference to the publicationChooser object itself
     79 *     inputElement:   reference to the input element
     80 *     event:          the event that has triggered the call. See http://docs.jquery.com/UI/Autocomplete#events
     81 *     ui:             the ui reference from jquery. If an item is selected,
     82 *                     ui.item contains a reference to that item. See http://docs.jquery.com/UI/Autocomplete#events
     83 *
     84 * In order to show the elements in the list, there is a render method. This method
     85 * accepts the item to be rendered, and returns an HTML string to be shown in the list
     86 *
     87 *     renderExample = function( item ) {}
     88 *
     89 * Of course, these methods must also be presented to the PublicationChooser object.
     90 *
     91 *     PublicationChooser.prototype.availableDBs[ "example" ] = {
     92 *         'source': sourceExample,
     93 *         'select': selectExample,
     94 *         'close':  closeExample,
     95 *         'render': renderExample
     96 *     };
     97 *
     98 * Example:
     99 * --------
     100 *
     101 *    sourceProgrammingLanguages = function( chooserObject, searchterm, response ) {
     102 *        var availableTags = ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl"];
     103 *        var foundTags = $.grep( availableTags, function( tag, i ){
     104 *            return ( tag.indexOf( searchterm ) !=-1 );
     105 *        } );
     106 *
     107 *        response( foundTags );
     108 *    }
     109 *
     110 *    selectProgrammingLanguages = function( chooserObject, inputElement, event, ui ) {
     111 *        alert( "Selected item: " + ui.item.value );
     112 *    }
     113 *
     114 *    closeProgrammingLanguages = function( chooserObject, inputElement, event, ui ) {
     115 *       alert( "No selected item" );
     116 *    }
     117 *
     118 *    renderProgrammingLanguages = function( item ) {
     119 *        return item.value;
     120 *    };
     121 *
     122 *    PublicationChooser.prototype.availableDBs[ "programminglanguages" ] = {
     123 *        'source': sourceProgrammingLanguages,
     124 *         'close' : closeProgrammingLanguages,
     125 *         'select': selectProgrammingLanguages,
     126 *        'render': renderProgrammingLanguages
     127 *     };
     128 *
     129 * Currently, only Pubmed is supported using publication-chooser.pubmed.js.
    18130 * Other database can easily be supported. See for example
    19131 * http://www.ncbi.nlm.nih.gov/bookshelf/br.fcgi?book=helpeutils&part=chapter2&rendertype=table&id=chapter2.chapter2_table1
     
    33145function PublicationChooser() {
    34146}
     147
     148/**
     149 * initialize object
     150 */
     151PublicationChooser.init = function() {
     152    // find all ontology elements
     153    $("input[rel*='publication']").each(function() {
     154        new PublicationChooser().initAutocomplete(this);
     155    });
     156};
     157
    35158PublicationChooser.prototype = {
    36159    minLength       : 3,        // minimum input length before launching Ajax request
     
    39162    database        : '',       // Default database to be used. As for now, also the only possible database
    40163    availableDBs    : {},       // Available databases, filled by extensions. Key is databasename and value is reference to method to be called
    41 
    42     /**
    43      * initialize object
    44      */
    45     init: function() {
    46         var that = this;
    47 
    48         // find all ontology elements
    49         $("input[rel*='publication']").each(function() {
    50             that.initAutocomplete(this);
    51         });
    52     },
    53 
     164   
    54165    /**
    55166     * initialize the ontology autocompleter
     
    72183        }
    73184
     185        // Initialize cache for this element
     186        this.cache[ this.database ] = [];
     187
    74188        // Put the autocomplete function on the input field. See jquery-ui
    75189        inputElement.autocomplete({
     
    78192
    79193            source: function(request, response) {
    80                         var q = $.trim(request.term);
    81 
    82                         // Check the cache first
    83                         if ( that.cache[ q ]) {
    84                             // yeah, lucky us! ;-P
    85                             response(that.cache[ q ]);
    86                         } else {
    87                             if( that.database != "" ) {
    88                                 that.availableDBs[ that.database ]( that, q, response );
    89                             }
    90                         }
     194                var q = $.trim(request.term);
     195
     196                // Check the cache first
     197                if ( that.cache[ that.database ][ q ]) {
     198                    // yeah, lucky us! ;-P
     199                    response(that.cache[ that.database ][ q ]);
     200                } else {
     201                    if( that.database != "" && that.availableDBs[ that.database ] && that.availableDBs[ that.database ][ 'source' ] ) {
     202                        that.availableDBs[ that.database ][ 'source' ]( that, q, response );
     203                    }
     204                }
     205            },
     206            search: function(event, ui ) {
     207                that.selected = false;
    91208            },
    92209            select: function(event, ui) {
    93210                // mark that the user selected a suggestion
    94                 selected = true;
    95 
    96                 // option selected, set hidden fields
    97                 var element = inputElement;
    98 
    99                 // set hidden fields
    100                 that.setInputValue(element, 'title', ui.item.title);
    101                 that.setInputValue(element, 'authorsList', ui.item.authors.join( ', ' ));
    102                 that.setInputValue(element, 'pubMedID', ui.item.id);
    103                 that.setInputValue(element, 'doi', ui.item.doi);
    104 
    105                 // remove error class (if present)
    106                 element.removeClass('error');
     211                that.selected = true;
     212
     213                if( that.database != "" && that.availableDBs[ that.database ] && that.availableDBs[ that.database ][ 'select' ] ) {
     214                    that.availableDBs[ that.database ][ 'select' ]( that, inputElement, event, ui );
     215                }
    107216            },
    108217            close: function(event, ui) {
    109                 // check if the user picked something from the ontology suggestions
    110                 if (!selected) {
    111                     // no he didn't, clear the field(s)
    112                     var element = inputElement;
    113 
    114                     // set fields
    115                     inputElement.val('');
    116                     that.setInputValue(element, 'title', '');
    117                     that.setInputValue(element, 'authorsList', '');
    118                     that.setInputValue(element, 'pubMedID', '');
    119 
    120                     // add error class
    121                     element.addClass('error');
     218                if( !that.selected ) {
     219                    if( that.database != "" && that.availableDBs[ that.database ] && that.availableDBs[ that.database ][ 'close' ] ) {
     220                        that.availableDBs[ that.database ][ 'close' ]( that, inputElement, event, ui );
     221                    }
    122222                }
    123223            }
    124224
    125         })
    126         .data( "autocomplete" )._renderItem = this.renderPublication;
     225        });
     226
     227        // Enable custom rendering if wanted. Otherwise use renderPublication method
     228        var renderMethod;
     229        if( this.database != "" && this.availableDBs[ that.database ] && this.availableDBs[ that.database ][ 'render' ] ) {
     230            renderMethod = this.availableDBs[ that.database ][ 'render' ];
     231        } else {
     232            renderMethod = this.renderPublication;
     233        }
     234
     235        inputElement.data( "autocomplete" )._renderItem = function( ul, item ) {
     236            return that.renderAutoCompleteText( ul, item, renderMethod( item ) );
     237        };
     238
    127239    },
    128240
    129     renderPublication: function( ul, item ) {
     241    /**
     242     * Renders a piece of text as a autocomplete menu item
     243     */
     244    renderAutoCompleteText: function( ul, item, text ) {
    130245        return $( "<li></li>" )
    131246                .data( "item.autocomplete", item )
    132                 .append( "<a>" + item.title + "<br><span style='font-size: 7pt;' class='authors'>" + item.authors.join( ', ' )+ "</span></a>" )
     247                .append( "<a>" + text + "</a>" )
    133248                .appendTo( ul );
     249    },
     250
     251    /**
     252     * Default rendering for publications in the autocomplete list
     253     */
     254    renderPublication: function( item ) {
     255        return item.title + "<br><span style='font-size: 7pt;' class='authors'>" + item.authors.join( ', ' )+ "</span>";
    134256    },
    135257
  • trunk/web-app/js/publication-chooser.pubmed.js

    r479 r483  
    2727                       
    2828                        // Save in cache
    29                         chooserObject.cache[ searchterm ] = parsedData;
     29                        chooserObject.cache[ chooserObject.database ][ searchterm ] = parsedData;
    3030
    3131                        // Return it to jquery
     
    3737
    3838};
     39
     40selectPubMed = function( chooserObject, inputElement, event, ui ) {
     41
     42    // option selected, set hidden fields
     43    var element = inputElement;
     44
     45    // set hidden fields
     46    chooserObject.setInputValue(element, 'title', ui.item.title);
     47    chooserObject.setInputValue(element, 'authorsList', ui.item.authors.join( ', ' ));
     48    chooserObject.setInputValue(element, 'pubMedID', ui.item.id);
     49    chooserObject.setInputValue(element, 'doi', ui.item.doi);
     50
     51    // remove error class (if present)
     52    element.removeClass('error');
     53};
     54closePubMed  = function( chooserObject, inputElement, event, ui ) {
     55    // no he didn't, clear the field(s)
     56    var element = inputElement;
     57
     58    // set fields
     59    inputElement.val('');
     60    chooserObject.setInputValue(element, 'title', '');
     61    chooserObject.setInputValue(element, 'authorsList', '');
     62    chooserObject.setInputValue(element, 'pubMedID', '');
     63    chooserObject.setInputValue(element, 'doi', '');
     64
     65    // add error class
     66    element.addClass('error');
     67};
     68
     69//renderPubMed = function( chooserObject, ul, item ) {};
    3970
    4071/**
     
    85116}
    86117
    87 PublicationChooser.prototype.availableDBs[ "pubmed" ] = sourcePubMed;
     118PublicationChooser.prototype.availableDBs[ "pubmed" ] = {
     119    'source': sourcePubMed,
     120    'select': selectPubMed,
     121    'close':  closePubMed
     122};
Note: See TracChangeset for help on using the changeset viewer.