Hi im looking a way to bookmark a page with JavaScript so that when a user reopens a course it remembers the page he or she is on by sending it to SCORM/Moodle.
any ideas folks?
using scorm 1.2 and Moodle 1.9:)
Many Thanks
<!-- ================ -->
<!-- Bookmarking start -->
<!-- ================ -->
<script type="text/javascript" src="SCORM_API_wrapper.js"></script>
<script type="text/javascript">
//Using pipwerks namespace, SCORM 1.2
var success = pipwerks.SCORM.init();
if(success){
var status = pipwerks.SCORM.get("cmi.core.lesson_status");
if(status != "completed"){
success = pipwerks.SCORM.get("cmi.core.lesson_status", "completed");
if(success){
pipwerks.SCORM.quit();
}
}
}
function setbookMark() {
var setlessonLocation = scorm.set("cmi.core.lesson_location", "2");
}
function showbookMark() {
alert(scorm.get("cmi.core.lesson_location"));
}
window.onload = function (){
init();
setbookMark();
}
</script>
<!-- ================ -->
<!-- Bookmarking End -->
<!-- ================ -->
First index page that is loaded
<script type="text/javascript" src="SCORM_API_wrapper.js"></script>
<script type="text/javascript">
var scorm = pipwerks.SCORM;
function init(){
//Specify SCORM 1.2:
scorm.version = "1.2";
var callSucceeded = scorm.init();
}
function end(){
var callSucceeded = scorm.quit();
}
function bookMark() {
var lessonLocation = scorm.get("cmi.core.lesson_location");
if (lessonLocation == "1") {
window.location = "1.html";
}
else if(lessonLocation == "2") {
window.location = "2.html";
}
else if(lessonLocation == "3") {
window.location = "3.html";
}
else if(lessonLocation == "4") {
window.location = "4.html";
}
else if(lessonLocation == "5") {
window.location = "5.html";
}
else if(lessonLocation == "6") {
window.location = "6.html";
}
else if(lessonLocation == "") {
window.location = "1.html";
}
}
window.onload = function (){
init();
bookMark();
}
window.onunload = function (){
end();
}
</script>
Setting lesson_location is the equivalent of creating a browser cookie... you need to write JavaScript in your course that parses the saved string and makes use of it.
You need to change your code in a number of places -- the code you've provided is an example that sets your course to complete the instant it's initialized. It isn't really what you're looking for.
Here's a quick primer on starting the course and looking for a bookmark:
var bookmark, initialized, status;
var scorm = pipwerks.SCORM; //shortcut for easier typing
function jumpToPage(url){
//write some code that navigates to the specified url
//Save whatever URL was just used as the bookmark
//each time the function is invoked.
scorm.set("cmi.core.lesson_location", url);
}
function init(){
//the default URL in case no bookmark is found
//or when course is launched for first time
var url = "url_of_first_page.html";
initialized = scorm.init();
if(!initialized){ alert("Course failed to initialize"); return false; }
//Get the lesson status from the LMS
status = scorm.get("cmi.core.lesson_status");
if(status === "completed"){
//You're already done, get out of here
scorm.quit();
return; //exit init() function
} else if(status === "ab-initio"){
//this is the very first launch, no bookmark will be found in LMS
//do nothing
} else {
//Check for a bookmark
bookmark = scorm.get("cmi.core.lesson_location");
//If a bookmark is found, use its value as the target URL
if(bookmark){
url = bookmark;
}
}
jumpToPage(url);
}
window.onload = init;
You can use cmi.core.lesson_location to store the learners current location in the course. If you need to store more complex information like the learners current state in the course then use cmi.suspend_data. These are both read/write properties that you can read when the course first loads and connects to the LMS and then navigate to the appropriate location within the course.
Quick reference on the CMI properties can be found under the Data Model section: http://scorm.com/scorm-explained/technical-scorm/run-time/run-time-reference/
Related
I'm trying to route to a dynamic page in JavaScript,
Is there any way I can do this,
localhost/page.html/001
Can I write a code like,
If (url last characters == 001) {
//Do something
}
<script type="text/javascript">
var lastUrl = window.location;
lastUrl = lastUrl.replace("localhost/page.html/", "");
if(lastUrl == "001"){
alert(lastUrl);
}
</script>
You could use:
const currentUrl = window.location.href
To get the current URL of the side (In this case localhost/page.html/001), then:
const filterUrl = currentURL.split("/");
if (filterUrl[2] === '001') { /* Do stuff */ } else { /* Do other stuff */ }
If your URL's are going to be always like that you could use this little snippet to filter them.
My home page has a couple of links: one for English version and the other for French version. Something like this:
<a class="ensite" href="/en">English</a>
<a class="ensite" href="/fr">French</a>
I want to use JavaScript to remember the last choice made by visitors and when they come again, they don't have to choose the language one more time because I want them to be autoredirected to the preferred language using cookies.
P.S. the visitors are strangers, not registered users. I want to store cookies in visitors' browsers, not in the database. Please, help me by providing me with the full solution.
Gelerally, the idea is: set handlers on links and upon clicking save preferred version into localStorage. Then every time user loads any page of your site, just check, whether the url contains the language context ("en"/"fr") the user chose before. If yes - do nothing, user opened the right version; if not - redirect him to the previously saved version. The following is a Vanilla approach (not properly tested). You will have to tweak it (attachEvent etc.) or use jQuery library to implement similar ideas in a shorter and more cross-browser way.
<a class="ensite" href="/en">English</a>
<a class="ensite" href="/fr">French</a>
JS:
function LanguageManager(selector) {
this.langLinks = document.querySelectorAll(selector);
}
LanguageManager.prototype.setHandler = function() {
var self = this;
this.langLinks.forEach(function(langLink) {
langLink.addEventListener("click", self.handler, false);
});
}
LanguageManager.prototype.redirect = function() {
var link = storageManager.restoreDataFromStorage();
if(link && !~window.location.href.indexOf(link)) window.location.href = link;
}
LanguageManager.prototype.handler = function() {
var e = event || window. event;
var elem = e.target || e.srcElement;
if(e.preventDefault) e.preventDefault(); else e.returnValue = false;
storageManager.saveDataToStorage(elem.href);
location.href = elem.href;
}
function StorageManager() {
this.storageName = "languageVersion";
this.storageData = null;
}
StorageManager.prototype.isStorageAvailable = function(type) {
try {
var storage = window[type], x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
} catch(e) { return false; }
}
StorageManager.prototype.saveDataToStorage = function(data) {
if(!this.isStorageAvailable('localStorage')) {
this.storageData = data;
return false;
}
try {
localStorage.setItem(this.storageName, JSON.stringify(data));
return this.storageName;
} catch(e) {
this.storageData = data;
return false;
}
}
StorageManager.prototype.restoreDataFromStorage = function() {
if(this.storageData) return this.storageData;
return JSON.parse(localStorage.getItem(this.storageName));
}
var storageManager = new StorageManager();
var languageManager = new LanguageManager(".ensite");
languageManager.setHandler();
languageManager.redirect();
Also notice, that there may be issues depending on how you implement language contexts on your site. You can start with my code on your own and tweak it or find someone else to get this properly done.
Just tested this, it works perfect.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<a class="ensite" href="" onclick ="localStorage.setItem('language','en')">English</a>
<a class="ensite" href="" onclick = "localStorage.setItem('language','fr')">French</a>
<script>
$(document).ready(function(){
var language = (localStorage.getItem('language') == null)? 'en' : localStorage.getItem('language');
console.log(language);
})
</script>
I'm trying to test my local storage so I've tried a few examples.
this example worked before but now its not. not sure what happened
https://stackoverflow.com/questions/30116818/how-to-use-local-storage-form-with-html-and-javascript?noredirect=1#comment48344527_30116818/
Now I am trying this code and nothing pops up on if else, it just says local storage is
function lsTest() {
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
var elem = document.getElementById('status');
if (lsTest() === true) {
elem.innerHTML += 'available.';
} else {
elem.innerHTML += 'unavailable.';
}
html
<div id="status">Local Storage is </div>
full code
http://tny.cz/39896a73
You should open your page using a webserver and not your local file system. The browser saves the localstorage data based on the host(domain). This prevents cross site local storage access.
Try this, using a webserver as Nimrodx said.
window.onload = function(){
function lsTest(){
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
console.log(e);
return false;
}
}
var elem = document.getElementById('status');
if(lsTest() === true){
elem.innerHTML += 'available.';
}
else{
elem.innerHTML += 'unavailable.';
}
};
There is no issue with your method, but I didn't see any call to this method.
To make it functional, you need to call it with some event. Like: button / anchor onlick, window load / ready as following:
Javascript:
window.onload = function(){lsTest();}
jQuery:
jQuery(document).ready(function(){
lsTest();
});
DEMO
However, if you just want to check the browser compatibility of localStorage / sessionStorage then if(typeof(Storage) !== undefined){} is quite useful.
I am trying to execute a javascript alert, but only alert if it is the first time that browser / computer has viewed that page - or something similar to that.
How would this be done? I have written the Javascript to what I think it be similar to.
function alert() {
alert(" Please view this is Firefox");
}
if (first time viewing this page) {
alert();
}
I really appreciate your help
You could use the JQuery Cookie Plugin for this.
function showPopUp() {
var cookie = $.cookie('the_cookie');
if(!cookie){
alert(" Please view this in Firefox");
$.cookie('the_cookie', 'the_value');
}
}
showPopUp();
You can use localStorage or cookies:
Here is an example with localStorage:
var visited = localStorage.getItem('visited');
if (!visited) {
alert("Please view this is Firefox");
localStorage.setItem('visited', true);
}
Don't use a Cookie it will be sent to the server at each time your make request. You can use Local Storage instead, like:
function load() {
var isFired = localStorage.getItem('checkFired');
if (isFired != '1'){
alert(" Please view this is Firefox");
localStorage.setItem('checkFired', '1');
}
}
load();
See this link you will get some idea example is based on cookies...Once you typed you value and if you refresh it, it will show the value..
Set cookie
document.cookie="first=first";
Read a Cookie with JavaScript
var x = document.cookie;
Example:
function getCookie(cname)
{
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++)
{
var c = ca[i].trim();
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
}
return "";
}
function checkCookie()
{
var first=getCookie("first");
if(first == "first")
{
alert(" Please view this is Firefox");
}else{
document.cookie="first=first";
}
}
Cookie in JS
EDIT: Just to clarify, my main question boils down to this: if you issue an AJAX request to some server (in this case Google's), but then the client leaves the page before the server completes the request, is it possible (or likely) that the server would abort the request as well, or would the server try to complete the request (in spite of having no one to respond to any more)?
Feel free to read the rest for all the specifics, if you want.
I am using Google Analytics on a page that is meant to immediately redirect. Since the Google javascript file ga.js is loaded asynchronously, I need to make sure that all the script tags that are added dynamically by the javascript are tracked and that the page redirect only happens after those scripts complete. I already handled that part.
The file ga.js seems to make a request to a __utm.gif file with parameters, which is what performs the actual tracking. That request obviously isn't being made from a file I can control, so here are my questions:
First of all, is the request asynchronous (I suspect it is)? Secondly, how can I make sure that that request has time to complete before I redirect the page (I'd prefer not to simply redirect after "enough time" has passed)? Would the request still complete if the originating page redirected before the request was finished (after all, I don't need any data back from Google)?
EDIT: Here's my code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Redirecting...</title>
<script type="text/javascript">
/* <![CDATA[ */
// Holds a value for each script. When all the values contained in this array are true, all loading has completed.
var scripts = [];
function scriptDetectLoaded(script)
{
scripts.push({ loaded: false, element: script });
var index = scripts.length - 1;
// Will set this script as loaded
var callback = function ()
{
//console.log("Script with index " + index + " finished loading");
scripts[index].loaded = true;
};
// For most browsers
script.onload = callback;
// For IE
script.onreadystatechange = function ()
{
if (this.readyState == "complete")
callback();
};
return index;
}
/* ]]> */
</script>
<!-- Google analytics code -->
<script type="text/javascript">
/* <![CDATA[ */
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-MY_ID-1']);
_gaq.push(['_trackPageview']);
(function ()
{
//debugger;
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
scriptDetectLoaded(ga); var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
/* ]]> */
</script>
</head>
<body>
<noscript>
<p>Please enable JavaScript and refresh this page. Our site won't work correctly without it.</p>
<p>How do I enable JavaScript?</p>
</noscript>
<!-- Google Code for New Account Conversion Page -->
<script type="text/javascript">
/* <![CDATA[ */
//debugger;
var google_conversion_id = SOME_ID;
var google_conversion_language = "en";
var google_conversion_format = "2";
var google_conversion_color = "ffffff";
var google_conversion_label = "SOME_LABEL";
var google_conversion_value = 0;
(function () {
var gad = document.createElement('script'); gad.type = 'text/javascript'; gad.async = true;
gad.src = document.location.protocol + "//www.googleadservices.com/pagead/conversion.js";
scriptDetectLoaded(gad); var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gad, s);
})();
/* ]]> */
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt="" src="http://www.googleadservices.com/pagead/conversion/1056222251/?label=keCSCNO9qAIQq9jS9wM&guid=ON&script=0"/>
</div>
</noscript>
<!-- Redirect Page -->
<script type="text/javascript">
/* <![CDATA[ */
//debugger;
var url = '/console';
var interval = 100 /*milliseconds*/;
var timeout = 5000 /*milliseconds*/;
var count = 0;
// Set a repeating function that checks to ensure all the scripts have loaded.
// Once all the scripts have loaded, redirect the page.
var id = setInterval(function ()
{
count += interval;
// Check for timeout
if (count > timeout)
{
//console.log("Timed out.");
redirect();
}
// Check to make sure all scripts have loaded
for (var i = 0, len = scripts.length; i < len; i++)
{
if (!scripts[i].loaded)
return;
}
// If we make it here, redirect
redirect();
}, interval);
function redirect()
{
location.replace(url);
// Run this in case the page doesn't redirect properly.
clearInterval(id);
var a = document.createElement("a");
a.href = url;
a.innerHTML = "Please click here to proceed";
var p = document.getElementById("message");
p.innerHTML = "";
p.appendChild(a);
}
/* ]]> */
</script>
<p id="message">Please wait as we redirect the page.</p>
</body>
</html>
If you redirect before the request completes, it will be cancelled on the client side. meaning, the server may have gotten the post and acted on it, but you will not get the results. if these items are added dynamically you cannot use any onload type of functions. i would imagine the google files your adding will have some type of callback you can use that will redirect you.
edit: if you want to load the script in a way that you will know exactly when it is done loading so you can redirect to another page i would use jquery's $.getScript function. it allows for a callback once the file has loaded then you can redirect instantly api.jquery.com/jQuery.getScript
For the tracking that depends on __utm.gif, the request shouldn't need to complete for the metrics to work. Once the browser sends the request (with all the params), GA has what it needs. So you just need to make sure that the image request fires.
If this is an interstitial page with no real content, you may be able to do something like check the length of the document's images collection; when length > 0, then you know GA has created the IMG and set its src (thereby triggering the request). Not sure about the details of that collection, but I know stuff like that used to exist; maybe it still does. In that case, a simple setInterval to perform the test and kick off the redirect should suffice.
Edit: Since the GA stuff adds scripts to the document, you can check the DOM structure to see if scripts with the proper src value exist. That may get you closer to chaining the redirect from the right kind of event.
For the current state of ga.js you can check tracking completing using this code:
(function (global) {
var listeners = []
, ImageReworked
, ImageNative = Image
;
function stringMatch(haystack, needle) {
if (typeof needle.valueOf() === 'string' && haystack.indexOf(needle) !== -1) {
return true;
} else if (needle instanceof RegExp && haystack.match(needle)) {
return true;
}
}
global.addImageListener = function (url, handler) {
if (!listeners.length) {
Image = ImageReworked;
}
listeners.push([url, handler]);
};
global.removeImageListener = function (url, handler) {
var newListeners = [];
listeners.forEach(function (el) {
if (url.constructor !== el[0].constructor //this will not work for object in different windows
|| el[0].toString() !== url.toString()
|| (handler && handler !== el[1])) {
newListeners.push(el);
}
});
listeners = newListeners;
if (!listeners.length) {
Image = ImageNative;
}
};
ImageReworked = function(w, h) {
var i = new ImageNative(w, h)
;
function handler() {
listeners.forEach(function (el) {
var url = el[0]
, handler = el[1]
;
if (stringMatch(i.src, url)) {
handler(i.src);
}
});
}
if (i.addEventListener) {
i.addEventListener('load', handler, false);
} else if (i.attachEvent) {
i.attachEvent('onload', handler);
}
return i;
};
})(window);
Usage example:
addImageListener(/__utm/, function (src) {
var parameters = {};
window.removeImageListener(new RegExp('__utm'));//see, regexp can be created by new RegExp!
(foundParameters = src.match(/(\?|&)(.*?\=[^?&]*)/g)) && foundParameters.forEach(function (parameter) {
var pair = parameter.replace(/^(\?|&)/, '').split('=');
parameters[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
});
console.log(parameters);
});
_gaq.push(['_setAccount', gaid], ['_trackPageview']);
But you should always keep in mind that if GA changes their tracking logic, this code will be broken.
You also should add timeout (what if load-event will never occure).
And don't use i.onload, because GA-script override this attribute.