diff --git a/README.md b/README.md
index dec285d123..f3d8dfa634 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,13 @@ Before you begin we recommend you read about the basic building blocks that asse
* AngularJS - Angular's [Official Website](http://angularjs.org/) is a great starting point. You can also use [Thinkster Popular Guide](http://www.thinkster.io/), and the [Egghead Videos](https://egghead.io/).
* Node.js - Start by going through [Node.js Official Website](http://nodejs.org/) and this [StackOverflow Thread](http://stackoverflow.com/questions/2353818/how-do-i-get-started-with-node-js), which should get you going with the Node.js platform in no time.
+## Use MongoLabs - insert in server.js
+var db = mongoose.connect('mongodb://cce:cce@ds039860.mongolab.com:39860/meandb', function(err) {
+ if (err) {
+ console.error('\x1b[31m', 'Could not connect to MongoLabDB!');
+ console.log(err);
+ }
+});
## Prerequisites
Make sure you have installed all these prerequisites on your development machine.
diff --git a/app/controllers/qas.server.controller.js b/app/controllers/qas.server.controller.js
new file mode 100644
index 0000000000..4ff4a6a9e7
--- /dev/null
+++ b/app/controllers/qas.server.controller.js
@@ -0,0 +1,129 @@
+'use strict';
+
+/**
+ * Module dependencies...
+ */
+var mongoose = require('mongoose'),
+ Qa = mongoose.model('Qa'),
+ _ = require('lodash');
+
+/**
+ * Get the error message from error object
+ */
+var getErrorMessage = function(err) {
+ var message = '';
+
+ if (err.code) {
+ switch (err.code) {
+ case 11000:
+ case 11001:
+ message = 'Qa already exists';
+ break;
+ default:
+ message = 'Something went wrong';
+ }
+ } else {
+ for (var errName in err.errors) {
+ if (err.errors[errName].message) message = err.errors[errName].message;
+ }
+ }
+
+ return message;
+};
+
+/**
+ * Create a Qa
+ */
+exports.create = function(req, res) {
+ var qa = new Qa(req.body);
+ qa.user = req.user;
+
+ qa.save(function(err) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(qa);
+ }
+ });
+};
+
+/**
+ * *
+ * Show the current Qa
+ */
+exports.read = function(req, res) {
+ res.jsonp(req.qa);
+};
+
+/**
+ * Update a Qa
+ */
+exports.update = function(req, res) {
+ var qa = req.qa ;
+
+ qa = _.extend(qa , req.body);
+
+ qa.save(function(err) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(qa);
+ }
+ });
+};
+
+/**
+ * Delete an Qa
+ */
+exports.delete = function(req, res) {
+ var qa = req.qa ;
+
+ qa.remove(function(err) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(qa);
+ }
+ });
+};
+
+/**
+ * List of Qas
+ */
+exports.list = function(req, res) { Qa.find().sort('-created').populate('user', 'displayName').exec(function(err, qas) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(qas);
+ }
+ });
+};
+
+/**
+ * Qa middleware
+ */
+exports.qaByID = function(req, res, next, id) { Qa.findById(id).populate('user', 'displayName').exec(function(err, qa) {
+ if (err) return next(err);
+ if (! qa) return next(new Error('Failed to load Qa ' + id));
+ req.qa = qa ;
+ next();
+ });
+};
+
+/**
+ * Qa authorization middleware
+ */
+exports.hasAuthorization = function(req, res, next) {
+ if (req.qa.user.id !== req.user.id) {
+ return res.send(403, 'User is not authorized');
+ }
+ next();
+};
\ No newline at end of file
diff --git a/app/controllers/quizzes.server.controller.js b/app/controllers/quizzes.server.controller.js
new file mode 100644
index 0000000000..1925645ada
--- /dev/null
+++ b/app/controllers/quizzes.server.controller.js
@@ -0,0 +1,129 @@
+'use strict';
+
+/**
+ * Module dependencies...
+ */
+var mongoose = require('mongoose'),
+ Quiz = mongoose.model('Quiz'),
+ _ = require('lodash');
+
+/**
+ * Get the error message from error object
+ */
+var getErrorMessage = function(err) {
+ var message = '';
+
+ if (err.code) {
+ switch (err.code) {
+ case 11000:
+ case 11001:
+ message = 'Quiz already exists';
+ break;
+ default:
+ message = 'Something went wrong';
+ }
+ } else {
+ for (var errName in err.errors) {
+ if (err.errors[errName].message) message = err.errors[errName].message;
+ }
+ }
+
+ return message;
+};
+
+/**
+ * Create a Quiz
+ */
+exports.create = function(req, res) {
+ var quiz = new Quiz(req.body);
+ quiz.user = req.user;
+
+ quiz.save(function(err) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(quiz);
+ }
+ });
+};
+
+/**
+ * *
+ * Show the current Quiz
+ */
+exports.read = function(req, res) {
+ res.jsonp(req.quiz);
+};
+
+/**
+ * Update a Quiz
+ */
+exports.update = function(req, res) {
+ var quiz = req.quiz ;
+
+ quiz = _.extend(quiz , req.body);
+
+ quiz.save(function(err) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(quiz);
+ }
+ });
+};
+
+/**
+ * Delete an Quiz
+ */
+exports.delete = function(req, res) {
+ var quiz = req.quiz ;
+
+ quiz.remove(function(err) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(quiz);
+ }
+ });
+};
+
+/**
+ * List of quizzes
+ */
+exports.list = function(req, res) { Quiz.find().sort('-created').populate('user', 'displayName').exec(function(err, quizzes) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(quizzes);
+ }
+ });
+};
+
+/**
+ * Quiz middleware
+ */
+exports.quizByID = function(req, res, next, id) { Quiz.findById(id).populate('user', 'displayName').exec(function(err, quiz) {
+ if (err) return next(err);
+ if (! quiz) return next(new Error('Failed to load Quiz ' + id));
+ req.quiz = quiz ;
+ next();
+ });
+};
+
+/**
+ * Quiz authorization middleware
+ */
+exports.hasAuthorization = function(req, res, next) {
+ if (req.quiz.user.id !== req.user.id) {
+ return res.send(403, 'User is not authorized');
+ }
+ next();
+};
\ No newline at end of file
diff --git a/app/controllers/takers.server.controller.js b/app/controllers/takers.server.controller.js
new file mode 100644
index 0000000000..27faa175ac
--- /dev/null
+++ b/app/controllers/takers.server.controller.js
@@ -0,0 +1,128 @@
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+var mongoose = require('mongoose'),
+ Taker = mongoose.model('Taker'),
+ _ = require('lodash');
+
+/**
+ * Get the error message from error object
+ */
+var getErrorMessage = function(err) {
+ var message = '';
+
+ if (err.code) {
+ switch (err.code) {
+ case 11000:
+ case 11001:
+ message = 'Taker already exists';
+ break;
+ default:
+ message = 'Something went wrong';
+ }
+ } else {
+ for (var errName in err.errors) {
+ if (err.errors[errName].message) message = err.errors[errName].message;
+ }
+ }
+
+ return message;
+};
+
+/**
+ * Create a Taker
+ */
+exports.create = function(req, res) {
+ var taker = new Taker(req.body);
+ taker.user = req.user;
+
+ taker.save(function(err) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(taker);
+ }
+ });
+};
+
+/**
+ * Show the current Taker
+ */
+exports.read = function(req, res) {
+ res.jsonp(req.taker);
+};
+
+/**
+ * Update a Taker
+ */
+exports.update = function(req, res) {
+ var taker = req.taker ;
+
+ taker = _.extend(taker , req.body);
+
+ taker.save(function(err) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(taker);
+ }
+ });
+};
+
+/**
+ * Delete an Taker
+ */
+exports.delete = function(req, res) {
+ var taker = req.taker ;
+
+ taker.remove(function(err) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(taker);
+ }
+ });
+};
+
+/**
+ * List of Takers
+ */
+exports.list = function(req, res) { Taker.find().sort('-created').populate('user', 'displayName').exec(function(err, takers) {
+ if (err) {
+ return res.send(400, {
+ message: getErrorMessage(err)
+ });
+ } else {
+ res.jsonp(takers);
+ }
+ });
+};
+
+/**
+ * Taker middleware
+ */
+exports.takerByID = function(req, res, next, id) { Taker.findById(id).populate('user', 'displayName').exec(function(err, taker) {
+ if (err) return next(err);
+ if (! taker) return next(new Error('Failed to load Taker ' + id));
+ req.taker = taker ;
+ next();
+ });
+};
+
+/**
+ * Taker authorization middleware
+ */
+exports.hasAuthorization = function(req, res, next) {
+ if (req.taker.user.id !== req.user.id) {
+ return res.send(403, 'User is not authorized');
+ }
+ next();
+};
\ No newline at end of file
diff --git a/app/models/qa.server.model.js b/app/models/qa.server.model.js
new file mode 100644
index 0000000000..6524d7aec4
--- /dev/null
+++ b/app/models/qa.server.model.js
@@ -0,0 +1,136 @@
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+var mongoose = require('mongoose'),
+ Schema = mongoose.Schema;
+
+//
+// Answer Schema
+//
+var AnswerSchema = new mongoose.Schema({
+ text: String,
+ selectedAnswer: {
+ type: Boolean,
+ default: false
+ }});
+
+var qaQuizSchema = new mongoose.Schema({
+ name: String,
+ id: Number,
+ selected: {
+ type: Boolean,
+ default: false
+ }});
+/**
+ * Qa Schema
+ */
+var QaSchema = new Schema({
+ created: {
+ type: Date,
+ default: Date.now
+ },
+ selected: {
+ type: Boolean,
+ default: false
+ },
+ question: {
+ type: String,
+ default: '',
+ trim: true
+
+ },
+ questionNumber: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ imageURL: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ choices: [AnswerSchema],
+ hint: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ user: {
+ type: Schema.ObjectId,
+ ref: 'User'
+ },
+ difficulty: {
+ type: String,
+ default: 'Easy',
+ trim: true
+ },
+ type: {
+ type: String,
+ default: 'FIB',
+ trim: true
+ },
+ hintOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ timeOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ fifty50On: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ randomizeQuestionsOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ randomizeAnswersOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+
+ },
+ qaQuizId: {
+ type: String,
+ default: 999
+ },
+ qaQuizName: {
+ type: String,
+ default: 'Quiz'
+ },
+ qaQuiz: [qaQuizSchema],
+ quiz: {
+ type: Schema.ObjectId,
+ ref: 'Quiz'
+ }
+});
+
+//console.log(AnswerSchema);
+
+/**
+ * Validations
+ */
+QaSchema.path('question').validate(function(question) {
+ return question.length;
+}, 'Question cannot be blank');
+
+/**
+ * Statics
+ */
+QaSchema.statics = {
+ load: function(id, cb) {
+ this.findOne({
+ _id: id
+ }).populate('user', 'displayName').exec(cb);
+ }
+};
+//console.log(QaSchema);
+mongoose.model('Qa', QaSchema);
+mongoose.model('Answer', AnswerSchema);
diff --git a/app/models/quiz.server.model.js b/app/models/quiz.server.model.js
new file mode 100644
index 0000000000..6330dc7032
--- /dev/null
+++ b/app/models/quiz.server.model.js
@@ -0,0 +1,72 @@
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+var mongoose = require('mongoose'),
+ Schema = mongoose.Schema;
+
+/**
+ * Quiz Schema
+ */
+var QuizSchema = new Schema({
+ name: {
+ type: String,
+ default: '',
+ required: 'Please fill Quiz name',
+ trim: true
+ },
+ created: {
+ type: Date,
+ default: Date.now
+ },
+ user: {
+ type: Schema.ObjectId,
+ ref: 'User'
+ },
+ quizNumber: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ category: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ keyWords: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ hintOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ timeOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ fifty50On: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ randomizeQuestionsOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ randomizeAnswersOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+
+ },
+ qa: [{ type: Schema.ObjectId, ref: 'Qa' }]
+
+});
+
+mongoose.model('Quiz', QuizSchema);
diff --git a/app/models/taker.server.model.js b/app/models/taker.server.model.js
new file mode 100644
index 0000000000..e2f4db4dd1
--- /dev/null
+++ b/app/models/taker.server.model.js
@@ -0,0 +1,174 @@
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+var mongoose = require('mongoose'),
+ Schema = mongoose.Schema;
+ var takerAnswerSchema = new mongoose.Schema({
+ text: String,
+ correctAnswer: Boolean});
+/**
+ * QA Schema
+ */
+var takerQASchema = new Schema({
+ created: {
+ type: Date,
+ default: Date.now
+ },
+ question: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ questionNumber: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ imageURL: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ choices: [takerAnswerSchema],
+ hint: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ user: {
+ type: Schema.ObjectId,
+ ref: 'User'
+ },
+ difficulty: {
+ type: String,
+ default: 'Easy',
+ trim: true
+ },
+ type: {
+ type: String,
+ default: 'FIB',
+ trim: true
+ },
+ hintOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ timeOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ fifty50On: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ randomizeQuestionsOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+ },
+ randomizeAnswersOn: {
+ type: Boolean,
+ default: false,
+ trim: true
+
+ }
+});
+
+
+/**
+ * Statics
+ */
+takerQASchema.statics = {
+ load: function(id, cb) {
+ this.findOne({
+ _id: id
+ }).populate('user', 'displayName').exec(cb);
+ }
+};
+//
+// AnswerCorrect Schema
+//
+var AnswerSelectedSchema = new mongoose.Schema({
+ text: String,
+ isSelected: Number});
+
+
+
+var TakerAnswersSchema = new Schema({
+ updated: {
+ type: Date,
+ default: Date.now
+ },
+ questionViewed: {
+ type: Boolean,
+ default: false
+ },
+ questionAnswered: {
+ type: Boolean,
+ default: false
+ },
+ questionNumber: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ answer: [AnswerSelectedSchema]
+
+});
+
+//console.log(TakerResultsSchema);
+
+
+var TakerSchema = new Schema({
+ updated: {
+ type: Date,
+ default: Date.now
+ },
+
+ quizNumber: {
+ type: Number,
+ default: 0
+ },
+ trialNumber: {
+ type: Number,
+ default: 0
+ },
+ trialOptions: {
+ type: String,
+ default: '',
+ trim: true
+ },
+ results: [TakerAnswersSchema],
+ qa:[takerQASchema]
+
+});
+
+ //Validations
+
+//QASchema.path('question').validate(function(question) {
+// return question.length;
+//}, 'Question cannot be blank');
+
+
+ // Statics
+
+ TakerSchema.statics = {
+ load: function(id, cb) {
+ this.findOne({
+ _id: id
+ }).populate('user', 'displayName').exec(cb);
+ }
+};
+
+mongoose.model('takerQA', takerQASchema);
+mongoose.model('takerAnswer', takerAnswerSchema);
+mongoose.model('AnswerSelected', AnswerSelectedSchema);
+mongoose.model('TakerAnswers', TakerAnswersSchema);
+mongoose.model('Taker', TakerSchema);
+
+
diff --git a/app/routes/qas.server.routes.js b/app/routes/qas.server.routes.js
new file mode 100644
index 0000000000..6ed1afc02b
--- /dev/null
+++ b/app/routes/qas.server.routes.js
@@ -0,0 +1,24 @@
+'use strict';
+//Routes...
+module.exports = function(app) {
+ var users = require('../../app/controllers/users');
+ var qas = require('../../app/controllers/qas');
+ var quizzes = require('../../app/controllers/qas');
+
+ // Qas Routes
+ app.route('/listQasQuizzes')
+ .get(quizzes.list)
+ .post(users.requiresLogin, quizzes.create);
+
+ app.route('/qas')
+ .get(qas.list)
+ .post(users.requiresLogin, qas.create);
+
+ app.route('/qas/:qaId')
+ .get(qas.read)
+ .put(users.requiresLogin, qas.hasAuthorization, qas.update)
+ .delete(users.requiresLogin, qas.hasAuthorization, qas.delete);
+
+ // Finish by binding the Qa middleware
+ app.param('qaId', qas.qaByID);
+};
\ No newline at end of file
diff --git a/app/routes/quizzes.server.routes.js b/app/routes/quizzes.server.routes.js
new file mode 100644
index 0000000000..4ad5563a34
--- /dev/null
+++ b/app/routes/quizzes.server.routes.js
@@ -0,0 +1,24 @@
+'use strict';
+//Routes...
+module.exports = function(app) {
+ var users = require('../../app/controllers/users');
+ var qas = require('../../app/controllers/qas');
+ var quizzes = require('../../app/controllers/quizzes');
+
+ // Qas Routes
+// app.route('/listQasQuizzes')
+// .get(quizzes.list)
+// .post(users.requiresLogin, quizzes.create);
+
+ app.route('/quizzes')
+ .get(quizzes.list)
+ .post(users.requiresLogin, quizzes.create);
+
+ app.route('/quizzes/:quizId')
+ .get(quizzes.read)
+ .put(users.requiresLogin, quizzes.hasAuthorization, quizzes.update)
+ .delete(users.requiresLogin, quizzes.hasAuthorization, qas.delete);
+
+ // Finish by binding the Qa middleware
+ app.param('quizId', quizzes.quizByID);
+};
diff --git a/app/routes/takers.server.routes.js b/app/routes/takers.server.routes.js
new file mode 100644
index 0000000000..918c323921
--- /dev/null
+++ b/app/routes/takers.server.routes.js
@@ -0,0 +1,23 @@
+'use strict';
+
+module.exports = function(app) {
+ var users = require('../../app/controllers/users');
+ var takers = require('../../app/controllers/takers');
+ var qas = require('../../app/controllers/takers');
+ var quizzes = require('../../app/controllers/takers');
+ // Takers Routes
+
+ //app.route('/listTakersQuizzes')
+ // .get(quizzes.list)
+ // .post(users.requiresLogin, quizzes.create);
+ app.route('/takers')
+ .get(takers.list)
+ .post(users.requiresLogin, takers.create);
+ app.route('/takers/:takerId')
+ .get(takers.read)
+ .put(users.requiresLogin, takers.hasAuthorization, takers.update)
+ .delete(users.requiresLogin, takers.hasAuthorization, takers.delete);
+
+ // Finish by binding the Taker middleware
+ app.param('takerId', takers.takerByID);
+};
diff --git a/app/tests/qa.server.model.test.js b/app/tests/qa.server.model.test.js
new file mode 100644
index 0000000000..0d1306cd64
--- /dev/null
+++ b/app/tests/qa.server.model.test.js
@@ -0,0 +1,64 @@
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+var should = require('should'),
+ mongoose = require('mongoose'),
+ User = mongoose.model('User'),
+ Qa = mongoose.model('Qa');
+
+/**
+ * Globals
+ */
+var user, qa;
+
+/**
+ * Unit tests
+ */
+describe('Qa Model Unit Tests:', function() {
+ beforeEach(function(done) {
+ user = new User({
+ firstName: 'Full',
+ lastName: 'Name',
+ displayName: 'Full Name',
+ email: 'test@test.com',
+ username: 'username',
+ password: 'password'
+ });
+
+ user.save(function() {
+ qa = new Qa({
+ name: 'Qa Name',
+ user: user
+ });
+
+ done();
+ });
+ });
+
+ describe('Method Save', function() {
+ it('should be able to save without problems', function(done) {
+ return qa.save(function(err) {
+ should.not.exist(err);
+ done();
+ });
+ });
+
+ it('should be able to show an error when try to save without name', function(done) {
+ qa.name = '';
+
+ return qa.save(function(err) {
+ should.exist(err);
+ done();
+ });
+ });
+ });
+
+ afterEach(function(done) {
+ Qa.remove().exec();
+ User.remove().exec();
+
+ done();
+ });
+});
\ No newline at end of file
diff --git a/app/tests/taker.server.model.test.js b/app/tests/taker.server.model.test.js
new file mode 100644
index 0000000000..f55980cd93
--- /dev/null
+++ b/app/tests/taker.server.model.test.js
@@ -0,0 +1,64 @@
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+var should = require('should'),
+ mongoose = require('mongoose'),
+ User = mongoose.model('User'),
+ Taker = mongoose.model('Taker');
+
+/**
+ * Globals
+ */
+var user, taker;
+
+/**
+ * Unit tests
+ */
+describe('Taker Model Unit Tests:', function() {
+ beforeEach(function(done) {
+ user = new User({
+ firstName: 'Full',
+ lastName: 'Name',
+ displayName: 'Full Name',
+ email: 'test@test.com',
+ username: 'username',
+ password: 'password'
+ });
+
+ user.save(function() {
+ taker = new Taker({
+ name: 'Taker Name',
+ user: user
+ });
+
+ done();
+ });
+ });
+
+ describe('Method Save', function() {
+ it('should be able to save without problems', function(done) {
+ return taker.save(function(err) {
+ should.not.exist(err);
+ done();
+ });
+ });
+
+ it('should be able to show an error when try to save without name', function(done) {
+ taker.name = '';
+
+ return taker.save(function(err) {
+ should.exist(err);
+ done();
+ });
+ });
+ });
+
+ afterEach(function(done) {
+ Taker.remove().exec();
+ User.remove().exec();
+
+ done();
+ });
+});
\ No newline at end of file
diff --git a/gruntfile.js b/gruntfile.js
index ca48bbd883..a977357986 100644
--- a/gruntfile.js
+++ b/gruntfile.js
@@ -31,7 +31,7 @@ module.exports = function(grunt) {
clientViews: {
files: watchFiles.clientViews,
options: {
- livereload: true,
+ livereload: true
}
},
clientJS: {
@@ -59,7 +59,7 @@ module.exports = function(grunt) {
},
csslint: {
options: {
- csslintrc: '.csslintrc',
+ csslintrc: '.csslintrc'
},
all: {
src: watchFiles.clientCSS
diff --git a/public/dist/application.js b/public/dist/application.js
index f59c8fee04..b5f3f6245f 100644
--- a/public/dist/application.js
+++ b/public/dist/application.js
@@ -44,6 +44,10 @@ angular.element(document).ready(function () {
ApplicationConfiguration.registerModule('articles');'use strict';
// Use Applicaion configuration module to register a new module
ApplicationConfiguration.registerModule('core');'use strict';
+// Use application configuration module to register a new module
+ApplicationConfiguration.registerModule('qas');'use strict';
+// Use applicaion configuration module to register a new module
+ApplicationConfiguration.registerModule('takers');'use strict';
// Use Applicaion configuration module to register a new module
ApplicationConfiguration.registerModule('users');'use strict';
// Configuring the Articles module
@@ -89,6 +93,7 @@ angular.module('articles').controller('ArticlesController', [
title: this.title,
content: this.content
});
+ // console.log(response);
article.$save(function (response) {
$location.path('articles/' + response._id);
$scope.title = '';
@@ -176,16 +181,20 @@ angular.module('core').controller('HomeController', [
//Menu service used for managing menus
angular.module('core').service('Menus', [function () {
// Define a set of default roles
- this.defaultRoles = ['user'];
+ this.defaultRoles = ['*'];
// Define the menus object
this.menus = {};
// A private function for rendering decision
var shouldRender = function (user) {
if (user) {
- for (var userRoleIndex in user.roles) {
- for (var roleIndex in this.roles) {
- if (this.roles[roleIndex] === user.roles[userRoleIndex]) {
- return true;
+ if (!!~this.roles.indexOf('*')) {
+ return true;
+ } else {
+ for (var userRoleIndex in user.roles) {
+ for (var roleIndex in this.roles) {
+ if (this.roles[roleIndex] === user.roles[userRoleIndex]) {
+ return true;
+ }
}
}
}
@@ -245,7 +254,7 @@ angular.module('core').service('Menus', [function () {
menuItemClass: menuItemType,
uiRoute: menuItemUIRoute || '/' + menuItemURL,
isPublic: isPublic === null || typeof isPublic === 'undefined' ? this.menus[menuId].isPublic : isPublic,
- roles: roles || this.defaultRoles,
+ roles: roles === null || typeof roles === 'undefined' ? this.menus[menuId].roles : roles,
position: position || 0,
items: [],
shouldRender: shouldRender
@@ -266,7 +275,7 @@ angular.module('core').service('Menus', [function () {
link: menuItemURL,
uiRoute: menuItemUIRoute || '/' + menuItemURL,
isPublic: isPublic === null || typeof isPublic === 'undefined' ? this.menus[menuId].items[itemIndex].isPublic : isPublic,
- roles: roles || this.defaultRoles,
+ roles: roles === null || typeof roles === 'undefined' ? this.menus[menuId].items[itemIndex].roles : roles,
position: position || 0,
shouldRender: shouldRender
});
@@ -306,6 +315,380 @@ angular.module('core').service('Menus', [function () {
//Adding the topbar menu
this.addMenu('topbar');
}]);'use strict';
+// Configuring the Articles module.
+angular.module('qas').run([
+ 'Menus',
+ function (Menus) {
+ // Set top bar menu items
+ Menus.addMenuItem('topbar', 'Qas', 'qas', 'dropdown', '/qas(/create)?');
+ Menus.addSubMenuItem('topbar', 'qas', 'List Qas', 'qas');
+ Menus.addSubMenuItem('topbar', 'qas', 'New Qa', 'qas/create');
+ }
+]);'use strict';
+//Setting up route...
+angular.module('qas').config([
+ '$stateProvider',
+ function ($stateProvider) {
+ // Qas state routing
+ $stateProvider.state('listQas', {
+ url: '/qas',
+ templateUrl: 'modules/qas/views/list-qas.client.view.html'
+ }).state('createQa', {
+ url: '/qas/create',
+ templateUrl: 'modules/qas/views/create-qa.client.view.html'
+ }).state('viewQa', {
+ url: '/qas/:qaId',
+ templateUrl: 'modules/qas/views/view-qa.client.view.html'
+ }).state('editQa', {
+ url: '/qas/:qaId/edit',
+ templateUrl: 'modules/qas/views/edit-qa.client.view.html'
+ });
+ }
+]);'use strict';
+// Qas controller...
+angular.module('qas').controller('QasController', [
+ '$scope',
+ '$stateParams',
+ '$location',
+ 'Authentication',
+ 'Qas',
+ 'CalculatorService',
+ 'MathService',
+ 'qasInitService',
+ function ($scope, $stateParams, $location, Authentication, Qas, CalculatorService, MathService, qasInitService) {
+ $scope.authentication = Authentication;
+ //Test of Calculator and Math Service
+ $scope.doit = CalculatorService.cce(77);
+ // Initialize Dropdown labels
+ $scope.typeDropdown = qasInitService.typeDropdown();
+ $scope.difficultyDropdown = qasInitService.difficultyDropdown();
+ $scope.qa = qasInitService.init();
+ // Create and validate qa entries
+ $scope.create = function () {
+ var qa = new Qas({
+ question: this.question,
+ imageURL: this.imageURL,
+ choices: [
+ {
+ text: this.text,
+ selectedAnswer: false
+ },
+ {
+ text: this.text,
+ selectedAnswer: this.correctAnswer
+ },
+ {
+ text: this.text,
+ selectedAnswer: this.correctAnswer
+ }
+ ],
+ hint: this.hint,
+ type: this.td,
+ difficulty: this.difficulty,
+ hintOn: this.hintOn,
+ timeOn: this.timeOn,
+ fifty50On: this.fifty50On,
+ randomizeQuestionsOn: this.randomizeQuestionsOn,
+ randomizeAnswersOn: this.randomizeAnswersOn
+ });
+ // Hack to load these variables. Not handled above???
+ qa.choices = $scope.qa.choices;
+ qa.difficulty = $scope.dd.label;
+ qa.type = $scope.td.label;
+ // Check that question was entered
+ if (qa.question.length > 0) {
+ var choiceCount = 0;
+ //Loop through choices to get at least two
+ console.log('qa if', qa);
+ for (var i = 0, ln = qa.choices.length; i < ln; i++) {
+ var choice = qa.choices[i].text;
+ console.log('choice', choice, ' i', i);
+ if (choice.length > 0) {
+ choiceCount++;
+ }
+ }
+ if (choiceCount > 1) {
+ } else {
+ alert('You must have at least two choices');
+ }
+ } else {
+ alert('You must have a question');
+ }
+ console.log('qaFinal', qa);
+ qa.$save(function (response) {
+ $location.path('qas/' + response._id);
+ });
+ };
+ // Method to add an additional choice option
+ $scope.addChoice = function () {
+ console.log('qa add', $scope.qa);
+ $scope.qa.choices.push({
+ text: this.text,
+ selectedAnswer: false
+ });
+ };
+ $scope.remove = function (qa) {
+ if (qa) {
+ qa.$remove();
+ for (var i in $scope.qas) {
+ if ($scope.qas[i] === qa) {
+ $scope.qas.splice(i, 1);
+ }
+ }
+ } else {
+ $scope.qa.$remove(function () {
+ $location.path('qas');
+ });
+ }
+ };
+ $scope.update = function () {
+ var qa = $scope.qa;
+ console.log('From update', qa);
+ if (!qa.updated) {
+ qa.updated = [];
+ }
+ qa.updated.push(new Date().getTime());
+ qa.$update(function () {
+ $location.path('qas/' + qa._id);
+ });
+ };
+ $scope.find = function () {
+ Qas.query(function (qas) {
+ $scope.qas = qas;
+ });
+ };
+ $scope.findOne = function () {
+ Qas.get({ qaId: $stateParams.qaId }, function (qa) {
+ $scope.qa = qa;
+ });
+ };
+ $scope.deleteChoice = function (ev) {
+ var ss = ev.target.innerText.toString() - 1;
+ console.log(ss);
+ var qa = $scope.qa;
+ console.log(qa);
+ $scope.qa.choices.splice(ss, 1);
+ };
+ }
+]);'use strict';
+//Qas service used to communicate Qas REST endpoints
+angular.module('qas').factory('Qas', [
+ '$resource',
+ function ($resource) {
+ return $resource('qas/:qaId', { qaId: '@_id' }, { update: { method: 'PUT' } });
+ }
+]);/**
+ * Created by EbyC on 8/24/2014.
+ */
+'use strict';
+angular.module('qas').service('MathService', [function () {
+ this.add = function (a, b) {
+ return a + b;
+ };
+ this.subtract = function (a, b) {
+ return a - b;
+ };
+ this.multiply = function (a, b) {
+ return a * b;
+ };
+ this.divide = function (a, b) {
+ return a / b;
+ };
+ }]).service('CalculatorService', function (MathService) {
+ this.square = function (a) {
+ return MathService.multiply(a, a);
+ };
+ this.cce = function (a) {
+ return a + a * 1000;
+ };
+ this.cube = function (a) {
+ return MathService.multiply(a, MathService.multiply(a, a));
+ };
+});/**
+ * Created by EbyC on 8/24/2014.
+ */
+'use strict';
+//Qas service used to communicate Qas REST endpoints
+angular.module('qas').service('qasInitService', [function () {
+ this.typeDropdown = function () {
+ return [
+ {
+ 'label': 'FIB',
+ 'value': 1
+ },
+ {
+ 'label': 'TF',
+ 'value': 2
+ },
+ {
+ 'label': 'MC',
+ 'value': 3
+ },
+ {
+ 'label': 'Matching',
+ 'value': 4
+ }
+ ];
+ };
+ this.difficultyDropdown = function () {
+ return [
+ {
+ 'label': 'Easy',
+ 'value': 1
+ },
+ {
+ 'label': 'Medium',
+ 'value': 2
+ },
+ {
+ 'label': 'Hard',
+ 'value': 3
+ },
+ {
+ 'label': 'Impossible',
+ 'value': 4
+ }
+ ];
+ };
+ this.init = function () {
+ return {
+ choices: [
+ {
+ text: '',
+ correctAnswer: false
+ },
+ {
+ text: '',
+ correctAnswer: false
+ },
+ {
+ text: '',
+ correctAnswer: false
+ }
+ ]
+ };
+ };
+ }]);'use strict';
+// Configuring the Takers module
+angular.module('takers').run([
+ 'Menus',
+ function (Menus) {
+ // Set top bar menu items
+ Menus.addMenuItem('topbar', 'Takers', 'takers', 'dropdown', '/takers(/create)?');
+ Menus.addSubMenuItem('topbar', 'takers', 'List Takers', 'takers');
+ Menus.addSubMenuItem('topbar', 'takers', 'New Taker', 'takers/create');
+ Menus.addSubMenuItem('topbar', 'takers', 'Take', 'takers/');
+ }
+]);'use strict';
+//Setting up route
+angular.module('takers').config([
+ '$stateProvider',
+ function ($stateProvider) {
+ // Takers state routing
+ $stateProvider.state('listTakers', {
+ url: '/takers',
+ templateUrl: 'modules/takers/views/take.html'
+ }).state('createTaker', {
+ url: '/takers/create',
+ templateUrl: 'modules/takers/views/create-taker.client.view.html'
+ }).state('viewTaker', {
+ url: '/takers/:takerId',
+ templateUrl: 'modules/takers/views/view-taker.client.view.html'
+ }).state('editTaker', {
+ url: '/takers/:takerId/edit',
+ templateUrl: 'modules/takers/views/edit-taker.client.view.html'
+ });
+ }
+]);'use strict';
+angular.module('takers').controller('TakersController', [
+ '$scope',
+ '$stateParams',
+ '$location',
+ 'Authentication',
+ 'Articles',
+ function ($scope, $stateParams, $location, Authentication, Qas, Takers) {
+ $scope.authentication = Authentication;
+ // Takers controller logic
+ var taker = new Takers();
+ //taker.qa = qas;
+ $scope.taker = new Takers({
+ quizNumber: '0',
+ trialNumber: '0',
+ trialOptions: '',
+ results: [{
+ questionViewed: false,
+ questionAnswered: false,
+ questionNumber: '',
+ answer: [{
+ selection: '0',
+ answer: '0'
+ }]
+ }]
+ });
+ console.log('From ScopeTaker', $scope.taker);
+ $scope.find = function () {
+ Qas.query(function (qas) {
+ $scope.qas = qas;
+ });
+ };
+ console.log('From ScopeTaker', $scope.qas);
+ // Create and validate taker entries
+ $scope.next = function () {
+ $scope.questionIndex++;
+ taker.questionViewed = true;
+ taker.$save(function (response) {
+ $location.path('takers/' + response._id);
+ });
+ console.log('next', $scope.questionIndex);
+ };
+ $scope.prev = function () {
+ $scope.questionIndex--;
+ console.log('prev', $scope.questionIndex);
+ };
+ $scope.answerToggled = function () {
+ //var taker = $scope.taker;
+ // Grab data from input boxes
+ //console.log(taker);
+ //taker.qa.question = qas[questionIndex].question;
+ //taker.questionNumber = $scope.questionNumber;
+ console.log('toggledtaker', taker);
+ for (var i = 0, ln = taker.qa[$scope.questionIndex].choices.length; i < ln; i++) {
+ //taker.results.answer.selection[i] = $scope.results.answer.selection[i];
+ //console.log(taker.results[$scope.questionIndex].answer.isSelected[i],$scope.choice[i].selectedAnswer)
+ taker.results[$scope.questionIndex].answer.isSelected[i] = $scope.choice[i].selectedAnswer;
+ taker.updated.push(new Date().getTime());
+ }
+ ;
+ console.log('From taker 1', taker);
+ // Check that question was entered
+ taker.$save(function (response) {
+ $location.path('takers/' + response._id);
+ });
+ console.log(taker);
+ };
+ $scope.find = function () {
+ Qas.query(function (qas) {
+ // $scope.qas = qas;
+ taker.qa = qas;
+ $scope.taker = taker;
+ console.log('From ScopeTaker1', qas[0].questionNumber, taker.qa[0].question, $scope.qas, taker);
+ });
+ $scope.questionIndex = 0;
+ };
+ $scope.findOne = function () {
+ takers.get({ qasId: $stateParams.qasId }, function (qas) {
+ $scope.taker = qas;
+ });
+ };
+ }
+]);'use strict';
+//Takers service used to communicate Takers REST endpoints
+angular.module('takers').factory('Takers', [
+ '$resource',
+ function ($resource) {
+ return $resource('takers/:takerId', { takerId: '@_id' }, { update: { method: 'PUT' } });
+ }
+]);'use strict';
// Config HTTP Error Handling
angular.module('users').config([
'$httpProvider',
diff --git a/public/dist/application.min.js b/public/dist/application.min.js
index 7c75a13709..1e663897bd 100644
--- a/public/dist/application.min.js
+++ b/public/dist/application.min.js
@@ -1 +1 @@
-"use strict";var ApplicationConfiguration=function(){var applicationModuleName="mean",applicationModuleVendorDependencies=["ngResource","ngAnimate","ui.router","ui.bootstrap","ui.utils"],registerModule=function(moduleName,dependencies){angular.module(moduleName,dependencies||[]),angular.module(applicationModuleName).requires.push(moduleName)};return{applicationModuleName:applicationModuleName,applicationModuleVendorDependencies:applicationModuleVendorDependencies,registerModule:registerModule}}();angular.module(ApplicationConfiguration.applicationModuleName,ApplicationConfiguration.applicationModuleVendorDependencies),angular.module(ApplicationConfiguration.applicationModuleName).config(["$locationProvider",function($locationProvider){$locationProvider.hashPrefix("!")}]),angular.element(document).ready(function(){"#_=_"===window.location.hash&&(window.location.hash="#!"),angular.bootstrap(document,[ApplicationConfiguration.applicationModuleName])}),ApplicationConfiguration.registerModule("articles"),ApplicationConfiguration.registerModule("core"),ApplicationConfiguration.registerModule("users"),angular.module("articles").run(["Menus",function(Menus){Menus.addMenuItem("topbar","Articles","articles","dropdown","/articles(/create)?"),Menus.addSubMenuItem("topbar","articles","List Articles","articles"),Menus.addSubMenuItem("topbar","articles","New Article","articles/create")}]),angular.module("articles").config(["$stateProvider",function($stateProvider){$stateProvider.state("listArticles",{url:"/articles",templateUrl:"modules/articles/views/list-articles.client.view.html"}).state("createArticle",{url:"/articles/create",templateUrl:"modules/articles/views/create-article.client.view.html"}).state("viewArticle",{url:"/articles/:articleId",templateUrl:"modules/articles/views/view-article.client.view.html"}).state("editArticle",{url:"/articles/:articleId/edit",templateUrl:"modules/articles/views/edit-article.client.view.html"})}]),angular.module("articles").controller("ArticlesController",["$scope","$stateParams","$location","Authentication","Articles",function($scope,$stateParams,$location,Authentication,Articles){$scope.authentication=Authentication,$scope.create=function(){var article=new Articles({title:this.title,content:this.content});article.$save(function(response){$location.path("articles/"+response._id),$scope.title="",$scope.content=""},function(errorResponse){$scope.error=errorResponse.data.message})},$scope.remove=function(article){if(article){article.$remove();for(var i in $scope.articles)$scope.articles[i]===article&&$scope.articles.splice(i,1)}else $scope.article.$remove(function(){$location.path("articles")})},$scope.update=function(){var article=$scope.article;article.$update(function(){$location.path("articles/"+article._id)},function(errorResponse){$scope.error=errorResponse.data.message})},$scope.find=function(){$scope.articles=Articles.query()},$scope.findOne=function(){$scope.article=Articles.get({articleId:$stateParams.articleId})}}]),angular.module("articles").factory("Articles",["$resource",function($resource){return $resource("articles/:articleId",{articleId:"@_id"},{update:{method:"PUT"}})}]),angular.module("core").config(["$stateProvider","$urlRouterProvider",function($stateProvider,$urlRouterProvider){$urlRouterProvider.otherwise("/"),$stateProvider.state("home",{url:"/",templateUrl:"modules/core/views/home.client.view.html"})}]),angular.module("core").controller("HeaderController",["$scope","Authentication","Menus",function($scope,Authentication,Menus){$scope.authentication=Authentication,$scope.isCollapsed=!1,$scope.menu=Menus.getMenu("topbar"),$scope.toggleCollapsibleMenu=function(){$scope.isCollapsed=!$scope.isCollapsed},$scope.$on("$stateChangeSuccess",function(){$scope.isCollapsed=!1})}]),angular.module("core").controller("HomeController",["$scope","Authentication",function($scope,Authentication){$scope.authentication=Authentication}]),angular.module("core").service("Menus",[function(){this.defaultRoles=["user"],this.menus={};var shouldRender=function(user){if(!user)return this.isPublic;for(var userRoleIndex in user.roles)for(var roleIndex in this.roles)if(this.roles[roleIndex]===user.roles[userRoleIndex])return!0;return!1};this.validateMenuExistance=function(menuId){if(menuId&&menuId.length){if(this.menus[menuId])return!0;throw new Error("Menu does not exists")}throw new Error("MenuId was not provided")},this.getMenu=function(menuId){return this.validateMenuExistance(menuId),this.menus[menuId]},this.addMenu=function(menuId,isPublic,roles){return this.menus[menuId]={isPublic:isPublic||!1,roles:roles||this.defaultRoles,items:[],shouldRender:shouldRender},this.menus[menuId]},this.removeMenu=function(menuId){this.validateMenuExistance(menuId),delete this.menus[menuId]},this.addMenuItem=function(menuId,menuItemTitle,menuItemURL,menuItemType,menuItemUIRoute,isPublic,roles,position){return this.validateMenuExistance(menuId),this.menus[menuId].items.push({title:menuItemTitle,link:menuItemURL,menuItemType:menuItemType||"item",menuItemClass:menuItemType,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].isPublic:isPublic,roles:roles||this.defaultRoles,position:position||0,items:[],shouldRender:shouldRender}),this.menus[menuId]},this.addSubMenuItem=function(menuId,rootMenuItemURL,menuItemTitle,menuItemURL,menuItemUIRoute,isPublic,roles,position){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===rootMenuItemURL&&this.menus[menuId].items[itemIndex].items.push({title:menuItemTitle,link:menuItemURL,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].items[itemIndex].isPublic:isPublic,roles:roles||this.defaultRoles,position:position||0,shouldRender:shouldRender});return this.menus[menuId]},this.removeMenuItem=function(menuId,menuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===menuItemURL&&this.menus[menuId].items.splice(itemIndex,1);return this.menus[menuId]},this.removeSubMenuItem=function(menuId,submenuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)for(var subitemIndex in this.menus[menuId].items[itemIndex].items)this.menus[menuId].items[itemIndex].items[subitemIndex].link===submenuItemURL&&this.menus[menuId].items[itemIndex].items.splice(subitemIndex,1);return this.menus[menuId]},this.addMenu("topbar")}]),angular.module("users").config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$q","$location","Authentication",function($q,$location,Authentication){return{responseError:function(rejection){switch(rejection.status){case 401:Authentication.user=null,$location.path("signin");break;case 403:}return $q.reject(rejection)}}}])}]),angular.module("users").config(["$stateProvider",function($stateProvider){$stateProvider.state("profile",{url:"/settings/profile",templateUrl:"modules/users/views/settings/edit-profile.client.view.html"}).state("password",{url:"/settings/password",templateUrl:"modules/users/views/settings/change-password.client.view.html"}).state("accounts",{url:"/settings/accounts",templateUrl:"modules/users/views/settings/social-accounts.client.view.html"}).state("signup",{url:"/signup",templateUrl:"modules/users/views/authentication/signup.client.view.html"}).state("signin",{url:"/signin",templateUrl:"modules/users/views/authentication/signin.client.view.html"}).state("forgot",{url:"/password/forgot",templateUrl:"modules/users/views/password/forgot-password.client.view.html"}).state("reset-invlaid",{url:"/password/reset/invalid",templateUrl:"modules/users/views/password/reset-password-invalid.client.view.html"}).state("reset-success",{url:"/password/reset/success",templateUrl:"modules/users/views/password/reset-password-success.client.view.html"}).state("reset",{url:"/password/reset/:token",templateUrl:"modules/users/views/password/reset-password.client.view.html"})}]),angular.module("users").controller("AuthenticationController",["$scope","$http","$location","Authentication",function($scope,$http,$location,Authentication){$scope.authentication=Authentication,$scope.authentication.user&&$location.path("/"),$scope.signup=function(){$http.post("/auth/signup",$scope.credentials).success(function(response){$scope.authentication.user=response,$location.path("/")}).error(function(response){$scope.error=response.message})},$scope.signin=function(){$http.post("/auth/signin",$scope.credentials).success(function(response){$scope.authentication.user=response,$location.path("/")}).error(function(response){$scope.error=response.message})}}]),angular.module("users").controller("PasswordController",["$scope","$stateParams","$http","$location","Authentication",function($scope,$stateParams,$http,$location,Authentication){$scope.authentication=Authentication,$scope.authentication.user&&$location.path("/"),$scope.askForPasswordReset=function(){$scope.success=$scope.error=null,$http.post("/auth/forgot",$scope.credentials).success(function(response){$scope.credentials=null,$scope.success=response.message}).error(function(response){$scope.credentials=null,$scope.error=response.message})},$scope.resetUserPassword=function(){$scope.success=$scope.error=null,$http.post("/auth/reset/"+$stateParams.token,$scope.passwordDetails).success(function(response){$scope.passwordDetails=null,Authentication.user=response,$location.path("/password/reset/success")}).error(function(response){$scope.error=response.message})}}]),angular.module("users").controller("SettingsController",["$scope","$http","$location","Users","Authentication",function($scope,$http,$location,Users,Authentication){$scope.user=Authentication.user,$scope.user||$location.path("/"),$scope.hasConnectedAdditionalSocialAccounts=function(){for(var i in $scope.user.additionalProvidersData)return!0;return!1},$scope.isConnectedSocialAccount=function(provider){return $scope.user.provider===provider||$scope.user.additionalProvidersData&&$scope.user.additionalProvidersData[provider]},$scope.removeUserSocialAccount=function(provider){$scope.success=$scope.error=null,$http.delete("/users/accounts",{params:{provider:provider}}).success(function(response){$scope.success=!0,$scope.user=Authentication.user=response}).error(function(response){$scope.error=response.message})},$scope.updateUserProfile=function(isValid){if(isValid){$scope.success=$scope.error=null;var user=new Users($scope.user);user.$update(function(response){$scope.success=!0,Authentication.user=response},function(response){$scope.error=response.data.message})}else $scope.submitted=!0},$scope.changeUserPassword=function(){$scope.success=$scope.error=null,$http.post("/users/password",$scope.passwordDetails).success(function(){$scope.success=!0,$scope.passwordDetails=null}).error(function(response){$scope.error=response.message})}}]),angular.module("users").factory("Authentication",[function(){var _this=this;return _this._data={user:window.user},_this._data}]),angular.module("users").factory("Users",["$resource",function($resource){return $resource("users",{},{update:{method:"PUT"}})}]);
\ No newline at end of file
+"use strict";var ApplicationConfiguration=function(){var applicationModuleName="mean",applicationModuleVendorDependencies=["ngResource","ngAnimate","ui.router","ui.bootstrap","ui.utils"],registerModule=function(moduleName,dependencies){angular.module(moduleName,dependencies||[]),angular.module(applicationModuleName).requires.push(moduleName)};return{applicationModuleName:applicationModuleName,applicationModuleVendorDependencies:applicationModuleVendorDependencies,registerModule:registerModule}}();angular.module(ApplicationConfiguration.applicationModuleName,ApplicationConfiguration.applicationModuleVendorDependencies),angular.module(ApplicationConfiguration.applicationModuleName).config(["$locationProvider",function($locationProvider){$locationProvider.hashPrefix("!")}]),angular.element(document).ready(function(){"#_=_"===window.location.hash&&(window.location.hash="#!"),angular.bootstrap(document,[ApplicationConfiguration.applicationModuleName])}),ApplicationConfiguration.registerModule("articles"),ApplicationConfiguration.registerModule("core"),ApplicationConfiguration.registerModule("qas"),ApplicationConfiguration.registerModule("takers"),ApplicationConfiguration.registerModule("users"),angular.module("articles").run(["Menus",function(Menus){Menus.addMenuItem("topbar","Articles","articles","dropdown","/articles(/create)?"),Menus.addSubMenuItem("topbar","articles","List Articles","articles"),Menus.addSubMenuItem("topbar","articles","New Article","articles/create")}]),angular.module("articles").config(["$stateProvider",function($stateProvider){$stateProvider.state("listArticles",{url:"/articles",templateUrl:"modules/articles/views/list-articles.client.view.html"}).state("createArticle",{url:"/articles/create",templateUrl:"modules/articles/views/create-article.client.view.html"}).state("viewArticle",{url:"/articles/:articleId",templateUrl:"modules/articles/views/view-article.client.view.html"}).state("editArticle",{url:"/articles/:articleId/edit",templateUrl:"modules/articles/views/edit-article.client.view.html"})}]),angular.module("articles").controller("ArticlesController",["$scope","$stateParams","$location","Authentication","Articles",function($scope,$stateParams,$location,Authentication,Articles){$scope.authentication=Authentication,$scope.create=function(){var article=new Articles({title:this.title,content:this.content});article.$save(function(response){$location.path("articles/"+response._id),$scope.title="",$scope.content=""},function(errorResponse){$scope.error=errorResponse.data.message})},$scope.remove=function(article){if(article){article.$remove();for(var i in $scope.articles)$scope.articles[i]===article&&$scope.articles.splice(i,1)}else $scope.article.$remove(function(){$location.path("articles")})},$scope.update=function(){var article=$scope.article;article.$update(function(){$location.path("articles/"+article._id)},function(errorResponse){$scope.error=errorResponse.data.message})},$scope.find=function(){$scope.articles=Articles.query()},$scope.findOne=function(){$scope.article=Articles.get({articleId:$stateParams.articleId})}}]),angular.module("articles").factory("Articles",["$resource",function($resource){return $resource("articles/:articleId",{articleId:"@_id"},{update:{method:"PUT"}})}]),angular.module("core").config(["$stateProvider","$urlRouterProvider",function($stateProvider,$urlRouterProvider){$urlRouterProvider.otherwise("/"),$stateProvider.state("home",{url:"/",templateUrl:"modules/core/views/home.client.view.html"})}]),angular.module("core").controller("HeaderController",["$scope","Authentication","Menus",function($scope,Authentication,Menus){$scope.authentication=Authentication,$scope.isCollapsed=!1,$scope.menu=Menus.getMenu("topbar"),$scope.toggleCollapsibleMenu=function(){$scope.isCollapsed=!$scope.isCollapsed},$scope.$on("$stateChangeSuccess",function(){$scope.isCollapsed=!1})}]),angular.module("core").controller("HomeController",["$scope","Authentication",function($scope,Authentication){$scope.authentication=Authentication}]),angular.module("core").service("Menus",[function(){this.defaultRoles=["*"],this.menus={};var shouldRender=function(user){if(!user)return this.isPublic;if(~this.roles.indexOf("*"))return!0;for(var userRoleIndex in user.roles)for(var roleIndex in this.roles)if(this.roles[roleIndex]===user.roles[userRoleIndex])return!0;return!1};this.validateMenuExistance=function(menuId){if(menuId&&menuId.length){if(this.menus[menuId])return!0;throw new Error("Menu does not exists")}throw new Error("MenuId was not provided")},this.getMenu=function(menuId){return this.validateMenuExistance(menuId),this.menus[menuId]},this.addMenu=function(menuId,isPublic,roles){return this.menus[menuId]={isPublic:isPublic||!1,roles:roles||this.defaultRoles,items:[],shouldRender:shouldRender},this.menus[menuId]},this.removeMenu=function(menuId){this.validateMenuExistance(menuId),delete this.menus[menuId]},this.addMenuItem=function(menuId,menuItemTitle,menuItemURL,menuItemType,menuItemUIRoute,isPublic,roles,position){return this.validateMenuExistance(menuId),this.menus[menuId].items.push({title:menuItemTitle,link:menuItemURL,menuItemType:menuItemType||"item",menuItemClass:menuItemType,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].isPublic:isPublic,roles:null===roles||"undefined"==typeof roles?this.menus[menuId].roles:roles,position:position||0,items:[],shouldRender:shouldRender}),this.menus[menuId]},this.addSubMenuItem=function(menuId,rootMenuItemURL,menuItemTitle,menuItemURL,menuItemUIRoute,isPublic,roles,position){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===rootMenuItemURL&&this.menus[menuId].items[itemIndex].items.push({title:menuItemTitle,link:menuItemURL,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].items[itemIndex].isPublic:isPublic,roles:null===roles||"undefined"==typeof roles?this.menus[menuId].items[itemIndex].roles:roles,position:position||0,shouldRender:shouldRender});return this.menus[menuId]},this.removeMenuItem=function(menuId,menuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===menuItemURL&&this.menus[menuId].items.splice(itemIndex,1);return this.menus[menuId]},this.removeSubMenuItem=function(menuId,submenuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)for(var subitemIndex in this.menus[menuId].items[itemIndex].items)this.menus[menuId].items[itemIndex].items[subitemIndex].link===submenuItemURL&&this.menus[menuId].items[itemIndex].items.splice(subitemIndex,1);return this.menus[menuId]},this.addMenu("topbar")}]),angular.module("qas").run(["Menus",function(Menus){Menus.addMenuItem("topbar","Qas","qas","dropdown","/qas(/create)?"),Menus.addSubMenuItem("topbar","qas","List Qas","qas"),Menus.addSubMenuItem("topbar","qas","New Qa","qas/create")}]),angular.module("qas").config(["$stateProvider",function($stateProvider){$stateProvider.state("listQas",{url:"/qas",templateUrl:"modules/qas/views/list-qas.client.view.html"}).state("createQa",{url:"/qas/create",templateUrl:"modules/qas/views/create-qa.client.view.html"}).state("viewQa",{url:"/qas/:qaId",templateUrl:"modules/qas/views/view-qa.client.view.html"}).state("editQa",{url:"/qas/:qaId/edit",templateUrl:"modules/qas/views/edit-qa.client.view.html"})}]),angular.module("qas").controller("QasController",["$scope","$stateParams","$location","Authentication","Qas","CalculatorService","MathService","qasInitService",function($scope,$stateParams,$location,Authentication,Qas,CalculatorService,MathService,qasInitService){$scope.authentication=Authentication,$scope.doit=CalculatorService.cce(77),$scope.typeDropdown=qasInitService.typeDropdown(),$scope.difficultyDropdown=qasInitService.difficultyDropdown(),$scope.qa=qasInitService.init(),$scope.create=function(){var qa=new Qas({question:this.question,imageURL:this.imageURL,choices:[{text:this.text,selectedAnswer:!1},{text:this.text,selectedAnswer:this.correctAnswer},{text:this.text,selectedAnswer:this.correctAnswer}],hint:this.hint,type:this.td,difficulty:this.difficulty,hintOn:this.hintOn,timeOn:this.timeOn,fifty50On:this.fifty50On,randomizeQuestionsOn:this.randomizeQuestionsOn,randomizeAnswersOn:this.randomizeAnswersOn});if(qa.choices=$scope.qa.choices,qa.difficulty=$scope.dd.label,qa.type=$scope.td.label,qa.question.length>0){var choiceCount=0;console.log("qa if",qa);for(var i=0,ln=qa.choices.length;ln>i;i++){var choice=qa.choices[i].text;console.log("choice",choice," i",i),choice.length>0&&choiceCount++}choiceCount>1||alert("You must have at least two choices")}else alert("You must have a question");console.log("qaFinal",qa),qa.$save(function(response){$location.path("qas/"+response._id)})},$scope.addChoice=function(){console.log("qa add",$scope.qa),$scope.qa.choices.push({text:this.text,selectedAnswer:!1})},$scope.remove=function(qa){if(qa){qa.$remove();for(var i in $scope.qas)$scope.qas[i]===qa&&$scope.qas.splice(i,1)}else $scope.qa.$remove(function(){$location.path("qas")})},$scope.update=function(){var qa=$scope.qa;console.log("From update",qa),qa.updated||(qa.updated=[]),qa.updated.push((new Date).getTime()),qa.$update(function(){$location.path("qas/"+qa._id)})},$scope.find=function(){Qas.query(function(qas){$scope.qas=qas})},$scope.findOne=function(){Qas.get({qaId:$stateParams.qaId},function(qa){$scope.qa=qa})},$scope.deleteChoice=function(ev){var ss=ev.target.innerText.toString()-1;console.log(ss);var qa=$scope.qa;console.log(qa),$scope.qa.choices.splice(ss,1)}}]),angular.module("qas").factory("Qas",["$resource",function($resource){return $resource("qas/:qaId",{qaId:"@_id"},{update:{method:"PUT"}})}]),angular.module("qas").service("MathService",[function(){this.add=function(a,b){return a+b},this.subtract=function(a,b){return a-b},this.multiply=function(a,b){return a*b},this.divide=function(a,b){return a/b}}]).service("CalculatorService",function(MathService){this.square=function(a){return MathService.multiply(a,a)},this.cce=function(a){return a+1e3*a},this.cube=function(a){return MathService.multiply(a,MathService.multiply(a,a))}}),angular.module("qas").service("qasInitService",[function(){this.typeDropdown=function(){return[{label:"FIB",value:1},{label:"TF",value:2},{label:"MC",value:3},{label:"Matching",value:4}]},this.difficultyDropdown=function(){return[{label:"Easy",value:1},{label:"Medium",value:2},{label:"Hard",value:3},{label:"Impossible",value:4}]},this.init=function(){return{choices:[{text:"",correctAnswer:!1},{text:"",correctAnswer:!1},{text:"",correctAnswer:!1}]}}}]),angular.module("takers").run(["Menus",function(Menus){Menus.addMenuItem("topbar","Takers","takers","dropdown","/takers(/create)?"),Menus.addSubMenuItem("topbar","takers","List Takers","takers"),Menus.addSubMenuItem("topbar","takers","New Taker","takers/create"),Menus.addSubMenuItem("topbar","takers","Take","takers/")}]),angular.module("takers").config(["$stateProvider",function($stateProvider){$stateProvider.state("listTakers",{url:"/takers",templateUrl:"modules/takers/views/take.html"}).state("createTaker",{url:"/takers/create",templateUrl:"modules/takers/views/create-taker.client.view.html"}).state("viewTaker",{url:"/takers/:takerId",templateUrl:"modules/takers/views/view-taker.client.view.html"}).state("editTaker",{url:"/takers/:takerId/edit",templateUrl:"modules/takers/views/edit-taker.client.view.html"})}]),angular.module("takers").controller("TakersController",["$scope","$stateParams","$location","Authentication","Articles",function($scope,$stateParams,$location,Authentication,Qas,Takers){$scope.authentication=Authentication;var taker=new Takers;$scope.taker=new Takers({quizNumber:"0",trialNumber:"0",trialOptions:"",results:[{questionViewed:!1,questionAnswered:!1,questionNumber:"",answer:[{selection:"0",answer:"0"}]}]}),console.log("From ScopeTaker",$scope.taker),$scope.find=function(){Qas.query(function(qas){$scope.qas=qas})},console.log("From ScopeTaker",$scope.qas),$scope.next=function(){$scope.questionIndex++,taker.questionViewed=!0,taker.$save(function(response){$location.path("takers/"+response._id)}),console.log("next",$scope.questionIndex)},$scope.prev=function(){$scope.questionIndex--,console.log("prev",$scope.questionIndex)},$scope.answerToggled=function(){console.log("toggledtaker",taker);for(var i=0,ln=taker.qa[$scope.questionIndex].choices.length;ln>i;i++)taker.results[$scope.questionIndex].answer.isSelected[i]=$scope.choice[i].selectedAnswer,taker.updated.push((new Date).getTime());console.log("From taker 1",taker),taker.$save(function(response){$location.path("takers/"+response._id)}),console.log(taker)},$scope.find=function(){Qas.query(function(qas){taker.qa=qas,$scope.taker=taker,console.log("From ScopeTaker1",qas[0].questionNumber,taker.qa[0].question,$scope.qas,taker)}),$scope.questionIndex=0},$scope.findOne=function(){takers.get({qasId:$stateParams.qasId},function(qas){$scope.taker=qas})}}]),angular.module("takers").factory("Takers",["$resource",function($resource){return $resource("takers/:takerId",{takerId:"@_id"},{update:{method:"PUT"}})}]),angular.module("users").config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$q","$location","Authentication",function($q,$location,Authentication){return{responseError:function(rejection){switch(rejection.status){case 401:Authentication.user=null,$location.path("signin");break;case 403:}return $q.reject(rejection)}}}])}]),angular.module("users").config(["$stateProvider",function($stateProvider){$stateProvider.state("profile",{url:"/settings/profile",templateUrl:"modules/users/views/settings/edit-profile.client.view.html"}).state("password",{url:"/settings/password",templateUrl:"modules/users/views/settings/change-password.client.view.html"}).state("accounts",{url:"/settings/accounts",templateUrl:"modules/users/views/settings/social-accounts.client.view.html"}).state("signup",{url:"/signup",templateUrl:"modules/users/views/authentication/signup.client.view.html"}).state("signin",{url:"/signin",templateUrl:"modules/users/views/authentication/signin.client.view.html"}).state("forgot",{url:"/password/forgot",templateUrl:"modules/users/views/password/forgot-password.client.view.html"}).state("reset-invlaid",{url:"/password/reset/invalid",templateUrl:"modules/users/views/password/reset-password-invalid.client.view.html"}).state("reset-success",{url:"/password/reset/success",templateUrl:"modules/users/views/password/reset-password-success.client.view.html"}).state("reset",{url:"/password/reset/:token",templateUrl:"modules/users/views/password/reset-password.client.view.html"})}]),angular.module("users").controller("AuthenticationController",["$scope","$http","$location","Authentication",function($scope,$http,$location,Authentication){$scope.authentication=Authentication,$scope.authentication.user&&$location.path("/"),$scope.signup=function(){$http.post("/auth/signup",$scope.credentials).success(function(response){$scope.authentication.user=response,$location.path("/")}).error(function(response){$scope.error=response.message})},$scope.signin=function(){$http.post("/auth/signin",$scope.credentials).success(function(response){$scope.authentication.user=response,$location.path("/")}).error(function(response){$scope.error=response.message})}}]),angular.module("users").controller("PasswordController",["$scope","$stateParams","$http","$location","Authentication",function($scope,$stateParams,$http,$location,Authentication){$scope.authentication=Authentication,$scope.authentication.user&&$location.path("/"),$scope.askForPasswordReset=function(){$scope.success=$scope.error=null,$http.post("/auth/forgot",$scope.credentials).success(function(response){$scope.credentials=null,$scope.success=response.message}).error(function(response){$scope.credentials=null,$scope.error=response.message})},$scope.resetUserPassword=function(){$scope.success=$scope.error=null,$http.post("/auth/reset/"+$stateParams.token,$scope.passwordDetails).success(function(response){$scope.passwordDetails=null,Authentication.user=response,$location.path("/password/reset/success")}).error(function(response){$scope.error=response.message})}}]),angular.module("users").controller("SettingsController",["$scope","$http","$location","Users","Authentication",function($scope,$http,$location,Users,Authentication){$scope.user=Authentication.user,$scope.user||$location.path("/"),$scope.hasConnectedAdditionalSocialAccounts=function(){for(var i in $scope.user.additionalProvidersData)return!0;return!1},$scope.isConnectedSocialAccount=function(provider){return $scope.user.provider===provider||$scope.user.additionalProvidersData&&$scope.user.additionalProvidersData[provider]},$scope.removeUserSocialAccount=function(provider){$scope.success=$scope.error=null,$http.delete("/users/accounts",{params:{provider:provider}}).success(function(response){$scope.success=!0,$scope.user=Authentication.user=response}).error(function(response){$scope.error=response.message})},$scope.updateUserProfile=function(isValid){if(isValid){$scope.success=$scope.error=null;var user=new Users($scope.user);user.$update(function(response){$scope.success=!0,Authentication.user=response},function(response){$scope.error=response.data.message})}else $scope.submitted=!0},$scope.changeUserPassword=function(){$scope.success=$scope.error=null,$http.post("/users/password",$scope.passwordDetails).success(function(){$scope.success=!0,$scope.passwordDetails=null}).error(function(response){$scope.error=response.message})}}]),angular.module("users").factory("Authentication",[function(){var _this=this;return _this._data={user:window.user},_this._data}]),angular.module("users").factory("Users",["$resource",function($resource){return $resource("users",{},{update:{method:"PUT"}})}]);
\ No newline at end of file
diff --git a/public/modules/articles/controllers/articles.client.controller.js b/public/modules/articles/controllers/articles.client.controller.js
index 364987eb9e..ee02cd230a 100644
--- a/public/modules/articles/controllers/articles.client.controller.js
+++ b/public/modules/articles/controllers/articles.client.controller.js
@@ -9,6 +9,7 @@ angular.module('articles').controller('ArticlesController', ['$scope', '$statePa
title: this.title,
content: this.content
});
+ // console.log(response);
article.$save(function(response) {
$location.path('articles/' + response._id);
diff --git a/public/modules/articles/services/articles.client.service.js b/public/modules/articles/services/articles.client.service.js
index deeb7da58c..59e7355f59 100644
--- a/public/modules/articles/services/articles.client.service.js
+++ b/public/modules/articles/services/articles.client.service.js
@@ -3,12 +3,9 @@
//Articles service used for communicating with the articles REST endpoints
angular.module('articles').factory('Articles', ['$resource',
function($resource) {
- return $resource('articles/:articleId', {
- articleId: '@_id'
- }, {
- update: {
- method: 'PUT'
- }
+ return $resource('articles/:articleId', {articleId: '@_id'
+ },{
+ update: {method: 'PUT'}
});
}
]);
\ No newline at end of file
diff --git a/public/modules/qas/config/qas.client.config.js b/public/modules/qas/config/qas.client.config.js
new file mode 100644
index 0000000000..bfb1dc4731
--- /dev/null
+++ b/public/modules/qas/config/qas.client.config.js
@@ -0,0 +1,12 @@
+'use strict';
+
+// Configuring the Articles module.
+angular.module('qas').run(['Menus',
+ function(Menus) {
+ // Set top bar menu items
+ Menus.addMenuItem('topbar', 'Qas', 'qas', 'dropdown', '/qas(/create)?');
+ Menus.addSubMenuItem('topbar', 'qas', 'List Qas', 'qas');
+ Menus.addSubMenuItem('topbar', 'qas', 'New Qa', 'qas/create');
+ Menus.addSubMenuItem('topbar', 'qas', 'List Quizzes', 'listQasQuizzes');
+ }
+]);
\ No newline at end of file
diff --git a/public/modules/qas/config/qas.client.routes.js b/public/modules/qas/config/qas.client.routes.js
new file mode 100644
index 0000000000..c67c7a20dd
--- /dev/null
+++ b/public/modules/qas/config/qas.client.routes.js
@@ -0,0 +1,29 @@
+'use strict';
+
+//Setting up route...
+angular.module('qas').config(['$stateProvider',
+ function($stateProvider) {
+ // Qas state routing
+ $stateProvider.
+ state('listQas', {
+ url: '/qas',
+ templateUrl: 'modules/qas/views/list-qas.client.view.html'
+ }).
+ state('createQa', {
+ url: '/qas/create',
+ templateUrl: 'modules/qas/views/create-qa.client.view.html'
+ }).
+ state('viewQa', {
+ url: '/qas/:qaId',
+ templateUrl: 'modules/qas/views/view-qa.client.view.html'
+ }).
+ state('editQa', {
+ url: '/qas/:qaId/edit',
+ templateUrl: 'modules/qas/views/edit-qa.client.view.html'
+ }).
+ state('listQasQuizzes', {
+ url: '/listQasQuizzes',
+ templateUrl: 'modules/qas/views/listquizzes-qas.client.view.html'
+ });
+ }
+]);
\ No newline at end of file
diff --git a/public/modules/qas/controllers/qas.client.controller.js b/public/modules/qas/controllers/qas.client.controller.js
new file mode 100644
index 0000000000..8c2beccc5a
--- /dev/null
+++ b/public/modules/qas/controllers/qas.client.controller.js
@@ -0,0 +1,185 @@
+'use strict';
+
+// Qas controller...
+angular.module('qas').controller('QasController', ['$scope','$rootScope','$modal', '$stateParams', '$location', 'Authentication',
+ 'Qas','Quizzes', 'CalculatorService', 'MathService', 'qasInitService',
+ function ($scope, $rootScope, $modal, $stateParams, $location, Authentication, Qas,Quizzes, CalculatorService, MathService, qasInitService) {
+ $scope.authentication = Authentication;
+//Test of Calculator and Math Service
+ $scope.doit = CalculatorService.cce(77);
+
+// Initialize Dropdown labels
+ $scope.typeDropdown = qasInitService.typeDropdown();
+ $scope.difficultyDropdown = qasInitService.difficultyDropdown();
+
+ var selectedQuiz = qasInitService.getSelectedQuiz();
+ //console.log('call to qasServiceQuiz',fixedQuiz);
+
+ $scope.qa = qasInitService.init();
+// Create and validate qa entries
+ $scope.create = function () {
+ var quiz = new Quizzes();
+ quiz.qa = new Qas({
+ question: this.question,
+ imageURL: this.imageURL,
+ choices: [
+ {text: this.text, selectedAnswer: false //doesn't work
+ },
+ {text: this.text, selectedAnswer: this.correctAnswer //doesn't work
+ },
+ {text: this.text, selectedAnswer: this.correctAnswer //doesn't work
+ }
+ ],
+ hint: this.hint,
+ type: this.td, //doesn't work
+ difficulty: this.difficulty, //doesn't work
+ hintOn: this.hintOn,
+ timeOn: this.timeOn,
+ fifty50On: this.fifty50On,
+ randomizeQuestionsOn: this.randomizeQuestionsOn,
+ randomizeAnswersOn: this.randomizeAnswersOn,
+ questionNumber: this.questionNumber
+ });
+
+// Hack to load these variables. Not handled above???
+ quiz.qa.choices = $scope.qa.choices;
+ // quiz.qa.difficulty = $scope.quiz.dd.label;
+ // quiz.qa.type = $scope.quiz.td.label;
+ quiz.qa.qaQuizName = selectedQuiz[0];
+ quiz.qa.qaQuizId = selectedQuiz[1];
+ // Check that question was entered
+ if (quiz.qa.question.length > 0) {
+ var choiceCount = 0;
+ //Loop through choices to get at least two
+ console.log('qa if', quiz.qa,qa);
+ for (var i = 0, ln = quiz.qa.choices.length; i < ln; i++) {
+ var choice = quiz.qa.choices[i].text;
+ console.log('choice', choice, " i", i);
+ if (choice.length > 0) {
+ choiceCount++;
+ }
+ }
+ if (choiceCount > 1) {
+ // Call API to save to database
+
+
+ } else {
+ alert('You must have at least two choices');
+ }
+ } else {
+ alert('You must have a question');
+ }
+ console.log('qaFinal', quiz,qa);
+ qa.$save(function (response) {
+ $location.path('qas/' + response._id)
+ });
+ };
+
+ // Method to add an additional choice option
+ $scope.addChoice = function () {
+ console.log('qa add', $scope.qa);
+ $scope.qa.choices.push({ text: this.text, selectedAnswer: false });
+ };
+
+ $scope.remove = function (qa) {
+ if (qa) {
+ qa.$remove();
+
+ for (var i in $scope.qas) {
+ if ($scope.qas[i] === qa) {
+ $scope.qas.splice(i, 1);
+ }
+ }
+ } else {
+ $scope.qa.$remove(function () {
+ $location.path('qas');
+ });
+ }
+ };
+
+ $scope.update = function () {
+ var qa = $scope.qa;
+ console.log('From update', qa);
+ if (!qa.updated) {
+ qa.updated = [];
+ }
+ qa.updated.push(new Date().getTime());
+
+ qa.$update(function () {
+ $location.path('qas/' + qa._id);
+ });
+ };
+
+ $scope.find = function () {
+ Qas.query(function (qas) {
+ $scope.qas = qas;
+ });
+ };
+
+ $scope.findQuizzes = function () {
+ Quizzes.query(function (quizzes) {
+ $scope.quizzes = quizzes;
+ });
+ };
+ $scope.findOne = function () {
+ Qas.get({
+ qaId: $stateParams.qaId
+ }, function (qa) {
+ $scope.qa = qa;
+ });
+ };
+ $scope.findQuizzesOne = function (quiz) {
+ // $scope.quiz = quiz;
+ var data = [quiz.name,quiz._id];
+ qasInitService.saveSelectedQuiz(data);
+
+
+ $rootScope.qname = quiz.name;
+ console.log($rootScope.qname);
+ };
+
+ $scope.deleteChoice = function (ev) {
+ var ss = ev.target.innerText.toString() - 1;
+ console.log(ss);
+ var qa = $scope.qa;
+ console.log(qa);
+ $scope.qa.choices.splice(ss, 1);
+ };
+// $scope.saveToOtherQuiz = function(){
+// var modalInstance = $modal.open({
+// templateUrl: 'modules/qas/views/modal-qa.client.html',
+// controller: ModalInstanceCtrl,
+// resolve: {
+// items: function () {
+// return $scope.items;
+// }
+// }
+// });
+//
+// modalInstance.result.then(function (selectedItem) {
+// $scope.selected = selectedItem;
+//
+// }, function () {
+// console.log('Modal dismissed at: ' + new Date());
+// });
+// };
+// var ModalInstanceCtrl = function ($scope, $modalInstance, Quizzes) {
+//
+// Quizzes.query(function(quizzes){
+// $scope.quizzes = quizzes;
+// });
+// $scope.selected = {
+// // quizzes: $scope.quizzes[0]
+// };
+//
+// $scope.ok = function () {
+// $modalInstance.close($scope.selected.item);
+// };
+//
+// $scope.cancel = function () {
+// $modalInstance.dismiss('cancel');
+// };
+// };
+ }
+]);
+
diff --git a/public/modules/qas/qas.client.module.js b/public/modules/qas/qas.client.module.js
new file mode 100644
index 0000000000..abf27a7ec1
--- /dev/null
+++ b/public/modules/qas/qas.client.module.js
@@ -0,0 +1,4 @@
+'use strict';
+
+// Use application configuration module to register a new module
+ApplicationConfiguration.registerModule('qas');
\ No newline at end of file
diff --git a/public/modules/qas/services/qas.client.service.js b/public/modules/qas/services/qas.client.service.js
new file mode 100644
index 0000000000..a1d2e6bdee
--- /dev/null
+++ b/public/modules/qas/services/qas.client.service.js
@@ -0,0 +1,11 @@
+'use strict';
+
+//Qas service used to communicate Qas REST endpoints
+angular.module('qas').factory('Qas', ['$resource',
+ function($resource) {
+ return $resource('qas/:qaId', { qaId: '@_id'
+ }, {
+ update: {method: 'PUT'}
+ });
+ }
+]);
\ No newline at end of file
diff --git a/public/modules/qas/services/qas.client.service1.js b/public/modules/qas/services/qas.client.service1.js
new file mode 100644
index 0000000000..85e2309417
--- /dev/null
+++ b/public/modules/qas/services/qas.client.service1.js
@@ -0,0 +1,22 @@
+/**
+ * Created by EbyC on 8/24/2014.
+ */
+'use strict';
+
+angular.module('qas')
+ .service('MathService', [ function() {
+
+ this.add = function(a, b) { return a + b };
+ this.subtract = function(a, b) { return a - b };
+ this.multiply = function(a, b) { return a * b };
+ this.divide = function(a, b) { return a / b };
+ }])
+
+ .service('CalculatorService', function(MathService){
+
+ this.square = function(a) { return MathService.multiply(a,a); };
+ this.cce = function(a) {return a+a*1000};
+ this.cube = function(a) { return MathService.multiply(a, MathService.multiply(a,a)); };
+
+ });
+
diff --git a/public/modules/qas/services/qas.client.service2.js b/public/modules/qas/services/qas.client.service2.js
new file mode 100644
index 0000000000..44e7264bc9
--- /dev/null
+++ b/public/modules/qas/services/qas.client.service2.js
@@ -0,0 +1,70 @@
+/**
+ * Created by EbyC on 8/24/2014.
+ */
+'use strict';
+
+//Qas service used to communicate Qas REST endpoints
+angular.module('qas')
+ .service('qasInitService', [ function () {
+ var data;
+ this.saveSelectedQuiz = function (item){
+ data = item
+ //console.log("service data",data);
+ return;
+ };
+ this.getSelectedQuiz = function () {
+ return data;
+ };
+
+ this.typeDropdown = function () {
+ return [
+ {
+ 'label': 'FIB',
+ 'value': 1
+ },
+ {
+ 'label': 'TF',
+ 'value': 2
+ },
+ {
+ 'label': 'MC',
+ 'value': 3
+ },
+ {
+ 'label': 'Matching',
+ 'value': 4
+ }
+ ];
+ };
+ this.difficultyDropdown = function () {
+ return [
+ {
+ 'label': 'Easy',
+ 'value': 1
+ },
+ {
+ 'label': 'Medium',
+ 'value': 2
+ },
+ {
+ 'label': 'Hard',
+ 'value': 3
+ },
+ {
+ 'label': 'Impossible',
+ 'value': 4
+ }
+ ];
+ };
+
+ this.init = function () {
+ return ({
+ choices: [
+ { text: '', correctAnswer: false },
+ { text: '', correctAnswer: false},
+ { text: '', correctAnswer: false}
+ ]
+ });
+ }
+
+ }]);
diff --git a/public/modules/qas/tests/qas.client.controller.test.js b/public/modules/qas/tests/qas.client.controller.test.js
new file mode 100644
index 0000000000..e841df9621
--- /dev/null
+++ b/public/modules/qas/tests/qas.client.controller.test.js
@@ -0,0 +1,163 @@
+'use strict';
+
+(function() {
+ // Qas Controller Spec
+ describe('Qas Controller Tests', function() {
+ // Initialize global variables
+ var QasController,
+ scope,
+ $httpBackend,
+ $stateParams,
+ $location;
+
+ // The $resource service augments the response object with methods for updating and deleting the resource.
+ // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match
+ // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher.
+ // When the toEqualData matcher compares two objects, it takes only object properties into
+ // account and ignores methods.
+ beforeEach(function() {
+ jasmine.addMatchers({
+ toEqualData: function(util, customEqualityTesters) {
+ return {
+ compare: function(actual, expected) {
+ return {
+ pass: angular.equals(actual, expected)
+ };
+ }
+ };
+ }
+ });
+ });
+
+ // Then we can start by loading the main application module
+ beforeEach(module(ApplicationConfiguration.applicationModuleName));
+
+ // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_).
+ // This allows us to inject a service but then attach it to a variable
+ // with the same name as the service.
+ beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) {
+ // Set a new global scope
+ scope = $rootScope.$new();
+
+ // Point global variables to injected services
+ $stateParams = _$stateParams_;
+ $httpBackend = _$httpBackend_;
+ $location = _$location_;
+
+ // Initialize the Qas controller.
+ QasController = $controller('QasController', {
+ $scope: scope
+ });
+ }));
+
+ it('$scope.find() should create an array with at least one Qa object fetched from XHR', inject(function(Qas) {
+ // Create sample Qa using the Qas service
+ var sampleQa = new Qas({
+ name: 'New Qa'
+ });
+
+ // Create a sample Qas array that includes the new Qa
+ var sampleQas = [sampleQa];
+
+ // Set GET response
+ $httpBackend.expectGET('qas').respond(sampleQas);
+
+ // Run controller functionality
+ scope.find();
+ $httpBackend.flush();
+
+ // Test scope value
+ expect(scope.qas).toEqualData(sampleQas);
+ }));
+
+ it('$scope.findOne() should create an array with one Qa object fetched from XHR using a qaId URL parameter', inject(function(Qas) {
+ // Define a sample Qa object
+ var sampleQa = new Qas({
+ name: 'New Qa'
+ });
+
+ // Set the URL parameter
+ $stateParams.qaId = '525a8422f6d0f87f0e407a33';
+
+ // Set GET response
+ $httpBackend.expectGET(/qas\/([0-9a-fA-F]{24})$/).respond(sampleQa);
+
+ // Run controller functionality
+ scope.findOne();
+ $httpBackend.flush();
+
+ // Test scope value
+ expect(scope.qa).toEqualData(sampleQa);
+ }));
+
+ it('$scope.create() with valid form data should send a POST request with the form input values and then locate to new object URL', inject(function(Qas) {
+ // Create a sample Qa object
+ var sampleQaPostData = new Qas({
+ name: 'New Qa'
+ });
+
+ // Create a sample Qa response
+ var sampleQaResponse = new Qas({
+ _id: '525cf20451979dea2c000001',
+ name: 'New Qa'
+ });
+
+ // Fixture mock form input values
+ scope.name = 'New Qa';
+
+ // Set POST response
+ $httpBackend.expectPOST('qas', sampleQaPostData).respond(sampleQaResponse);
+
+ // Run controller functionality
+ scope.create();
+ $httpBackend.flush();
+
+ // Test form inputs are reset
+ expect(scope.name).toEqual('');
+
+ // Test URL redirection after the Qa was created
+ expect($location.path()).toBe('/qas/' + sampleQaResponse._id);
+ }));
+
+ it('$scope.update() should update a valid Qa', inject(function(Qas) {
+ // Define a sample Qa put data
+ var sampleQaPutData = new Qas({
+ _id: '525cf20451979dea2c000001',
+ name: 'New Qa'
+ });
+
+ // Mock Qa in scope
+ scope.qa = sampleQaPutData;
+
+ // Set PUT response
+ $httpBackend.expectPUT(/qas\/([0-9a-fA-F]{24})$/).respond();
+
+ // Run controller functionality
+ scope.update();
+ $httpBackend.flush();
+
+ // Test URL location to new object
+ expect($location.path()).toBe('/qas/' + sampleQaPutData._id);
+ }));
+
+ it('$scope.remove() should send a DELETE request with a valid qaId and remove the Qa from the scope', inject(function(Qas) {
+ // Create new Qa object
+ var sampleQa = new Qas({
+ _id: '525a8422f6d0f87f0e407a33'
+ });
+
+ // Create new Qas array and include the Qa
+ scope.qas = [sampleQa];
+
+ // Set expected DELETE response
+ $httpBackend.expectDELETE(/qas\/([0-9a-fA-F]{24})$/).respond(204);
+
+ // Run controller functionality
+ scope.remove(sampleQa);
+ $httpBackend.flush();
+
+ // Test array after successful delete
+ expect(scope.qas.length).toBe(0);
+ }));
+ });
+}());
\ No newline at end of file
diff --git a/public/modules/qas/views/create-qa.client.view.html b/public/modules/qas/views/create-qa.client.view.html
new file mode 100644
index 0000000000..c893f47963
--- /dev/null
+++ b/public/modules/qas/views/create-qa.client.view.html
@@ -0,0 +1,115 @@
+New Big QA
+ {{qname}}
+ {{fixedQuiz}}
+ Edit Qa
+ LIST
+
+ LIST Quiz
+
+ {{quiz.name}}
+ select
+
+
+
+ {{qa.question}}
+
+
+