How to capture time spent inactive in Qualtrics - time

Hi I am trying to measure if people are cheating by leaving the Qualtrics survey. I want to know how long they spend outside of the quiz window. I found a few answers on this website, but my javascript does not send the data to embeddeddata. Here is my script that I put in the Header of my Quiz(please keep in mind that I started to learn Java yesterday):
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<script>
Qualtrics.SurveyEngine.addOnload(function() {
var log = "${e://Field/total}";
(function() {
var time = 0,
delta = 100,
tid;
tid = setInterval(function() {
if ( window.blurred ) { return; }
total = ((time+=delta)/1000);
log.text(total);
}, delta);
})();
window.onblur = function() { window.blurred = false; alert("YOLO!")};
window.onfocus = function() { window.blurred = true; };
Qualtrics.SurveyEngine.setEmbeddedData('total', log);
});
</script>

Related

Issue with google.maps.event.trigger(map, “resize”) in jquery tabs

I have a button named update details.On clicking the button a dialog is created which contains 3 tabs.In the third tab a field named map is there where users can select their location in map.I have 2 hidden fields which contain latitude and longitude of user stored in database.If the values are null,I need to show marker to their current location.My code is as follows.
<script>
$(document).ready(function(){
var directionsDisplay,
directionsService,
map;
$("#tabs").tabs({
show: function(e, ui) {
if (ui.index == 2) {
google.maps.event.trigger(map, "resize");//for showing google
//map in tabs
}
}
});
if(!window.google||!window.google.maps){
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3&' +
'callback=initialize';
document.body.appendChild(script);
}
else{
initialize();
}
});
</script>
<script>
//var directionsDisplay,
//directionsService,
//map;
function initialize() {
//var directionsService = new google.maps.DirectionsService();
//directionsDisplay = new google.maps.DirectionsRenderer();
if(($("#latitude_val").val().length >3) || ($("#longitude_val").val().length>3))
{
var chicago = new google.maps.LatLng($("#latitude_val").val(), $("#longitude_val").val());
}
else
{
geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': 'Dubai internet city'}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK)
{
console.log("Latitude: "+results[0].geometry.location.lat());
console.log("Longitude: "+results[0].geometry.location.lng());
}
else
{
console.log("Geocode was not successful for the following reason: " + status);
}
//console.log("latitude"+position.coords.latitude+'longitude='+position.coords.longitude);
});
}
//chicago = new google.maps.LatLng(51.508742, -0.120850);
var mapOptions = { zoom:16, mapTypeId: google.maps.MapTypeId.ROADMAP, center: chicago }
map = new google.maps.Map(document.getElementById("googlemap"), mapOptions);
var marker=new google.maps.Marker({
position:chicago,
map:map,
draggable:true,
animation: google.maps.Animation.DROP
});
marker.setMap(map);
google.maps.event.addListener(
marker,
'drag',
function() {
document.getElementById('latitude_val').value = marker.position.lat();
document.getElementById('longitude_val').value = marker.position.lng();
console.log($("#latitude_val").val());
console.log($("#longitude_val").val());
}
);
//directionsDisplay.setMap(map);
}
function fail(){
alert('navigator.geolocation failed, may not be supported');
}
</script>
When I run this code,it showing the following error.
ReferenceError: google is not defined
google.maps.event.trigger(map, "resize");
You're calling google.maps.event.trigger before you've added the call to load the google maps javascript. Maybe just swap the two parts of what's going on in your document.ready
$(document).ready(function(){
var directionsDisplay,
directionsService,
map;
if(!window.google||!window.google.maps){
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3&' +
'callback=initialize';
document.body.appendChild(script);
}
else{
initialize();
}
$("#tabs").tabs({
show: function(e, ui) {
if (ui.index == 2) {
google.maps.event.trigger(map, "resize");//for showing google
//map in tabs
}
}
});
});

Angular $http, $q: track progress

