Skip to content

Commit

Permalink
Loading HTML files from templates using backbone
Browse files Browse the repository at this point in the history
  • Loading branch information
dmarkant committed May 7, 2013
1 parent b744767 commit 93769a2
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 80 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
config.txt
participants.db
26 changes: 19 additions & 7 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import datetime
import logging
from fnmatch import filter
from functools import wraps
from random import choice
try:
Expand All @@ -11,7 +12,7 @@
from counter import Counter

# Importing flask
from flask import Flask, render_template, request, Response, make_response
from flask import Flask, render_template, request, Response, make_response, jsonify

# Database setup
from db import db_session, init_db
Expand Down Expand Up @@ -380,24 +381,35 @@ def inexpsave():
db_session.commit()
return render_template('error.html', errornum= experiment_errors['intermediate_save'])

@app.route('/data/<assignmentId>', methods=['PUT'])
def update(assignmentId=None):
@app.route('/data/<id>', methods=['PUT'])
def update(id=None):
"""
Save experiment data.
Save experiment data, which should be a JSON object and will be stored
after converting to string.
"""
print "accessing the /data route with id:", assignmentId
print "accessing the /data route with id:", id

if not request.json.has_key('data'):
raise ExperimentError('improper_inputs')

user = Participant.query.\
filter(Participant.assignmentid == assignmentId).\
filter(Participant.assignmentid == id).\
one()
user.datastring = request.json['data']
user.datastring = str(request.json)
db_session.add(user)
db_session.commit()
return "Success"

@app.route('/pages', methods=['GET'])
def pages():
"""
Load HTML resources found in templates folder
"""
print "accessing the /pages route"
files = filter(os.listdir('./templates'), '*.html')
pages = [{'name':file, 'html':render_template(file)} for file in files]
return jsonify(collection=pages)

