mehmetc / jQuery.PRIMO

A client side convenience library for PRIMO.
MIT License
27 stars 8 forks source link

jQuery.PRIMO

The missing model for PRIMO v4.9 and better.
This is a work in progress! If you want a feature, have a comment, found a bug you can:

See the releases for downloads and release notes

WARNING

jQuery.PRIMO.js is intended to be used with a vanilla(unchanged) view. You might not get the intended experience if you changed/removed/renamed class names, id's etc.

Contact me if you are experiencing problems. Installation

From February 2016 this will be a part of the general Primo release cycle. But if you have server access you can install it yourself.

jQuery.PRIMO exists of 2 parts:

Install and setup

That is it.

I also created 3 screencasts(no audio) as a guide.

Installing jQuery.PRIMO

Setup jQuery.PRIMO.js

Or if you want to isolate jQuery.PRIMO.

Setup jQuery.PRIMO.js

Just for testing

You can inject the script into your results page, for testing. This works best using Firefox. Open the JavaScript console and paste the next line. You will not be able to use the more advanced functions but it should give you an idea of what it can be used for.

    $.getScript('https://cdn.rawgit.com/mehmetc/jQuery.PRIMO/4a091fc5/dist/jQuery.PRIMO.min.js')

Browsers are getting stricter with every release. If you get strange errors just copy the complete source into your console.

Compilation (TODO)

If you would want to compile jquery.PRIMO.js then follow these steps

Exposed model

jQuery.PRIMO Object Model

Examples

Objects

MISC

Version of jQuery.PRIMO library

    jQuery.PRIMO.version;

Reload jQuery.PRIMO

    jQuery.PRIMO.reload();

SESSION

Some functions and attributes will only be available when jQuery.PRIMO.jar is installed on the server. Otherwise it will load a minimum of session data from the default getUserInfoServlet service.

Get the session id

    jQuery.PRIMO.session.sessionId;

Reload session data

    jQuery.PRIMO.session.reload();

USER

Read the current sessions user id

    jQuery.PRIMO.session.user.id;    

Read the current session user name

    jQuery.PRIMO.session.user.name;            

Read the current session user email

    jQuery.PRIMO.session.user.email;            

Check if the current user is logged in

    jQuery.PRIMO.session.user.isLoggedIn();    

Check if the current user is on campus

    jQuery.PRIMO.session.user.isOnCampus();    

Get the Personalized Ranking Categories

    jQuery.PRIMO.session.user.ranking.categories;

Get the Personalized Ranking 'Prefer newer material' value

    jQuery.PRIMO.session.user.ranking.prefer_new;

VIEW

Get the current view code

    jQuery.PRIMO.session.view.code;

Get the current view's institution name

    jQuery.PRIMO.session.view.institution.name;

Get the current view's institution code

    jQuery.PRIMO.session.view.institution.code;

Get the current view's interface language

    jQuery.PRIMO.session.view.interfaceLanguage;

Is the current view in full display mode

    jQuery.PRIMO.session.view.isFullDisplay();    

Get the current view frontend id

This is the hashCode() of the machines hostname. It is usefull for debugging or if you want a feature to only work on for example your staging enviroment.

    jQuery.PRIMO.session.view.frontEndID;    

IP

Get IP address as seen on PRIMO

    jQuery.PRIMO.session.ip.address;

Get institution name by IP

    jQuery.PRIMO.session.ip.institution.name;

Get institution code by IP

    jQuery.PRIMO.session.ip.institution.code;

PDS

When you are logged in you will get the bor-info from PDS. It serializes the xml into json.

Get the url for PDS

    jQuery.PRIMO.session.pds.url;

Get PDS Handle (only available after login)

    jQuery.PRIMO.session.pds.handle;

GET borrower info Object from PDS.

    jQuery.PRIMO.session.pds.borInfo;

PERFORMANCE

Only available if the browser supports it. Be careful the getPageLoad and getPageRender methods are non blocking. This means they will only return sain values after the page is completely loaded and rendered.

Timing

Get timing for Network latency

    jQuery.PRIMO.session.performance.timing.getNetworkLatency();