Is there a way to track progress of http requests with Angular $http and $q? I'm making $http calls from a list of urls and then using $q.all I'm returning result of all requests. I would like to track progress of each request (promise resolved) so that I can show some progress to the user. I'm thinking of emitting event when a promise gets resolved but I'm not sure where should that be.
var d = $q.defer();
var promises = [];
for(var i = 0; i < urls.length; i++){
var url = urls[i];
var p = $http.get(url, {responseType: "arraybuffer"});
promises.push(p);
}
$q.all(promises).then(function(result){
d.resolve(result);
}, function(rejection){
d.reject(rejection);
});
return d.promise;
EDIT:
OK, after a bit of fiddling, this is what I've come up with
var d = $q.defer();
var promises = [];
var completedCount = 0;
for(var i = 0; i < urls.length; i++){
var url = urls[i];
var p = $http.get(url, {responseType: "arraybuffer"}).then(function(respose){
completedCount = completedCount+1;
var progress = Math.round((completedCount/urls.length)*100);
$rootScope.$broadcast('download.completed', {progress: progress});
return respose;
}, function(error){
return error;
});
promises.push(p);
}
$q.all(promises).then(function(result){
d.resolve(result);
}, function(rejection){
d.reject(rejection);
});
return d.promise;
Not sure if it is the right way of doing it.
I see you have already edit your own code, but if you need a more overall solution, keep reading
I once made a progress solution based on all pending http request (showing a indicator that something is loading, kind of like youtube has on the top progress bar)
js:
app.controller("ProgressCtrl", function($http) {
this.loading = function() {
return !!$http.pendingRequests.length;
};
});
html:
<div id="fixedTopBar" ng-controller="ProgressCtrl as Progress">
<div id="loading" ng-if="Progress.loading()">
loading...
</div>
</div>
.
Hardcore
For my latest project it wasn't just enought with just request calls. I started to get into sockets, webworker, filesystem, filereader, dataChannel and any other asynchronous calls that use $q. So i start looking into how i could get all the pending promises (including $http). Turns out there wasn't any angular solution, so i kind of monkey patched the $q provider by decorating it.
app.config(function($provide) {
$provide.decorator("$q", function($delegate) {
// $delegate == original $q service
var orgDefer = $delegate.defer;
$delegate.pendingPromises = 0;
// overide defer method
$delegate.defer = function() {
$delegate.pendingPromises++; // increass
var defer = orgDefer();
// decreass no mather of success or faliur
defer.promise['finally'](function() {
$delegate.pendingPromises--;
});
return defer;
}
return $delegate
});
});
app.controller("ProgressCtrl", function($q) {
this.loading = function() {
return !!$q.pendingPromises;
};
});
This may not perhaps fit everyone needs for production but it could be useful to developers to see if there is any unresolved issues that has been left behind and never gets called
Make a small general helper function:
function allWithProgress(promises, progress) {
var total = promises.length;
var now = 0;
promises.forEach(function(p) {
p.then(function() {
now++;
progress(now / total);
});
})
return $q.all(promises);
}
Then use it:
var promises = urls.map(function(url) {
return $http.get(url, {responseType: "arraybuffer"});
});
allWithProgress(promises, function(progress) {
progress = Math.round(progress * 100);
$rootScope.$broadcast('download.completed', {progress: progress});
}).catch(function(error) {
console.log(error);
});

Why is AJAX settimeout not working?

I'm going a little crazy trying to understand why this outputs the json data once and then not again as per timeout function. What am I doing wrong?
<script type="text/javascript">
var myTimer =0;
function ajax_get_json(){
var results = document.getElementById("results");
var hr = new XMLHttpRequest();
hr.open("POST", "ballJson.php",true);
hr.setRequestHeader("Content-type", "application/json");
hr.onreadystatechange = function() {
if(hr.readyState == 4 && hr.status == 200) {
var data = JSON.parse(hr.responseText);
results.innerHTML = "";
for(var obj in data){
results.innerHTML += data[obj]+"<br />";
}
}
}
hr.send(null);
results.innerHTML = "requesting...";
myTimer = setTimeout('ajax_get_json()',10000);
}
</script>
I think that you want to use the setInterval function as setTimeout only executes one time.
It is also much preferred to use setTimeout(function () { ajax_get_json(); }, 10000) or setTimeout(ajax_get_json, 10000) instead of using a string that is evaluated as the function callback.
Also note that the ajax requests may complete at any time, so it won't exactly be once every 10 seconds using setInterval. You could also call setTimout in the onreadystatechange callback to chain the calls.

Google maps in firefox6 zooms znd scrolls page

