/***** Created by Terje Rudi, HVL, 2017 *****/ function domReady () { // JQUERY ready-alternative - det blir ingen feil dersom denne funksjonen gjentas document.body.className += " javascript"; //... } function isNotVal(val){ // brukes til sjekking om verdi har innhold og/eller er gyldig return (val==null || val===false); } // Mozilla, Opera, Webkit if ( document.addEventListener ) { document.addEventListener( "DOMContentLoaded", function(){ document.removeEventListener( "DOMContentLoaded", arguments.callee, false); domReady(); // <- kan brukes ute i html-doc }, false ); // If IE event model is used (Explorer 8...) } else if ( document.attachEvent ) { // ensure firing before onload document.attachEvent("onreadystatechange", function(){ if ( document.readyState === "complete" ) { document.detachEvent( "onreadystatechange", arguments.callee ); domReady(); // <- kan brukes ute i html-doc } }); } // AJAX var AJAXerrors = { "0":"Unknown Error", "100":"Continue", "101":"Switching Protocol", "103":"Processing (WebDAV)", "200":"OK", "201":"Created", "202":"Accepted", "203":"Non-Authoritative Information", "204":"No Content", "205":"Reset Content", "206":"Partial Content", "207":"Multi-Status (WebDAV)", "208":"Multi-Status (WebDAV)", "226":"IM Used (HTTP Delta encoding)", "300":"Multiple Choice", "301":"Moved Permanently", "302":"Found", "303":"See Other", "304":"Not Modified", "305":"Use Proxy ", "306":"unused", "307":"Temporary Redirect", "308":"Permanent Redirect", "400":"Bad Request", "401":"Unauthorized", "402":"Payment Required", "403":"Forbidden", "404":"Not Found", "405":"Method Not Allowed", "406":"Not Acceptable", "407":"Proxy Authentication Required", "408":"Request Timeout", "409":"Conflict", "410":"Gone", "411":"Length Required", "412":"Precondition Failed", "413":"Payload Too Large", "414":"URI Too Long", "415":"Unsupported Media Type", "416":"Requested Range Not Satisfiable", "417":"Expectation Failed", "418":"I'm a teapot", "421":"Misdirected Request", "422":"Unprocessable Entity (WebDAV)", "423":"Locked (WebDAV)", "424":"Failed Dependency (WebDAV)", "426":"Upgrade Required", "428":"Precondition Required", "429":"Too Many Requests", "431":"Request Header Fields Too Large", "451":"Unavailable For Legal Reasons", "500":"Internal Server Error", "501":"Not Implemented", "502":"Bad Gateway", "503":"Service Unavailable", "504":"Gateway Timeout", "505":"HTTP Version Not Supported", "506":"Variant Also Negotiates", "507":"Insufficient Storage", "508":"Loop Detected (WebDAV)", "510":"Not Extended", "511":"Network Authentication Required" } function makeRequest(url,callback,ref,callbackExstraArgsObj) { // AJAX-kall if (typeof callback != "undefined"){ var req = new XMLHttpRequest(); if (!req) { alert('Gir opp :( XMLHTTP instance not created -1'); return false; } req.onreadystatechange = function(){ try { if (req.readyState === XMLHttpRequest.DONE) { if (req.status !== 200) { try { console.log('En feil oppstod: ' + AJAXerrors[req.status] + ' (' + req.status + ')'); }catch (e){ console.log('Det var et problem med å hente data. Feilkode: ' + req.status); } }else{ try{ if (callbackExstraArgsObj && typeof callbackExstraArgsObj == "object"){ callback(req.responseText,callbackExstraArgsObj); }else{ callback(req.responseText); } }catch(e){ try { console.log('En feil oppstod [-1]: ' + e + ' (Melding: ' + AJAXerrors[req.status] + ' (sjekk callback))'); }catch (f){ console.log('Kunne ikke aktivere callback: ' + e + ' (Status: ' + req.status + ')'); } } } } }catch( e ) { console.log('Opplevde et unntak: ' + e.description); } }; req.open('GET', url); req.send(); }else{ console.log("Callback undefinert i 'makeRequest', referanse: " + ref); } } function postJson(url,json,callback,ref,callbackExstraArgsObj) { // Sendes som btoa (base64) // AJAX-kall if (typeof callback != "undefined"){ var req = new XMLHttpRequest(); if (!req) { alert('Gir opp :( XMLHTTP instance not created -2'); return false; } req.onreadystatechange = function(){ try { if (req.readyState === XMLHttpRequest.DONE) { if (req.status !== 200) { try { console.log('En feil oppstod: ' + AJAXerrors[req.status]); }catch (e){ console.log('Det var et problem med å hente data. Feilkode: ' + req.status); } }else{ try{ if (callbackExstraArgsObj && typeof callbackExstraArgsObj == "object"){ callback(req.responseText,callbackExstraArgsObj); }else{ callback(req.responseText); } }catch(e){ try { console.log('En feil oppstod [-2]: ' + e + ' (Melding: ' + AJAXerrors[req.status] + ', Callback = ' + JSON.stringify(callback) + ')'); }catch (f){ console.log('Kunne ikke aktivere callback: ' + e + ' (Status: ' + req.status + ')'); } } } } }catch( e ) { console.log('Opplevde et unntak: ' + e.description); } }; req.open("POST", url); var params = "btoajson=" + btoa(JSON.stringify(json)); //Send the proper header information along with the request req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); //req.setRequestHeader("Content-length", params.length); //req.setRequestHeader("Connection", "close"); req.send(params); }else{ console.log("Callback undefinert i 'makeJSONpostRequest', referanse: " + ref); } } function addCSSRule(sheet, selector, rules, index) { return true; /* FASET UT try{ if("insertRule" in sheet) { sheet.insertRule(selector + "{" + rules + "}", index); }else if("addRule" in sheet) { sheet.addRule(selector, rules, index); } }catch(e){ console.log("FEIL ved innsetting av i stilark: " + e + ". Sheet = " + sheet + " Selector = " + selector + " Index = " + index); } */ } // SlideUp SlideDown SlideToggle /* Element to slide gets the following CSS: max-height: 0;opacity: 0;overflow: hidden;transition: max-height 0.4s ease 0s; */ function slideElemDown(elem) { elem.style.maxHeight = '1000px'; // We're using a timer to set opacity = 0 because setting max-height = 0 doesn't (completely) hide the element. elem.style.opacity = '1'; } function slideElemUp(elem) { elem.style.maxHeight = '0'; once( 1, function () { elem.style.opacity = '0'; }); } function slideElemToggle(elem){ if (elem.style.opacity == 1){ slideElemUp(elem); }else{ slideElemDown(elem); } } function once (seconds, callback) { var counter = 0; var time = window.setInterval( function () { counter++; if ( counter >= seconds ) { callback(); window.clearInterval( time ); } }, 400 ); } // Sliding ferdig /* UTFASET // direkte manipulering av stilark for HVL-Bouvet-stil try{ // Fjerne dobbel ned-pil i Explorer i rullegardinmeny: addCSSRule(document.styleSheets[0],'select::-ms-expand','display: none',0); // Sette inn spinner addCSSRule(document.styleSheets[0],'@-webkit-keyframes rwSpinnerRotate','{-webkit-transform:rotate(0deg);}to{-webkit-transform:rotate(360deg);}',document.styleSheets[0].cssRules.length); addCSSRule(document.styleSheets[0],'@-moz-keyframes rwSpinnerRotate','{-moz-transform:rotate(0deg);}to{-moz-transform:rotate(360deg);}',document.styleSheets[0].cssRules.length); addCSSRule(document.styleSheets[0],'@-ms-keyframes rwSpinnerRotate','{-ms-transform:rotate(0deg);}to{-ms-transform:rotate(360deg);}',document.styleSheets[0].cssRules.length); addCSSRule(document.styleSheets[0],'@keyframes rwSpinnerRotate','{transform:rotate(0deg);}to{transform:rotate(360deg);}',document.styleSheets[0].cssRules.length); addCSSRule(document.styleSheets[0],'.rwSpin','position:relative;top:0.3rem;left:0.3rem;padding: 0.2rem;color: #fff;width: 0.6rem;height: 0.6rem;background: #acb7b2;border-radius: 0.6rem;-webkit-animation-name: rwSpinnerRotate;-webkit-animation-duration: 0.8s;-webkit-animation-iteration-count: infinite;-webkit-animation-timing-function: linear;-moz-animation-name: rwSpinnerRotate;-moz-animation-duration: 0.8s;-moz-animation-iteration-count: infinite;-moz-animation-timing-function: linear;-ms-animation-name: rwSpinnerRotate;-ms-animation-duration: 0.8s;-ms-animation-iteration-count: infinite;-ms-animation-timing-function: linear;'); }catch(e){ console.log("addRule or insertRule not supported"); } */ /*** FASTE HJELPERE ***/ function swapLang(){ // Bytter ut all elementers tekst med verdi fra 'data-english' - oversetter rett ot slett, // men bare derson verdi i data-english eksisterer: // Eks: try{ var otherLangVals = document.querySelectorAll("[data-english]"); for (key in otherLangVals){ try{ var otherLangString = otherLangVals[key].getAttribute("data-english"); if (otherLangString != "undefined"){ var originalString = otherLangVals[key].innerHTML; otherLangVals[key].innerHTML = otherLangString; otherLangVals[key].setAttribute("data-english",originalString); } }catch(f){ console.log(f); } } }catch(e){ alert("Sorry, translation unavailable :-("); } } /*** FASTE HJELPERE SLUTT ***/ // EXTENSION listXMLfeedClass /* Copyright: Terje Rudi, 2021 Slik bruker du dette scriptet i ei web-side: 1) Implementer dette scriptet i en html-script-tag 2) Se eksempel paa oppsett 3) Eksempel egen funksjon for manipulering av data La inn vask av duplikater, 27. jan -21. Se 'hash'! */ function generateHash(string) { // Blir brukt for å unngå dubletter let hash = 0; if (string.length == 0) return hash; for (let i = 0; i < string.length; i++) { let charCode = string.charCodeAt(i); hash = ((hash << 7) - hash) + charCode; hash = hash & hash; } return hash; } function _RWLoadFeedAndOutput() { //LoadXMLconvertToJSON(){ this.loaded = false; this.htmlResult = false; this.runLoadAndConvert = function(htmlTarget,d,options){ // XML source try{ if (d["url"] != undefined && options["main"] && options["items"]){ // Bare bestemte leverandoerer av XML blir godkjent i en white list. Kontakt administrator dersom du har en ny 'host' document.getElementById(htmlTarget).innerHTML = "

" + d["label"] + "

Inga liste.

"; console.log('CallUrl A: ' + "https://v.hvl.no/verktyg/remoteXml2JSON.php?url=" + escape(d["url"])); this.fetchFeed = makeRequest("https://v.hvl.no/verktyg/remoteXml2JSON.php?url=" + escape(d["url"]),this.treatJSONfeed,"xmlfeed",{"target":htmlTarget,"label":d["label"],"options":options}); }else{ console.log("D2 - XML " + htmlTarget + " " + e); this.htmlResult = "

Feed-url eller innstillinger (options) mangler! Se eksempel i javascriptet!

"; } }catch(e){ console.log("D3 - XML " + htmlTarget + " " + e); this.htmlResult = "

Scriptet kunne ikke kjøres p.g.a. feil: " + e + "

"; } }; this.runLoad = function(htmlTarget,d,options){ // JSON source try{ if (d["url"] != undefined && options){ // Ingen restriksjoner for blogginnhenting end if (d["label"] != undefined){ document.getElementById(htmlTarget).innerHTML = "

" + d["label"] + "

Inga liste.

"; } console.log('CallUrl B: ' + d["url"]); this.fetchFeed = makeRequest(d["url"],this.treatJSONfeed,"jsonfeed",{"target":htmlTarget,"label":d["label"],"options":options}); }else{ console.log("D2 - JSON"); this.htmlResult = "

Feed-url eller innstillinger (options) mangler! Se eksempel i javascriptet!

"; } }catch(e){ console.log("D3 - JSON"); this.htmlResult = "

Scriptet kunne ikke kjøres p.g.a. feil: " + e + "

"; } }; this.treatJSONfeed = function(d,options){ console.log('Callback treatJSONfeed activated'); opts = options["options"]; opts["targetId"] = options["target"]; opts["label"] = options["label"]; var response = JSON.parse(d); // Resultatet fra innhentet JSON under constructor: makeRequest konverteres til objekt //console.log(JSON.stringify(response)); if (response["Error"] == true){ fullFeedHTML = "

Feil: " + response["Msg"] + "

"; }else{ try{ if (typeof response["Data"]["channel"]["title"] !== "undefined" && (response["Data"]["channel"]["title"] == "Error Report")){ // Sjekk om det er returnert feilmelding fra kilde try{ document.getElementById(opts["targetId"]).innerHTML = "

Feil fra kildedokument:
" + response["Data"]["body"]["div"]["div"][0]["div"] + "

"; }catch(e){ document.getElementById(opts["targetId"]).innerHTML = "

Ukjent feil fra kildedokument

"; } } }catch(e){ console.log('No error found:' + e + ' (typeof response["Data"]["channel"]["title"] = ' + typeof response["Data"]["channel"]["title"]); } // Laster inn liste og henter inn detaljer om hvert element i lista try{ var responseData = response["Data"]; if (opts["main"] != undefined){ var feedTitle = eval("responseData['" + opts["main"]["title"]["path"].join("']['") + "']"); }else{ console.log("opts[\"main\"] er udefinert, men det er tillatt"); } if (opts["items"]["path"] != undefined){ var feedItems = eval("responseData['" + opts["items"]["path"].join("']['") + "']"); }else{ var feedItems = response; // Direkte items-feed oeverst i hierarkiet } }catch(e){ var feedTitle = opts["label"] + ": Inga liste"; var feedItems = []; } // Sjekk om feedItems er objekt (om bare ett element) - pakk da inn i array if (typeof feedItems.length == "undefined"){ feedItems = new Array(feedItems); } let items = []; let itemsHashed = []; if (feedItems.length > 0){ console.log("Type: " + typeof feedItems); // Hver enkelt liste-element for (var i = 0; i < feedItems.length; i++) { var responseData = feedItems[i]; var feedHTML = ""; // Element wrap tag if (opts["items"]["design"]["htmlTag"]){ feedHTML += "<" + opts["items"]["design"]["htmlTag"]; if (opts["items"]["design"]["cssStyle"]){ feedHTML += " style=\"" + opts["items"]["design"]["cssStyle"] + "\""; } if (opts["items"]["design"]["dataVal"]){ try{ feedHTML += " data-" + opts["items"]["design"]["dataVal"] + "=\"" + escape(responseData[opts["items"]["design"]["dataVal"]]) + "\""; }catch(e){ console.log("Kunne ikke sette data-tag: " + e); } } feedHTML += ">"; } if (opts["items"]["design"]){ for (var key in opts["items"]["design"]) { if (key != "htmlTag" && key != "cssStyle" && key != "dataVal"){ if (typeof responseData[key] != "undefined"){ // Main tag feedHTML += "<" + opts["items"]["design"][key]["htmlTag"]; if (opts["items"]["design"][key]["cssStyle"]){ feedHTML += " style=\"" + opts["items"]["design"][key]["cssStyle"] + "\""; } feedHTML += ">"; // Label if (opts["items"]["design"][key]["uiLabel"]){ if ((typeof opts["main"] != "undefined") && (typeof opts["main"]["lang"] != "undefined") && (typeof opts["items"]["design"][key]["uiLabel"][opts["main"]["lang"]] == "string")){ feedHTML += "" + opts["items"]["design"][key]["uiLabel"][opts["main"]["lang"]] + ": "; }else{ feedHTML += "" + opts["items"]["design"][key]["uiLabel"] + ": "; } } // Hyperlink var hasLink = true; try{ // Her er det nioe troebbel med at lenke ikke blir lagt inn paa rett sted, saa maa hentes direkte fra responseData - er det greit? if ((typeof opts["items"]["design"][key]["hyperlink"] != "undefined") && responseData[opts["items"]["design"][key]["hyperlink"]].length){ feedHTML += ""; }else if (typeof responseData[opts["items"]["design"]["hyperlink"]] != "undefined") { feedHTML += ""; }else if (typeof responseData["link"] != "undefined") { feedHTML += ""; }else{ hasLink = false; console.log("Link-url not available") } }catch(e){ hasLink = false; } // Text string value (HER ER TEKSTVERDIEN!) if (typeof opts["items"]["design"][key]["callback"] != "undefined"){ // Her utfoeres evt. funksjon. Baade elementes del-verdi, samt alle data for elementes levers med som argumenter feedHTML += eval(opts["items"]["design"][key]["callback"] + "('" + responseData[key] + "',responseData);"); }else{ if (typeof opts["items"]["design"][key]["valuepath"] != "undefined"){ // Verdien er et objekt og tekst ligger dypere feedHTML += eval("responseData['" + opts["items"]["design"][key]["valuepath"].join("']['") + "']") }else{ feedHTML += responseData[key]; } } // Closure hyperlink if (hasLink){ feedHTML += ""; } // Closure main tag of items feedHTML += ""; } } } }else{ items.push("
Feil: Design is not set in opts['items']['design'].
Options received: " + JSON.stringify(opts) + "
Data received: " + JSON.stringify(responseData) + "
"); break; } // Closure element wrap tag if (opts["items"]["design"]["htmlTag"]){ feedHTML += ""; } // Add to list of HTML if not already existant let feedHash = generateHash(feedHTML); if (itemsHashed.indexOf(feedHash) != -1){ console.info('Duplikat for: ' + feedHash); }else{ itemsHashed.push(feedHash); items.push(feedHTML); } } }else{ console.log("Ingen elementer: " + JSON.stringify(feedItems)); items.push = "

Ingen elementer

"; } var fullFeedHTML = ""; // Main tag if (opts["main"] != undefined){ if (opts["main"]["htmlTag"]){ fullFeedHTML += "<" + opts["main"]["htmlTag"]; if (opts["main"]["cssStyle"]){ fullFeedHTML += " style=\"" + opts["main"]["cssStyle"] + "\""; } fullFeedHTML += ">"; } // Main title tag if (opts["main"]["title"]["htmlTag"]){ fullFeedHTML += "<" + opts["main"]["title"]["htmlTag"]; if (opts["main"]["title"]["cssStyle"]){ fullFeedHTML += " style=\"" + opts["main"]["title"]["cssStyle"] + "\""; } fullFeedHTML += ">"; } // Main title value fullFeedHTML += feedTitle; // Closure main title tag if (opts["main"]["title"]["htmlTag"]){ fullFeedHTML += ""; } } // Write all items html to main // List wrap tag if (opts["items"]["htmlTag"]){ fullFeedHTML += "<" + opts["items"]["htmlTag"]; if (opts["items"]["cssStyle"]){ fullFeedHTML += " style=\"" + opts["items"]["cssStyle"] + "\""; } fullFeedHTML += ">"; } // Joining element together fullFeedHTML += items.join(""); // List wrap tag closure if (opts["items"]["htmlTag"]){ fullFeedHTML += ""; } if (opts["main"] != undefined){ // Closure main tag if (opts["main"]["htmlTag"]){ fullFeedHTML += ""; } } } if (opts["targetId"]){ // Writes HTML to a defined element in the page try{ document.getElementById(opts["targetId"]).innerHTML = fullFeedHTML; }catch(e){ document.write("

