Skip to content

Commit

Permalink
More work on SlickGrid
Browse files Browse the repository at this point in the history
  • Loading branch information
danieldickison committed Aug 30, 2011
1 parent 6c0d130 commit b62e4ef
Show file tree
Hide file tree
Showing 18 changed files with 200 additions and 833 deletions.
177 changes: 101 additions & 76 deletions src/TestHarness/clientjs/instructor.js
@@ -1,6 +1,7 @@
"use strict";

require('./common/Utilities');
var constants = require('./common/Constants'),
util = require('./common/Utilities');

$(document).ready(function ()
{
Expand Down Expand Up @@ -73,36 +74,87 @@ $(document).ready(function ()
$('#new-student-dialog').dialog('open');
});

function submitNewStudent()

// Table data

function connectGridToDataView(grid, dataView)
{
$.post(here + 'student', $('#new-student-dialog form').serialize())
.success(function (data)
{
addStudentToTable(0, data.student);
$('#new-student-dialog').dialog('close');
})
.error(function (jqXHR, statusText, errorThrown)
{
alert('Error saving student: ' + jqXHR.responseText);
})
.complete(function ()
grid.onSort = function (sortCol, sortAsc)
{
var field = sortCol.field;
var sortFun = function (item1, item2)
{
//unlock();
});
var a = item1[field],
b = item2[field];
return util.compare(a, b);
};
dataView.sort(sortFun, sortAsc);
};
dataView.onRowCountChanged.subscribe(function ()
{
grid.updateRowCount();
grid.render();
});
dataView.onRowsChanged.subscribe(function (rows)
{
grid.removeRows(rows);
grid.render();
});
}

var studentGrid = new Slick.Grid($('#student-table'), [],
function formatTimestamp(row, cell, value, columnDef, dataContext)
{
return util.dateFormat(value * 1000, 'm/d HH:MM');
}
function formatDuration(row, cell, value, columnDef, dataContext)
{
return Math.round(value / 1000) + ' s'
}
function formatMedal(row, cell, value, columnDef, dataContext)
{
var medal = constants.medal.codeToString(value);
return '<div class="medal ' + medal + '">' + medal + '</div>';
}
function formatEndState(row, cell, value, columnDef, dataContext)
{
var endState = constants.endState.codeToString(value);
return '<div class="end-state ' + endState + '">' + endState + '</div>';
}

var studentDataView = new Slick.Data.DataView();
var studentGrid = new Slick.Grid($('#student-table'), studentDataView.rows,
[
{id:'instructorLoginID', field:'instructorLoginID', name:'Instructor'},
{id:'rosterID', field:'rosterID', name:'Roster ID'},
{id:'firstName', field:'firstName', name:'First Name'},
{id:'lastName', field:'lastName', name:'Last Name'},
{id:'loginID', field:'loginID', name:'Login ID'},
{id:'instructorLoginID', field:'instructorLoginID', name:'Instructor', sortable:true},
{id:'rosterID', field:'rosterID', name:'Roster ID', sortable:true},
{id:'firstName', field:'firstName', name:'First Name', sortable:true},
{id:'lastName', field:'lastName', name:'Last Name', sortable:true},
{id:'loginID', field:'loginID', name:'Login ID', sortable:true},
{id:'password', field:'password', name:'Password'},
{id:'condition', field:'condition', name:'Condition'},
{id:'gameCount', field:'gameCount', name:'Games Played'}
{id:'condition', field:'condition', name:'Condition', sortable:true},
{id:'gameCount', field:'gameCount', name:'Games', sortable:true}
],
{});
{
forceFitColumns: true
});
connectGridToDataView(studentGrid, studentDataView);

