Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d1b2352
Timer module code added
cpill0789 Aug 22, 2012
3b4b888
Deploy timer module
cpill0789 Aug 22, 2012
cd8cba3
Timer implementation
cpill0789 Aug 22, 2012
2b5b920
timer code deployed
cpill0789 Aug 22, 2012
f7b8369
Updated settings file
cpill0789 Aug 22, 2012
81b9aef
Deleted outdated text in readme
cpill0789 Aug 27, 2012
1eed600
Implemented time overwrite functionality
cpill0789 Sep 4, 2012
c18f6ea
extra files
cpill0789 Sep 4, 2012
3da24f4
Cleaned up timerModule code
cpill0789 Sep 21, 2012
98cb433
Cleaned up timerModule code
cpill0789 Sep 21, 2012
65e7dc5
Changes to timer code deployed
cpill0789 Sep 21, 2012
0991aa9
Ignore OS files
cpill0789 Oct 6, 2012
eeed750
Removed operating sustem log files.
cpill0789 Dec 9, 2012
698b1d8
Merged developer
cpill0789 Dec 9, 2012
eaaf286
New deployment
cpill0789 Dec 9, 2012
70188c3
deleted old files
cpill0789 Dec 9, 2012
000e1f4
Removed hidden log files.
cpill0789 Dec 9, 2012
2b29768
Merge branch 'timer' of https://github.com/cpill0789/experigen into t…
cpill0789 Dec 9, 2012
0facb81
Update to do.md
cpill0789 Dec 9, 2012
dff9d9a
Update to do.md
cpill0789 Dec 9, 2012
b21b924
Update readme
cpill0789 Dec 9, 2012
3b87f23
updated comments
cpill0789 Dec 10, 2012
e9575fa
Merged upstream changes
cpill0789 Dec 12, 2012
681dd80
Added audio button disabling after audio finishes playing
cpill0789 Dec 12, 2012
767d9ee
Added disable audio button code and redeployed
cpill0789 Dec 12, 2012
e5e76c6
added button scale midpoint highlighting function
cpill0789 Dec 12, 2012
18a9e28
merged audio button disable
cpill0789 Dec 12, 2012
425d779
redeployed
cpill0789 Dec 12, 2012
3e18bb1
Merge branch 'scaleMidpointStyling' into Developer
cpill0789 Dec 12, 2012
575eda9
merged scale mid point highlighting function
cpill0789 Dec 12, 2012
b0138c3
Merge branch 'timer' into Developer
cpill0789 Dec 12, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

.DS_Store

_lib/.DS_Store

web/.DS_Store
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

A framework for creating phonology experiments.

The developer branch of this fork includes the following features:
* timing functionality

## Who is it for? How can I get help?

Experigen is for linguists who have some basic knowledge of HTML, CSS, and Javascript, who know some of the basics of putting a webpage up, and who know a little bit of R – or for linguists who want to learn these things, or for linguists who have someone like this on their team. It's not for linguists who are ''not good with computers''.
Expand All @@ -12,8 +15,6 @@ If you fixed anything or added functionality to Experigen, we invite you contrib

## Known limitations

Experigen does not measure reaction times. You can only get a very rough idea of how fast participants are working by examining the server timestamps.