@app.route('/quitter', methods=['POST'])
def quitter():
"""
Expand Down
65 changes: 50 additions & 15 deletions static/js/psiturk.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,49 @@ var TaskView = Backbone.View.extend({
Backbone.Notifications.on('_psiturk_finishedtask', function(msg) {
$(window).off("beforeunload");
});

},

});
var taskview = new TaskView();


/****************
* HTML PAGES *
***************/
var Page = Backbone.Model.extend({
defaults: {
name: "",
html: ""
}
});
var PageCollection = Backbone.Collection.extend({

model: Page,
url: '/pages',

// need this because Flask won't return JSON with
// array at the top level
parse: function(response) {
return response.collection;
},

getHTML: function(pagename, callback) {

matches = this.where({name: pagename});
if (matches.length > 0) {
html = matches[0].get('html');
} else {
html = "Page not found";
};
callback(html);
},


});
var pages = new PageCollection();
pages.fetch({async:false});



/****************
* MODEL *
Expand All @@ -75,7 +111,7 @@ var TaskData = Backbone.Model.extend({
this.set({"currenttrial": this.get("currenttrial")+1});
},

addQuestionData: function(field, response) {
addTabularData: function(field, response) {
qd = this.get("questiondata");
qd[field] = response;
this.set("questiondata", qd);
Expand All @@ -85,26 +121,25 @@ var TaskData = Backbone.Model.extend({
var taskdata = new TaskData();


// Data handling functions
/*
var savedata = function(callbacks) {
// TODO: app.py must be updated to accept a PUT with /data/assignmentid
var exceptions = exceptions || [];
taskdata.save(callbacks);
};
*/

/*******
* API *
******/
var psiTurk = {

// Get HTML file from collection and pass on to any callback
getPage: function(pagename, callback) {
pages.getHTML(pagename, callback);
},

// Use to add a line of data with any number of columns
addTrialData: function(trialdata) {
taskdata.addTrialData(trialdata);
},

addQuestionData: function(field, response) {
taskdata.addQuestionData(field, response);
// Use to add data value for one column. If a value already
// exists for that column, it will be overwritten
addTabularData: function(field, value) {
taskdata.addTabularData(field, value);
},

finishInstructions: function(optmessage) {
Expand All @@ -115,8 +150,8 @@ var psiTurk = {
Backbone.Notifications.trigger('_psiturk_finishedtask', optmessage);
},

saveData: function() {
taskdata.save();
saveData: function(callbacks) {
taskdata.save(callbacks);
},

};
Expand Down
84 changes: 37 additions & 47 deletions static/js/task.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,77 +137,58 @@ var recordtesttrial = function (word, color, trialtype, resp, hit, rt ) {
psiTurk.addTrialData([workerId, assignmentId, currenttrial, "TEST", word, color, hit, resp, hit, rt]);
};

// TODO this url needs to bring the next screen, we're no longer doing it with a POST
// Also questionnaire answers are now saved separately from the main csv.
var thanksurl = "/thanks";
// TODO: Make posterror prompt to resubmit.
var posterror = function() { alert( "There was an error submitting." ); };
// TODO: Make sure taskfinished works properly
var taskfinished = function() { window.location = thanksurl; };

/*var finalsave = function() {
psiTurk.saveData({error: posterror, success: taskfinished});
};*/



/********************
* HTML snippets
********************/
var pages = {};

var showpage = function(pagename) {
$('body').html( pages[pagename] );
psiTurk.getPage(pagename, replacebody);
};

var replacebody = function(pagehtml) {
$('body').html(pagehtml);
};

var pagenames = [
"postquestionnaire",
"test",
"instruct"
var instructpages = [
"instruct.html"
];



/************************
* CODE FOR INSTRUCTIONS *
************************/
var Instructions = function( screens ) {
var that = this,
currentscreen = "",
currentscreen = 0,
timestamp;

// TODO: Replace this with a backbone collection that fills itself with the appropriate values
// TODO Values should probably be defined in the config or something.
for( i=0; i<screens.length; i++) {
pagename = screens[i];
$.ajax({
url: pagename + ".html",
success: function(pagename){ return function(page){ pages[pagename] = page; }; }(pagename),
async: false
});
}

this.recordtrial = function() {
rt = (new Date().getTime()) - timestamp;
recordinstructtrial( currentscreen, rt );
};

this.nextForm = function () {
var next = screens.splice(0, 1)[0];
currentscreen = next;
showpage( next );

showpage(instructpages[currentscreen]);
currentscreen = currentscreen + 1;

timestamp = new Date().getTime();
if ( screens.length === 0 ) $('.continue').click(function() {
that.recordtrial();
that.startTest();
});
else $('.continue').click( function() {
that.recordtrial();
that.nextForm();
});
if ( currentscreen == instructpages.length ) {
$('.continue').click(function() {
that.recordtrial();
that.startTest();
});
} else { $('.continue').click( function() {
that.recordtrial();
that.nextForm();
});
};
};
this.startTest = function() {

// Backbone.Notifications.trigger('_psiturk_finishedistructions', optoutmessage);
psiTurk.finishInstructions();
testobject = new TestPhase();
};
Expand All @@ -232,7 +213,7 @@ var TestPhase = function() {

var acknowledgment = '<p>Thanks for your response!</p>';
var textprompt = '<p id="prompt">Type<br> "R" for Red<br>"B" for blue<br>"G" for green.';
showpage( 'test' );
showpage('test.html');

var addprompt = function() {
buttonson = new Date().getTime();
Expand Down Expand Up @@ -324,14 +305,23 @@ var TestPhase = function() {
* Questionnaire *
****************/

// TODO this url needs to bring the next screen, we're no longer doing it with a POST
// Also questionnaire answers are now saved separately from the main csv.
var thanksurl = "/thanks";
// TODO: Make posterror prompt to resubmit.
var posterror = function() { alert( "There was an error submitting." ); };
// TODO: Make sure taskfinished works properly
//var taskfinished = function() { window.location = thanksurl; };
var taskfinished = function() { showpage('thanks.html') };

// We may want this to end up being a backbone view
var givequestionnaire = function() {
var timestamp = new Date().getTime();
showpage('postquestionnaire');
showpage('postquestionnaire.html');
recordinstructtrial("postquestionnaire", (new Date().getTime())-timestamp );
$("#continue").click(function () {
addqustionnaire();
psiTurk.teardownTask(); // including final save
psiTurk.teardownTask();
psiTurk.saveData({error: posterror, success: taskfinished});

});
Expand All @@ -340,10 +330,10 @@ var givequestionnaire = function() {
};
var addqustionnaire = function() {
$('textarea').each( function(i, val) {
psiTurk.addQuestionData(this.id, this.value);
psiTurk.addTabularData(this.id, this.value);
});
$('select').each( function(i, val) {
psiTurk.addQuestionData(this.id, this.value);
psiTurk.addTabularData(this.id, this.value);
});
};

Expand Down
11 changes: 0 additions & 11 deletions templates/exp.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,6 @@
{% endif %}
}

// TODO replace with a Backbone model
// Load resources then run the exp
$.ajaxSetup({cache: false});
for (i=0; i<pagenames.length; i++) {
var pagename = pagenames[i];
$.ajax({
url: pagename + ".html",
success: function(pagename){ return function(page){ pages[pagename] = page; } }(pagename),
async: false
});
}
runfun();
});
</script>
Expand Down

0 comments on commit 93769a2

Please sign in to comment.