Get timing for Page Load

    jQuery.PRIMO.session.performance.timing.getPageLoad();

Get timing for Page Render

    jQuery.PRIMO.session.performance.timing.getPageRender();

RECORDS

Extends the DOM.

Get number of records on screen (this is an Array)

    jQuery.PRIMO.records.length;

Get the record id of the 6th field

    jQuery.PRIMO.records[5].id;    

Get the record index

    jQuery.PRIMO.records[5].index;    

Get title of 6th record

    jQuery.PRIMO.records[5].title;    

Get OpenUrl of 6th record

    jQuery.PRIMO.records[5].openUrl;

Get type of 6th record

    jQuery.PRIMO.records[5].materialType();

Get getIt1 of 6th record

    jQuery.PRIMO.records[5].getIt1();

Is the 6th record a remote record

    jQuery.PRIMO.records[5].isRemoteRecord();

Is the 6th record on the eShelf

    jQuery.PRIMO.records[5].isOnEShelf();

Get the PNX data as text,json,xml of the 6th record

    jQuery.PRIMO.records[5].getPNX('text');
    jQuery.PRIMO.records[5].getPNX('json');
    jQuery.PRIMO.records[5].getPNX();    

Get the material type of the first record

    jQuery.PRIMO.records[0].getData().display.type;

Check if 6th record was deduped

    jQuery.PRIMO.records[5].isDedupedRecord();

Get all record ids for a deduped record

    jQuery.PRIMO.records[2].getDedupedRecordIds();

Highlight all journals on screen

      jQuery.PRIMO.records.each(
        function(){ 
            if (this.getData().display.type === 'journal') {
                this.css('background-color', 'yellow')
            } 
        }
      ); 

Make the 'View Online' tab popout

    jQuery.PRIMO.records.each(
        function(index, record){
            var view_online = record.tabs.getByName('ViewOnline');
            try{
                view_online.find('a').attr('target', '_blank').attr('href', record.getIt1);                          
            } catch (e) {
                console.log('Error setting url');
            }
        }
    );    

FACETS

Extends the DOM.

Get all facet names

    jQuery.PRIMO.facets.getNames();

Get facet by name

    jQuery.PRIMO.facets.getByName('facet_lang')

Get title for a facet by name

_facetlang is the technical name. Title will return the screen name. The screen name depends on the view language.

    jQuery.PRIMO.facets.getByName('facet_lang').title

Get ALL value objects for facet_lang

    jQuery.PRIMO.facets.getByName('facet_lang').values

Get ALL values for first facet

    jQuery.map(jQuery.PRIMO.facets[0].values, function(f,i){return f.value})

Get FIRST value for facet_lang

    jQuery.PRIMO.facets.getByName('facet_lang').values[0].value

Get number of hits for FIRST facet of facet_lang

    jQuery.PRIMO.facets.getByName('facet_lang').values[0].count

TABS

Extends the DOM.

Add a new tab to all records

      jQuery.PRIMO.records.each(
        function(index, record){
          record.tabs.addTab('HelloTab',{
            label: 'Hello World',
            state:'enabled', 
            click:function(event, tab, record, options){
                    if (tab.isOpen()){
                        tab.close();
                    } else {
                        tab.open('Hello from tab', {reload:true});
                    }
                  } 
          });          
        }
      );