Experigen requires participants to be online and using an active internet connection. There is no offline mode at the moment (it's in the works, though).


Expand Down
1 change: 1 addition & 0 deletions _lib/deploy.pl
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
push(@{$inputfile[0]}, "js/array.js");

$inputfile[1] = [];
push(@{$inputfile[1]}, "js/timerModule.js");
push(@{$inputfile[1]}, "js/trial.js");
push(@{$inputfile[1]}, "js/dataconnection.js");
push(@{$inputfile[1]}, "js/experiment.js");
Expand Down
10 changes: 10 additions & 0 deletions _lib/js/experiment.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ Experigen.fieldsToSave = {};
Experigen.resources = [];
Experigen.position = -1;
Experigen.initialized = false;
Experigen.trackTimes = false;



Experigen.launch = function () {
var that = this;
Expand Down Expand Up @@ -74,6 +77,13 @@ Experigen.load = function () {
this.progressbar = this.new_progressbar();
this.progressbar.initialize();

// Initialize response time tracker if necessary
if(this.settings.recordResponseTimes) {
this.timeTracker = timer_maker( );
this.trackTimes = true;
}


if (this.settings.audio) {

soundManager.onready(function() {
Expand Down
60 changes: 60 additions & 0 deletions _lib/js/timerModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**********************************************
* timerModule.js
*
* Creates an object that tracks response times for experigen trials.
* Designed to record times for each part in a screen, then return times
* in an object to write to database server.
*
* by Carl Pillot
* last update 9-20-12
***********************************************/

var timer_maker = function ( ) {

// private variables
var start_time = 0;
var stop_time = 0;
var response_times = {};

var clear_values = function ( ) {
start_time = 0;
stop_time = 0;
response_times = {};
};

return {
set_start_time: function ( ) {
start_time = new Date().getTime();
},
log_part: function ( responseID ) {

// Immediately record stop time
stop_time = new Date().getTime();

var responseName = 'response' + responseID + '_time';

// If a response doesn't exist for this part, add new response
if(!response_times.hasOwnProperty(responseName)) {
response_times[responseName] =
{ start: start_time,
stop: stop_time,
time: stop_time - start_time,
number: 1
};
}

// If a response has already been logged, recalculate the response time with new stop time
else {
response_times[responseName]['stop'] = stop_time;
response_times[responseName]['time'] = stop_time - response_times[responseName]['start'];
response_times[responseName]['number'] = response_times[responseName]['number'] + 1;
}
},
get_response_times: function ( ) {
return response_times;
},
new_frame: function ( ) {
clear_values( );
}
};
}
113 changes: 94 additions & 19 deletions _lib/js/trial.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

Experigen.make_into_trial = function (that) {

that.userCode = Experigen.userCode;
Expand All @@ -12,7 +11,7 @@ Experigen.make_into_trial = function (that) {
that.callingPart = 0;
that.soundbuttons = [];
that.responses = 0;


that.advance = function(spec) {
var parts = $(".trialpartWrapper");
Expand Down Expand Up @@ -40,7 +39,7 @@ Experigen.make_into_trial = function (that) {
// does it contain text boxes that shouldn't allowed to be empty?
if (/textInputNotEmpty/.test($(part).find(':input').first().attr("class")) && !Experigen.screen().checkEmpty($(part).find(':input').first())) {
return false;
} else {
} else {
// no text boxes to fill, we can move on
// hide current part first if needed
if (spec && spec.hide) {
Expand All @@ -52,8 +51,9 @@ Experigen.make_into_trial = function (that) {
}
// now advance and show next part, or advance to next screen
Experigen.screen().currentPart += 1;

if (Experigen.screen().currentPart > Experigen.screen().parts.length) {

// add all require data to the current form
for (i in Experigen.fieldsToSave) {
var str = "";
Expand All @@ -69,15 +69,37 @@ Experigen.make_into_trial = function (that) {
var str= "<input type='hidden' name='sound" + (i+1) + "' value='" + Experigen.screen().soundbuttons[i].presses + "'>\n";
$("#currentform").append(str);
}

// Add timing values to current form if necessary
if(Experigen.trackTimes) {
var responseTimes = Experigen.timeTracker.get_response_times( );
for (x in responseTimes) {
str = "<input type='hidden' name='" + x + "' value='" + responseTimes[x]['time'] + "'>";
$("#currentform").append(str);
}
}

// send the form
// enabled all text fields before sending, because disabled elements will not be sent
$("#currentform " + 'input[type="text"]').attr("disabled","")
Experigen.sendForm($("#currentform"));

// reset time tracker values for next screen
if(Experigen.trackTimes) {
Experigen.timeTracker.new_frame( );
}

Experigen.advance();
} else {
// show next part
part = "#" + "part" + Experigen.screen().currentPart;
$(part).show();

// TIMER: Reset Start Time
if(Experigen.trackTimes) {
Experigen.timeTracker.set_start_time( );
}

// give focus to the first form object inside, if any
$(part).find(':input[type!="hidden"][class!="scaleButton"]').first().focus();
}
Expand All @@ -86,7 +108,7 @@ Experigen.make_into_trial = function (that) {
return true;
}


that.makeScale = function(obj) {
Experigen.screen().responses++;
var buttons = obj.buttons || ["1","2","3","4","5","6","7"];
Expand Down Expand Up @@ -119,8 +141,58 @@ Experigen.make_into_trial = function (that) {
str += "<input type='hidden' name='response" + Experigen.screen().responses + "' value=''>\n";
return str;
}

// makeScaleWithMidpoint: For scales with an odd number, this applies a given style to the midpoint scale button.
that.makeScaleWithMidpoint = function(obj) {
Experigen.screen().responses++;
var buttons = obj.buttons || ["1","2","3","4","5","6","7"];
var edgelabels = obj.edgelabels || [''];
var linebreaks = obj.linebreaks || 0;
var style = obj.style || "";
var midpointStyle = obj.midpointStyle || "text-decoration:underline;";
var buttontype = "button";
var disable = (obj.disable) ? true : false;
var hide = (obj.hide) ? true : false;

var serverValues = obj.serverValues || buttons;
/// validate serverValues here to be non-empty and distinct

var highlightMidpoint = (buttons.length % 2 == 1) ? true : false;

var str = "";
str += '<div class="scaleWrapper">';
str += '<div class="scaleEdgeLabel">' + edgelabels[0] + '</div>';
for (var i=0; i<buttons.length; i+=1) {
str += '<div class="scalebuttonWrapper">';
str += '<input type="' + buttontype + '" value="'+ buttons[i] +'" id="' + Experigen.screen().responses + 'button' + i + '" name="scale'+ Experigen.screen().responses +'" class="scaleButton" onClick="Experigen.screen().recordResponse(' + Experigen.screen().responses + "," + "'" + buttons[i] + "'" + ');Experigen.screen().continueButtonClick(this,{hide:' + hide + ',disable:' + disable + '});';

if (obj.rightAnswer) {
str += 'Experigen.screen().feedbackOnText(this,\'' + obj.feedbackID + '\',\'' + obj.matchRegExpression + '\',\'' + obj.rightAnswer + '\',\'' + obj.feedbackWrong + '\',\'' + obj.feedbackMatch + '\',\'' + obj.feedbackRight + '\')';
}

str += '"';

if (highlightMidpoint && (i == Math.floor(buttons.length/2))){
str += ' style="' + midpointStyle + '" ';
} else {
str += ' style="' + style + '" ';
}

str += '></div>';
if (linebreaks>0 && (i+1)%linebreaks==0 && (i+1)!=buttons.length) { str += '<br>'}
}
str += '<div class="scaleEdgeLabel">' + edgelabels[edgelabels.length-1] + '</div>';
str += '</div>';
str += "<input type='hidden' name='response" + Experigen.screen().responses + "' value=''>\n";
return str;
}

that.recordResponse = function (scaleNo, buttonNo) {

// Record response time for part
if(Experigen.trackTimes) {
Experigen.timeTracker.log_part( scaleNo );
}
/// make all the necessary fields in document.forms["currentform"],
/// and fill them with data
if (scaleNo!==undefined && buttonNo!==undefined) {
Expand Down Expand Up @@ -163,11 +235,11 @@ Experigen.make_into_trial = function (that) {
return comingFrom;
}


that.makeTextInput = function (obj) {

Experigen.screen().responses++;

if (typeof obj==="string") {
obj = {initValue: obj}
}
Expand Down Expand Up @@ -244,7 +316,7 @@ Experigen.make_into_trial = function (that) {


that.makePicture = function (obj) {

if (typeof obj==="string") {
obj = {src: obj}
}
Expand All @@ -255,7 +327,7 @@ Experigen.make_into_trial = function (that) {
obj.scr = "";
}
obj.src = Experigen.settings.folders.pictures + obj.src;

var str = "";
str += "<img ";
if (obj.src) {
Expand Down Expand Up @@ -295,7 +367,7 @@ Experigen.make_into_trial = function (that) {
return str;
}


that.checkEmpty = function (obj) {

if ($(obj).val().match(/^\s*$/)) {
Expand Down Expand Up @@ -344,12 +416,10 @@ Experigen.make_into_trial = function (that) {
} else {
Experigen.advance(caller);
}

}

}


that.makeSoundButton = function (obj) {
that.makeSoundButton = function (obj) {

if (typeof obj==="string") {
obj = {soundFile: obj}
Expand All @@ -361,14 +431,16 @@ Experigen.make_into_trial = function (that) {
if (obj.advance===false) {
advance = false;
}
Experigen.screen().soundbuttons.push({id: soundID, presses: 0, file: soundFile});
var disable = (obj.disable) ? true : false;

Experigen.screen().soundbuttons.push({id: soundID, presses: 0, file: soundFile});

var soundFile2 = "";
if (obj.soundFile2) {
soundFile2 = Experigen.settings.folders.sounds + obj.soundFile2;
}
var soundID2 = soundID + "2";

soundManager.createSound({
id: soundID,
url: soundFile,
Expand All @@ -385,6 +457,9 @@ Experigen.make_into_trial = function (that) {
onload:function() {
},
onfinish:function() {
if(disable) {
$("#"+soundID).attr("disabled", "disabled");
}
if (advance) {
Experigen.screen().advance();
}
Expand All @@ -395,6 +470,9 @@ Experigen.make_into_trial = function (that) {
onfinish:function() {
if (advance) {
if (soundFile2 === "") {
if(disable) {
$("#"+soundID).attr("disabled", "disabled");
}
Experigen.screen().advance();
} else {
soundManager.play(soundID2);
Expand All @@ -415,6 +493,3 @@ Experigen.make_into_trial = function (that) {

return that;
}



1 change: 0 additions & 1 deletion to do.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,3 @@ Email us with your suggestions, requests, and code contributions.
* send browser stats to server (with IP locator?)
* replace EJS?
* group-level variables
* add response time measurements
File renamed without changes.
Loading