I have problem with Firefox6 (don't know if it also concerns earlier versions).
I want to embed Google Map on page, and when page has scrollbars (is longer than viewport) mouse wheel not only zooms map but also scrolls page. I tried to catch mousewheel event and stop propagation but this event isn catchable when cursor os over map. When cursor is over map controls (zoom control, google logo, etc) i can catch event and stop propagation.
What is more strange it not happens always. Sometimes page srolls and after few scrolls it stops and mousewheel only zooms map (as expected). Sometimes page doesn't scroll and sometimes it scrolls with zoom all the time. Can't find pattern.
Source code is simple:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>test</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
window.onload = function(){
var latlng = new google.maps.LatLng(52.25, 21.01);
mapOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false,
zoomControl:true,
mapTypeControl:false
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
}
</script>
</head>
<body>
<p style="height:500px;">-lot of text-</p>
<div id="map_canvas" style="width:500px; height:500px;"></div>
<p style="height:500px;">-lot of text-</p>
</body>
</html>
Your problem is also described on code.google.com, this problem is only in Firefox, but it isn't a Firefox bug:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=3652
http://code.google.com/p/gmaps-api-issues/issues/detail?id=1605
Have also found out a workaround, that is not re-scrolling or re-zooming and works fine:
A new ScrollInterceptOverlay derived from google.maps.OverlayView, prepending a div on MapPanes.overlayMouseTarget:
Version with jQuery
// Ensure to have google.maps loaded:
// var gmap = new google.maps.Map($googlemap[0], mapOptions);
// Define a ScrollInterceptOverlay function
var ScrollInterceptOverlay = function (gmap) {
if (!(this instanceof ScrollInterceptOverlay)) return;
var $div;
var $mapDiv;
var initialize = function () {
$div = $('<div />').css({
position: 'absolute', top: 0, left: 0,
display: 'inline-block'
});
var div = $div[0];
if (div && div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div && div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
this.setMap(gmap);
};
var mouseScrollStop = function (e) {
if (e && e.preventDefault) e.preventDefault();
};
this.onAdd = function () {
$div.prependTo(this.getPanes().overlayMouseTarget);
};
this.onRemove = function () {
var div = $div[0];
if (div && div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div && div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
$div.detach();
};
this.draw = function () {
if ($mapDiv && $mapDiv.length === 1) {
$div.css({
width: $mapDiv.outerWidth(),
height: $mapDiv.outerHeight()
});
}
};
var base_setMap = this.setMap;
this.setMap = function (map) {
$mapDiv = $(map.getDiv());
base_setMap.call(this, map);
};
initialize.call(this);
};
// Setup prototype as OverlayView object
ScrollInterceptOverlay.prototype = new google.maps.OverlayView();
// Now create a new ScrollInterceptOverlay OverlayView object:
var mapScrollInterceptor = new ScrollInterceptOverlay(gmap);
This workaround is using jQuery, required for calculating outerWidth and outerHeight, but also for better reading.
Version with pure javaScript
Tested live: http://fiddle.jshell.net/fhSMM/7/
// Ensure to have google.maps loaded:
// var gmap = new google.maps.Map(googlemap, mapOptions);
// Define a ScrollInterceptOverlay class function
var ScrollInterceptOverlay = function () {
if (!(this instanceof ScrollInterceptOverlay)) return;
var div;
// private instance function
var mouseScrollStop = function (e) {
if (e && e.preventDefault) e.preventDefault();
};
// public instance function
this.onAdd = function () {
div = document.createElement('div');
div.style.display = 'inline-block';
div.style.position = 'absolute';
div.style.top = div.style.left = 0;
if (div.addEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.addEventListener("mousewheel", mouseScrollStop);
// Firefox
div.addEventListener("DOMMouseScroll", mouseScrollStop);
div.addEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div.attachEvent) { // IE before version 9
div.attachEvent("onmousewheel", mouseScrollStop);
}
var pane = this.getPanes().overlayMouseTarget;
var firstChild = pane.firstChild;
if (!firstChild) {
pane.appendChild(div);
}
else {
pane.insertBefore(div, firstChild);
}
};
// public instance function
this.onRemove = function () {
if (div) {
if (div.removeEventListener) {
// Internet Explorer, Opera, Google Chrome and Safari
div.removeEventListener("mousewheel", mouseScrollStop);
// Firefox
div.removeEventListener("DOMMouseScroll", mouseScrollStop);
div.removeEventListener("MozMousePixelScroll", mouseScrollStop);
}
else if (div.detachEvent) { // IE before version 9
div.detachEvent("onmousewheel", mouseScrollStop);
}
var parent = div.parentNode;
parent.removeChild(div);
}
// do not delete div var'iable
div = undefined;
};
// public instance function
this.draw = function () {
var map = this.getMap();
if (map) {
var mapDiv = map.getDiv();
if (mapDiv) {
var rect = mapDiv.getBoundingClientRect();
div.style.width = rect.width + 'px';
div.style.height = rect.height + 'px';
}
}
};
};
// Setup prototype as OverlayView object
ScrollInterceptOverlay.prototype = new google.maps.OverlayView();
// Now create a new ScrollInterceptOverlay OverlayView object:
var mapScrollInterceptor = new ScrollInterceptOverlay();
mapScrollInterceptor.setMap(gmap);
Please visit also http://metadea.de/V/ about what (real) javaScript class functions are, and why I like jQuery :)
Works now for me.
Also in Firefox, the map is zooming on mousescroll, but no more scrolling the document.
Edit: Updated support for MozMousePixelScroll, refined jS
For now it looks like firefox bug. Will close question when bug will be fixed.
I had the same issue.
You could try to start Firefox with a brand new profile (e.g. by starting the Profile Manager - executing 'firefox -P' on windows systems - and choosing 'Create...') and see if the problem persists.
I had several old but seemingly empty user profiles lying around in the VMs I used to verify if this was a bug in FF 6 and obviously installing only the new binaries didn't help. On the other hand, creating a blank profile did, so I can only think of this being a migration glitch. If major versions of FF are going to be released on a bi-monthly basis, though, a lot of people are going to suffer from similar issues.
Why not take UI control of zooming? This works well for me.
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
</head>
<body>
<div class="canvas" style="width:600px;height:400px;"></div>
<script>
// Load event
$(function() {
var myOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map($('.canvas')[0], myOptions);
var overlay = new google.maps.OverlayView();
overlay.draw = function() {};
overlay.setMap(map);
// Only a Mozilla bug
if($.browser.mozilla) {
// Wait for the map DOM to be ready
google.maps.event.addListenerOnce(map, 'idle', function() {
$('.canvas > div > div:first-child > div').bind('DOMMouseScroll', function(e) {
// setTimeout needed otherwise the return false has no effect
setTimeout(function() {
// Calculate new center
var offset = $('.canvas').offset();
var pos = overlay.getProjection().fromContainerPixelToLatLng(new google.maps.Point(e.pageX-offset.left, e.pageY-offset.top));
// Calculate new zoom level
var zoom = map.getZoom();
if(e.detail < 0) zoom++;
else if(e.detail > 0) zoom--;
map.setCenter(pos);
map.setZoom(zoom);
}, 1);
// Stop propagation (prevent default)
return false;
});
});
}
});
</script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</body>
</html>

MooTools - how to reload image?

Is there any way to reload the same image using mootools. I have a camera that gives me image, but I have to refresh it. I wrote this, but it doesn't work so well:
var url = "some valid url to some image.jpg";
var timer = 10;
var periodical;
var camera_container;
var refresh = (function() {
var loader = new Asset.image(url, {
onLoad : function() {
camera_container.empty();
camera_container.inject(loader);
}
});
});
window.addEvent('domready', function() {
// the periodical starts here, the * 1000 is because milliseconds required
refresh.periodical(timer * 1000, this);
camera_container = $('camera-image');
});
Any help appreciated. Thanks.
why not add a seeding bit to the url?
(function() {
var url = "some valid url to some image.jpg?";
this.timer = 10;
var counter = 0;
this.refresh = (function() {
var loader = new Asset.image(url + counter, {
onLoad: function() {
camera_container.empty();
camera_container.inject(loader);
counter++;
}
});
});
})();
window.addEvent('domready', function() {
// the periodical starts here, the * 1000 is because milliseconds required
refresh.periodical(timer * 1000, this);
this.camera_container = $('camera-image');
});
this way the url will always be path/image.jpg?n where n changes and will force the browser to re-fetch it.
I think something like this also can work:
<div id="image-holder">
<img src="http://www.image.com/image.jpg"/>
</div>
var srcImage = 'http://www.image.com/image.jpg';
var reloadTime = 4000;
var holder = document.id('image-holder');
var imageReload = function(){
holder.empty();
var newImage = new Element('img',{
id:'image',
src:srcImage ,
alt:'image new'
}).inject(holder);
}
var start = function() {
interval = imageReload.periodical(reloadTime);
};
start();

Resources