Add a new share tab and make the sendTo tab appear.

    jQuery.PRIMO.records.each(
        function(index, record){
            record.tabs.addTab('ShareTab', {label: 'Share',tooltip:'Share', state:'enabled', click:function (event, tab, record, options) {
                if (tab.isOpen()) {
                    tab.close();
                } else {
                    var tab_content = "";
                    var details_url = $(record.tabs).filter('.EXLDetailsTab').find('a').attr('href');

                    tab_content += "<div style='overflow:auto;height:100%;padding:20px;'>";
                    tab_content += '  <div class="share_options_import"></div>';
                    tab_content += '</div>';

                    $.get(details_url,
                        function(data){
                            var html = $($.parseHTML(data)).find('.EXLTabHeaderButtonSendToList li');
                            var permalink = html.filter('.EXLButtonSendToPermalink').length == 0 ? false : true;
                            var citation = html.filter('.EXLButtonSendToCitation').length == 0 ? false : true;

                            if (permalink) {
                                html.filter('.EXLButtonSendToPermalink').find('a').attr('onclick', html.filter('.EXLButtonSendToPermalink').find('a').attr('onclick').replace(/-1/g, record.index));
                            }

                            if (citation){
                                html.filter('.EXLButtonSendToCitation').find('a').attr('onclick', html.filter('.EXLButtonSendToCitation').find('a').attr('onclick').replace(/-1/g, record.index));
                            }

                            $('.share_options_import').empty().append(html);

                            eshelfUpdate(record.children(), record.isOnEShelf());
                        }, 'html'
                    );

                    details_url = 'http://' + location.hostname + location.pathname.substr(0, location.pathname.lastIndexOf('/')) + '/display.do?tabs=detailsTab&ct=display&fn=search&doc=' + record.id + "&recIds=" + record.id;

                    tab.open(tab_content, {reload:false, url:details_url});
                }
            }
        });
       }
    );                

Open an URL in the tab of the first record

    jQuery.PRIMO.records[0].tabs.addTab('KULeuvenTab', {label: 'KULeuven', 
                                                        state:'enabled',
                                                        url:'http://www.kuleuven.be',
                                                        click:function(event, tab, record, options) {
                                                            if (tab.isOpen()) {
                                                                tab.close();
                                                            } else {
                                                                tab.open('<iframe src="https://github.com/mehmetc/jQuery.PRIMO/raw/master/'+options.url+'"/>', {reload: true});
                                                            }
                                                        }
                                                       });      

Open the URL in a new window. Works as a normal link.

       jQuery.PRIMO.records[1].tabs.addTab('UrlTab', {label: 'Url', 
                                                      state:'enabled',
                                                      url:'http://www.kuleuven.be', url_target: '_blank',
                                                      click: null
                                                     }); 

Get all tab names for the 6th record

    jQuery.PRIMO.records[5].tabs.getNames();

Get all active tabs

    jQuery.PRIMO.records[5].tabs.getEnabled();

Get the details tab by name

    jQuery.PRIMO.records[5].tabs.getByName('DetailsTab');

Programmatically click on a tab

    jQuery.PRIMO.records[0].tabs.getByName('DetailsTab').find('a').click();

Get the link behind the details tab

    jQuery.PRIMO.records[5].tabs.getByName('DetailsTab').find('a').attr('href');

Get the name of the first tab

    jQuery.PRIMO.records[5].tabs[0].name;    

Get the index of the first tab

    jQuery.PRIMO.records[5].tabs[0].index;

Get the container of the second tab

   jQuery.PRIMO.records[5].tabs[1].container;

Check if tab is open

    jQuery.PRIMO.records[5].tabs[4].isOpen();

SEARCH

Wraps the default XServices API this means that 'WS and XS IP' restrictions apply Wraps the default REST API

The results returned by the different API's are not compatible(feel free to fork and change) you can not switch between them without rewriting your code that consumes the search result.  
function byQuery(query, options)

query: can be a string or an array options: can be one of

    regionURL is one of:
        * America   https://api-na.hosted.exlibrisgroup.com
        * EU        https://api-eu.hosted.exlibrisgroup.com
        * APAC      https://api-ap.hosted.exlibrisgroup.com    

search for water (XServices)

    var result = jQuery.PRIMO.search.byQuery('any,contains,water');

search for water in title and pollution in subject return 100 records starting from position 10 on the result set. (XServices)

    var result = jQuery.PRIMO.search.byQuery(['title,contains,water', 'subject,contains,pollution'], {"index":10, "bulkSize":100});

search for water and return 5 records when locally hosted (REST)

    var result = jQuery.PRIMO.search.byQuery('any,contains,water', {"restAPI":true, "bulkSize":5});

