[MINITOC] ## Search via an external input field If you want to offer full-text search without invoking an entire anuraSearch, you can simply use an input field anywhere on the page. HTML: ```html ``` JS: ```js var gallery = $('#anura-gallery').anuraGallery({ /* ... your gallery settings ... */ }); $('#anura-search').on('keypress', function (e) { if (e.keyCode === 13) { // listen to "enter" gallery.anuraGallery({search: {string: $(this).val()}}); } }); ``` ## Change the sort order When not using anuraTable, you can still let the user decide the sort order via a simple ```select``` (for example). Please consult the main view documentation for available [sort options](/anura/frontend/mainview#sort). HTML: ```html ``` JS: ```js var gallery = $('#anura-gallery').anuraGallery({ /* ... your gallery settings ... */ }); $('#anura-sort-order').on('change', function (e) { gallery.anuraGallery({sort: $(this).val()}); }); ``` ## Change the language Here's an example for changing the presentation language. Suppose we have a dropdown like: HTML: ```html ``` ... then all we need to do is tell all of the loaded components to update their `loclae` option. They'll figure out the rest. JS: ```js var basket = $('#anura-basket').anuraBasket({ /* ... your basket settings ... */ }); var gallery = $('#anura-gallery').anuraGallery({ /* ... your gallery settings ... */ }); var search = $('#anura-search').anuraSearch({ /* ... your search settings ... */ }); // language selector $('#anura-locale').on('change', function (e) { var locale = $(this).val(); // tell the components to change their locale (keeping the other settings): basket.anuraBasket({locale: locale}); search.anuraSearch({locale: locale, initial_search: true /*does gallery as well*/}); }); ``` ## Display the total number of assets When you are using infini-scroll (a.k.a. pagination: 'auto'), it may be interesting to the user to know how many assets have been found in total, as this is only displayed in the paginator. Assuming that your display component looks something like ``, we can listen to the _anura-loaded-first_-event: ```js $('#anura-gallery').anuraGallery({ /* ... your gallery settings ... */ }).on('anura-loaded-first', function(e, options, total) { $('.anura-result-counter').text((total > 0)?(total+' Object'+(total > 1?'s':'')):'No matching objects found'); }); ``` ## Asset Marker (aka bullets) If you want to show some visual indicator on your assets (such as "copyright" or "internal use only"), you can add so-called Asset Markers: ![asset-marker](asset-marker.png) ### Simple example For starters, let's assume you only need this on the main view and only for one infofield: JS: ```js $('#anura-gallery').anuraGallery({ /* ... your gallery settings ... */ infofields: [108] // the information field(s) you need to load }).on('anura-loaded', function() { $('.anura-asset-container:not(.anura-info-processed)').each(function (index, item) { var asset = $(item), container = asset.find('.anura-image-container'); var markers = $('
').addClass('anura-asset-markers').appendTo(container); if (asset.data('asset-infofield-raw-108') === true) { // checkbox "copyright" $('').addClass('anura-asset-marker anura-asset-marker-copyright').appendTo(markers); } asset.addClass('anura-info-processed'); }); }); ``` CSS: ```css .anura-asset-marker-copyright { padding: 7px; position: absolute; background: white url("../img/copyright.png") no-repeat center center; bottom: 5px; left: 5px; border-radius: 100%; cursor: help; } ``` ### Complete example When you also need the asset marker in the basket, it's worth it to externalize the asset marker. Note that we're also using a second infofield to add context: ```js var assetMarker = function(asset, target) { if (!asset.hasClass('anura-info-processed')) { var markers = $('
').addClass('anura-asset-markers').appendTo(asset.find(target)); if (asset.data('asset-infofield-raw-108') === true) { $('').addClass('anura-asset-marker anura-asset-marker-copyright') .attr('title', asset.data('asset-infofield-110')).appendTo(markers); // note that there's always a '-raw' variant, i.e. asset-infofield-108 says "Yes", but asset-infofield-raw-108 says true } asset.addClass('anura-info-processed'); } }; var basket = $('#anura-basket').anuraBasket({ /* ... your basket settings ... */ infofields: [108, 110] // the information field(s) you need to load }).on('anura-asset-added', function (event, options, asset) { assetMarker($('#anura-basket-asset-'+asset), '.anura-basket-thumb-wrap'); // show the assets marker in the basket }); $('#anura-gallery').anuraGallery({ /* ... your gallery settings ... */ infofields: [108, 110] // the information field(s) you need to load }).on('anura-loaded', function() { $('.anura-asset-container').each(function (index, item) { assetMarker($(item), '.anura-image-container'); // show the asset markers in the main view }); }); ``` The CSS is the same as before. ## Add all to basket If you want to offer the ability to add all assets displayed in the main view to the basket, you'll need to include `jquery.anura.basket-add-all.js` and provide something to click on: ```html Add all () ``` Assuming that your main view is in a variable `view` and the basket is `basket`, use this after setting them up: ```js $('#anura-basket-add-all').anuraBasketAddAll({ mainView: view, basket: basket }); ``` ## Authenticating with a static token Simply define a global tokenProvider: ```js $.anura.tokenProvider = function () {return 'yourStaticTokenGoesHere';}; ``` ## Authenticating against CELUM If you are using the [anuraLoginTokenVerifier](/anura/backend#anura-1-tokenverifier) to protect Anura, the following provides an example of how you'd do that in the front-end: ### Take first endpoint ```js $(document).ready(function () { var baseUrl = 'http://your.celum.server/'; var locale = 'en'; // login and token handling: $.anura.onRequestFailure = function(response) { // access denied -> go to login (either for the first time or to refresh the token) if (response && response.status === 403) window.location.href = baseUrl + 'anuraLoginToken/login?to=' + encodeURIComponent(window.location.href); } $.anura.tokenProvider = function() { // where the other anura components get their token from var token, variables = window.location.search.substring(1).split('&'); for (var i = 0; i < variables.length; i++) { // get return variables from login var param = variables[i].split('='); switch (param[0]) { case 'token': token = param[1]; break; case 'endpoint': sessionStorage.setItem('endpoint', param[1]); break; } } if (token) { // new token -> store it sessionStorage.setItem('token', token); history.replaceState('', document.title, window.location.href.replace(/[?&](token|endpoint)=[^&#]*/g, '')); } else { // get existing token from storage token = sessionStorage.getItem('token'); if (token == null) window.location.href = baseUrl + 'anuraLoginToken/login?to=' + encodeURIComponent(window.location.href); } return token; }; $.anura.tokenProvider(); // run once straight at the beginning (in order to get a token) var endpoint = sessionStorage.getItem('endpoint') || 'default'; // dynamic endpoint, or a default one (called 'default' here) var server = baseUrl + 'anura/' + endpoint, locale = 'en'; // base settings // other anura components as usual: var basket = $('#anura-basket').anuraBasket({server: server, locale: locale}); $('#anura-gallery').anuraGallery({ // initialize an empty gallery on server: server, locale: locale, detail_view: 'slimbox', basket: basket }); $('#anura-tree').anuraTree({ // initialize a tree on
server: server, locale: locale, node: {kind: 105, id: 71}, // folder with ID 1337 //show_root: true, show: true // show the first sub-folder in the gallery by default }); }); ``` ### Take all endpoints ```js $(document).ready(function () { const baseUrl = 'http://localhost:8881/', locale = 'en' // login and token handling: $.anura.onRequestFailure = function(response) { // access denied -> go to login (no token or expired) if (response && response.status === 403) window.location.href = baseUrl + 'anuraLoginToken/login?to=' + encodeURIComponent(window.location.href) } $.anura.tokenProvider = function() { // where the other anura components get their token from let token, endpoints = []; const searchParams = Array.from(new URL(window.location.href).searchParams); // ?key1=value1&key2=value2 => [[key1, value1],[key2,value2]] for (const param of searchParams) { // get return variables from login switch (param[0]) { case 'token': token = param[1]; break; case 'endpoint': endpoints.push(param[1]); break; } } if (token) { // new token -> store it sessionStorage.setItem('token', token); sessionStorage.setItem('endpoints', endpoints.join(',')); // remove params from url history.replaceState('', document.title, window.location.href.replace(/[?&](token|endpoint)=[^&#]*/g, '')); } else { // get existing token from storage token = sessionStorage.getItem('token'); if (token == null) window.location.href = baseUrl + 'anuraLoginToken/login?to=' + encodeURIComponent(window.location.href); } return token; } $.anura.tokenProvider() // run once straight at the beginning (in order to get a token) // let the user select an endpoint or like here just take the first one automatically const endpoint = sessionStorage.getItem('endpoints').split(',')[0] || 'default', // dynamic endpoint, or a default one (called 'default' here) server = baseUrl + 'anura/' + endpoint // other anura components as usual: const basket = $('#anura-basket').anuraBasket({server: server, locale: locale}) $('#anura-gallery').anuraGallery({ // initialize an empty gallery on server: server, locale: locale, detail_view: 'slimbox', basket: basket }) $('#anura-tree').anuraTree({ // initialize a tree on
server: server, locale: locale, node: {kind: 105, id: 71}, // folder with ID 1337 //show_root: true, show: true // show the first sub-folder in the gallery by default }) }) ```