var gamesDataView = new Slick.Data.DataView();
var gamesGrid = new Slick.Grid($('#games-table'), gamesDataView.rows,
[
{id:'loginID', field:'loginID', name:'Login ID', sortable:true},
{id:'condition', field:'condition', name:'Condition', sortable:true},
{id:'stageID', field:'stageID', name:'Level', sortable:true},
{id:'questionSetID', field:'questionSetID', name:'Set', sortable:true},
{id:'score', field:'score', name:'Score', sortable:true},
{id:'medal', field:'medal', name:'Medal', sortable:true, formatter:formatMedal},
{id:'elapsedMS', field:'elapsedMS', name:'Duration', sortable:true, formatter:formatDuration},
{id:'endTime', field:'endTime', name:'Date', sortable:true, formatter:formatTimestamp},
{id:'endState', field:'endState', name:'End', sortable:true, formatter:formatEndState}
],
{
forceFitColumns: true
});
connectGridToDataView(gamesGrid, gamesDataView);
/*
.delegate('tr', 'click', function ()
{
Expand Down Expand Up @@ -160,12 +212,9 @@ $(document).ready(function ()
if (FLUENCY.isAdmin)
{
//fetchInstructors();
fetchStudents();
}
else
{
fetchStudents(FLUENCY.loginID);
}
fetchStudents();
fetchResults();

function makeXHRErrorHandler(message)
{
Expand All @@ -191,64 +240,40 @@ $(document).ready(function ()
$.getJSON(here + 'student')
.success(function (data)
{
console.log('setting data to:');
console.log(data.students);
studentGrid.setData(data.students);
studentGrid.updateRowCount();
studentGrid.render();
studentDataView.beginUpdate();
studentDataView.setItems(data.students);
studentDataView.endUpdate();
})
.error(makeXHRErrorHandler('Error fetching students: '));
}

function fetchResults(studentID)
function fetchResults()
{
//$.getJSON(here + instructorID + '/student/' + studentID + '/result')
$.getJSON(here + '/student/result')
$.getJSON(here + 'student/result')
.success(function (data)
{
$.each(data.results, addResultsToTable);
gamesDataView.beginUpdate();
gamesDataView.setItems(data.results);
gamesDataView.endUpdate();
})
.error(makeXHRErrorHandler('Error fetching game results: '));
}

function addInstructorToTable(index, json)
function submitNewStudent()
{
var cols = [

];
$('#instructor-table').dataTable().fnAddData(cols);
}

function addStudentToTable(index, json)
{
var cols = [
json.instructorLoginID,
json.rosterID,
json.firstName,
json.lastName,
json.loginID,
json.password,
json.condition,
json.gameCount
];
$('#student-table').dataTable().fnAddData(cols);
}

function addResultsToTable(index, json)
{
var cols = [
json.rosterID,
json.loginID,
json.condition,
json.stageID,
json.questionSetID,
json.score,
json.medal,
json.elapsedMS,
json.endTime,
json.endState,
json.dataFile
];
$('#games-table').dataTable().fnAddData(cols);
$.post(here + 'student', $('#new-student-dialog form').serialize())
.success(function (data)
{
studentDataView.addItem(data.student);
$('#new-student-dialog').dialog('close');
})
.error(function (jqXHR, statusText, errorThrown)
{
alert('Error saving student: ' + jqXHR.responseText);
})
.complete(function ()
{
//unlock();
});
}
});
5 changes: 3 additions & 2 deletions src/TestHarness/gamecontroller.js
Expand Up @@ -7,6 +7,7 @@ var fs = require('fs'),
path = require('path'),
GameController = require('../common/GameController').GameController,
QuestionHierarchy = require('../common/QuestionHierarchy'),
constants = require('../common/Constants'),
util = require('../common/Utilities');


Expand Down Expand Up @@ -124,8 +125,8 @@ exports.gameController = function (serverConfig, model)
endTime: Math.round(timestamp / 1000),
elapsedMS: scoreAttr.ElapsedTime || scoreAttr.TOTAL_ELAPSED_TIME || 0,
score: scoreAttr.TotalScore || scoreAttr.TOTAL_SCORE || 0,
endState: model.QuestionSetOutcome.endStateCode(endAttr.STATE),
medal: model.QuestionSetOutcome.medalCode(scoreAttr.Medal || scoreAttr.MEDAL_EARNED || 'none')
endState: constants.endState.stringToCode(endAttr.STATE),
medal: constants.medal.stringToCode(scoreAttr.Medal || scoreAttr.MEDAL_EARNED || 'none')
};

async.parallel([
Expand Down
34 changes: 16 additions & 18 deletions src/TestHarness/instructorserver.js
Expand Up @@ -8,6 +8,7 @@ var csv = require('csv'),
rimraf = require('rimraf'),
path = require('path'),
spawn = require('child_process').spawn,
constants = require('../common/Constants'),
util = require('../common/Utilities');

exports.addInstructorEndpoints = function (app, rootPath, gc, model, config)
Expand Down Expand Up @@ -65,7 +66,7 @@ exports.addInstructorEndpoints = function (app, rootPath, gc, model, config)
});
});

app.get(rootPath + '/instructor/student/result.:format?', function (req, res)
app.get(rootPath + '/instructor/student/result', function (req, res)
{
getResults(req.instructor, function (error, results, fields)
{
Expand All @@ -76,22 +77,7 @@ exports.addInstructorEndpoints = function (app, rootPath, gc, model, config)
}
else
{
for (var i = 0; i < results.length; i++)
{
var r = results[i];
r.medal = model.QuestionSetOutcome.medalString(r.medal);
r.endState = model.QuestionSetOutcome.endStateString(r.endState);
}
if (req.params.format == 'csv')
{
res.header('Content-Type', 'text/csv');
res.header('Content-Disposition', 'attachment; filename="game-results.csv"');
outputCSV(res, results, fields);
}
else
{
res.send({results: results});
}
res.send({results: results});
}
});
});
Expand Down Expand Up @@ -124,9 +110,10 @@ exports.addInstructorEndpoints = function (app, rootPath, gc, model, config)
student.password = req.body.password
student.condition = condition

student.setInstructor(req.instructor).on('success', function ()
student.setInstructor(req.instructor).on('success', function (student)
{
var json = student.toJSON();
json.id = student.id;
json.instructorLoginID = req.instructor.loginID;
json.gameCount = null;
res.send({
Expand Down Expand Up @@ -285,6 +272,15 @@ exports.addInstructorEndpoints = function (app, rootPath, gc, model, config)
{
if (err) return callback(err);

// Replace coded fields with strings.
for (var i = 0; i < results.length; i++)
{
var r = results[i];
r.medal = constants.medal.codeToString(r.medal);
r.endState = constants.endState.codeToString(r.endState);
r.endTime = util.dateFormat(r.endTime * 1000, 'yyyy-mm-dd HH:MM:ss Z', true);
}

async.parallel([
function (callback)
{
Expand Down Expand Up @@ -365,6 +361,7 @@ exports.addInstructorEndpoints = function (app, rootPath, gc, model, config)
var params = [];
var query = '\
SELECT \
Students.id, \
Students.rosterID, \
Students.loginID, \
Students.firstName, \
Expand Down Expand Up @@ -401,6 +398,7 @@ exports.addInstructorEndpoints = function (app, rootPath, gc, model, config)
var params = [];
var query = '\
SELECT \
QuestionSetOutcomes.id,\
Students.rosterID, \
Students.loginID, \
QuestionSetOutcomes.condition, \
Expand Down
27 changes: 0 additions & 27 deletions src/TestHarness/model.js
Expand Up @@ -74,33 +74,6 @@ module.exports = function model(db, user, password, options, callback)
condition: Sequelize.STRING,
stageID: Sequelize.STRING,
questionSetID: Sequelize.STRING
},
{
classMethods: {
medalString: function (medal)
{
return ['none', 'bronze', 'silver', 'gold'][medal || 0];
},
medalCode: function (str)
{
return {
g: 3,
s: 2,
b: 1
}[str && str.length > 0 && str.charAt(0).toLowerCase()] || 0;
},
endStateString: function (endState)
{
return ['completed', 'aborted'][endState] || 'unknown';
},
endStateCode: function (str)
{
return {
FINISH: 0,
ABORT: 1
}[str];
}
}
});

model.Student.hasMany(model.QuestionSetOutcome);
Expand Down

0 comments on commit b62e4ef

Please sign in to comment.