search for water when hosted by ExLibris Developers Network (REST)

    var result = jQuery.PRIMO.search.byQuery("any,contains,water", {"restAPI":true,"apiKey":"1234567890", "regionURL": "https://api-na.hosted.exlibrisgroup.com"})

QUERY

Parses the URL and scrapes the DOM for data.

Get result set count

   jQuery.PRIMO.query.count;

Get current page number

    jQuery.PRIMO.query.page;

Get number of records on page

    jQuery.PRIMO.query.step;

should be equal to

    jQuery.PRIMO.records.length;

Get search type basic/advanced

    jQuery.PRIMO.query.type;

Get search tab (search scope)

    jQuery.PRIMO.query.tab;

Get search sort

    jQuery.PRIMO.query.sorted_by;

Get query

This will return an Array of Object parsed from the URL not the DOM The Object contains the index, precision and term.

    jQuery.PRIMO.query.query;

contains

    [
        {
         "index":"any",
         "precision":"contains",
         "term":"perceval"
        }
    ]

Get query as text (like the xService syntax)

    jQuery.PRIMO.query.query.toText();

returns

    (any contains perceval)

Get search scope

    jQuery.PRIMO.query.scope;

Get facets

    jQuery.PRIMO.query.facets;

Is this a dlSearch.do search?

    jQuery.PRIMO.query.isDeeplinkSearch();

Rendering HTML using templates

    jQuery('body').append(jQuery.PRIMO.template.render('<div> Hello, {{who}}</div>', {who: 'world'}));

You can create templates using the script tag

    <script type='text/template' id='helloWorld-tpl'>
        <div>Hello {{who}}</div>
    </script>

and use them in your javascript

    <script type='text/javascript'>
        jQuery('body').append(jQuery.PRIMO.template.renderById('helloWorld-tpl', {who: 'world'}));
    </script>    

Print all titles using a template

Loop over all records and print title

   <script type='text/template' id='allTitles-tpl'>
       <div id="allTitles">
            <ol>
                {{ for(var i=0;i<records.length;i++){ }}
                    <li>{{ records[i].title }}</li>
                {{ } }}
            </ol>       
       </div>
   </script> 

Render the allTitles template and append it to the body

    <script type='text/javascript'>
        jQuery('body').append(jQuery.PRIMO.template.renderById('allTitles-tpl', {records: $.PRIMO.records}));
    </script>    

Add a search tab to Google Scolar (for simple search)

Idea by Lukas Koster

Template to add extra Search Scope Tab

<script type='text/template' id='searchTab-tpl'> 
    <li class="EXLSearchTab" id="{{id}}">
      <a href="https://github.com/mehmetc/jQuery.PRIMO/blob/master/{{href}}" title="{{description}}" target="{{target}}">
        <span>{{label}}</span>
      </a>
    </li>
</script>

Render the template using some variables

<script type='text/javascript'>
    var query = jQuery.PRIMO.query.query.map(function(d){return d.term}).join(" ");
    var renderedTemplate = jQuery.PRIMO.template.renderById('searchTab-tpl',
                        {id: 'exlidTabGoogleScolar',
                        label: 'Google Scholar',
                        description: 'Perform search on Google Scholar',
                        href:'http://scholar.google.com/scholar?as_q=' + query,                                 
                        target:'_blank'});

    jQuery('#exlidSearchTabs').append(renderedTemplate);
</script>

Events & Callbacks

!!This is experimental might change in the future.

tabReady CALLBACK

When a tab is done loading a tabReady callback is fired. You can attach a callback function to a tab that gets executed when the tab content is loaded.

Add the record id to the details tab when opened.

    $.each($.PRIMO.records, function(i, record){
        record.tabs.getByName('DetailsTab')[0].onTabReady = function(record, container, tab){
            $($(container.tabUtils.tabContent).find('.EXLDetailsContent ul')[0]).prepend("<li><strong>Record id:</strong><span class='EXLDetailsDisplayVal'>" + record.id + "</span></li>");
        }
    });

Contributing to jQuery.PRIMO

License

MIT (c) 2015 KULeuven/LIBIS written by Mehmet Celik