FEIL: Finner ikke elementet hvor data skal skrives til.

"); } }else{ // Alternatively writes HTML directly to the page where this script is placed document.write(fullFeedHTML); } },this.loaded = true; } /***** EKSEMPEL for script og innstillinger som settes inn ETTER denne klassen (brukes i epi-blokken 'Bibliotek Nye Bøker'): // Adressene til de forskjellige feedene som skal presenteres, keys blir targets (html-elementene som data skal legges inn i) var nybokListeFeeds = { "nybokListeForde":{ "url":"https://eu01.alma.exlibrisgroup.com/rep/getFile?institution_code=47BIBSYS_HIB&file=NewBooksForde&type=RSS", "label":"Campus Førde" }, "nybokListeHaugesund":{ "url":"https://eu01.alma.exlibrisgroup.com/rep/getFile?institution_code=47BIBSYS_HIB&file=NewBooksHaugesund&type=RSS", "label":"Campus Haugesund" } } // Instillinger for hvordan lista skal ta seg ut visuelt var nybokListeOptions = { "main":{ "htmlTag":"section", "title":{ "htmlTag":"h2", "path":["channel","title"], // Fetches string from responseData with that key } }, "items":{ "path":["channel","item"], // Fetches string from responseData with that key "htmlTag":"ol", "cssStyle":"list-style-type: none;", "design":{ "htmlTag":"li", "cssStyle":"margin-bottom: 1rem;", "title":{ "htmlTag":"p", "cssStyle":"margin: 0.2rem 0;font-weight: bold;", "hyperlink":"link" // Fetches string from responseData with that key }, "author":{ "htmlTag":"p", "cssStyle":"margin: 0.2rem 0;font-size: smaller;color: #707B7B;", "uiLabel":"Forfattar" }, "description":{ "htmlTag":"p", "cssStyle":"margin: 0.2rem 0;font-size: smaller;color: #707B7B;", "uiLabel":"Hylleplassering", "callback":"fiksHylleplass" } } } } // Callback(s) function fiksHylleplass(s){ var splitHylleplass = s.split("Call number - "); try{ return splitHylleplass[1]; }catch(e){ console.log(e); } return s; } // Trigger scriptet og gjoer jobben, ett objekt for hver url/target document.write(""); // <- bare om en vil ha fortegnelse oeverst var feedObjects = {} for (var nybokListeTarget in nybokListeFeeds) { document.write("
"); feedObjects[nybokListeTarget] = new _RWLoadFeedAndOutput(); feedObjects[nybokListeTarget].runLoadAndConvert(nybokListeTarget,nybokListeFeeds[nybokListeTarget],nybokListeOptions); // Legge til linje i toppfortegnelse document.getElementById("nybokListeFortegnelse").innerHTML += "
  • Nye bøker på " + nybokListeFeeds[nybokListeTarget]["label"] + "
  • "; // <- bare om en vil ha fortegnelse oeverst } *****/