got submission deletion working
This commit is contained in:
parent
79dfbbc8a7
commit
6983440113
|
@ -20,6 +20,10 @@ var mongoose = require('mongoose'),
|
||||||
exports.uploadPDF = function(req, res, next) {
|
exports.uploadPDF = function(req, res, next) {
|
||||||
|
|
||||||
console.log('inside uploadPDF');
|
console.log('inside uploadPDF');
|
||||||
|
|
||||||
|
// console.log(req.files.file);
|
||||||
|
// console.log('\n\nProperty Descriptor\n-----------');
|
||||||
|
// console.log(Object.getOwnPropertyDescriptor(req.files.file, 'path'));
|
||||||
if(req.files){
|
if(req.files){
|
||||||
var pdfFile = req.files.file;
|
var pdfFile = req.files.file;
|
||||||
var _user = req.user;
|
var _user = req.user;
|
||||||
|
@ -50,7 +54,7 @@ exports.uploadPDF = function(req, res, next) {
|
||||||
}
|
}
|
||||||
pdfFile.path = path.join(newDestination, pdfFile.name);
|
pdfFile.path = path.join(newDestination, pdfFile.name);
|
||||||
console.log(pdfFile.name + ' uploaded to ' + pdfFile.path);
|
console.log(pdfFile.name + ' uploaded to ' + pdfFile.path);
|
||||||
res.status(200).send('pdf file successfully uploaded');
|
res.json(pdfFile);
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -63,22 +67,46 @@ exports.uploadPDF = function(req, res, next) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a forms submissions
|
||||||
|
*/
|
||||||
|
exports.deleteSubmissions = function(req, res) {
|
||||||
|
console.log(req.body);
|
||||||
|
var submission_id_list = req.body.deleted_submissions,
|
||||||
|
form = req.form;
|
||||||
|
|
||||||
|
FormSubmission.remove({ form: req.form, admin: req.user, _id: {$in: submission_id_list} }, function(err){
|
||||||
|
|
||||||
|
if(err){
|
||||||
|
res.status(400).send({
|
||||||
|
message: errorHandler.getErrorMessage(err)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).send('Form submissions successfully deleted');
|
||||||
|
});
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Submit a form entry
|
* Submit a form entry
|
||||||
*/
|
*/
|
||||||
exports.createSubmission = function(req, res) {
|
exports.createSubmission = function(req, res) {
|
||||||
|
|
||||||
var submission = new FormSubmission(),
|
var submission,
|
||||||
form = req.form,
|
form = req.form,
|
||||||
fdfData,
|
fdfData,
|
||||||
fdfTemplate,
|
fdfTemplate,
|
||||||
that = this;
|
that = this;
|
||||||
|
|
||||||
|
submission = new FormSubmission({
|
||||||
|
admin: req.user,
|
||||||
|
form_fields: req.body.form_fields,
|
||||||
|
timeElapsed: req.body.timeElapsed
|
||||||
|
});
|
||||||
|
|
||||||
submission.form = form;
|
submission.form = form;
|
||||||
submission.admin = req.user;
|
submission.pdf = form.pdf;
|
||||||
submission.form_fields = req.body.form_fields;
|
submission.title = form.title;
|
||||||
submission.title = req.body.title;
|
|
||||||
submission.timeElapsed = req.body.timeElapsed;
|
|
||||||
// submission.ipAddr = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
// submission.ipAddr = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
||||||
|
|
||||||
if(form.autofillPDFs){
|
if(form.autofillPDFs){
|
||||||
|
@ -93,42 +121,23 @@ exports.createSubmission = function(req, res) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fdfData = pdfFiller.fillFdfTemplate(fdfTemplate, submission.form_fields, null);
|
fdfData = pdfFiller.convFieldJson2FDF(submission.form_fields);
|
||||||
submission.fdfData = fdfData;
|
submission.fdfData = fdfData;
|
||||||
|
}else{
|
||||||
|
submission.fdfData = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
async.series([
|
submission.save(function(err){
|
||||||
function(callback){
|
|
||||||
submission.save(function(err){
|
if(err){
|
||||||
if (err) {
|
res.status(400).send({
|
||||||
callback(err);
|
message: errorHandler.getErrorMessage(err)
|
||||||
} else {
|
});
|
||||||
callback(null);
|
}
|
||||||
}
|
// console.log(results);
|
||||||
});
|
// console.log(that.form_fields);
|
||||||
},
|
res.status(200).send('Form submission successfully saved');
|
||||||
function(callback){
|
});
|
||||||
//Add submission to Form.submissionns
|
|
||||||
form.submissions.push(submission);
|
|
||||||
|
|
||||||
form.save(function(err){
|
|
||||||
if (err) {
|
|
||||||
callback(err);
|
|
||||||
} else {
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
], function(err, results) {
|
|
||||||
if(err){
|
|
||||||
res.status(400).send({
|
|
||||||
message: errorHandler.getErrorMessage(err)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// console.log(results);
|
|
||||||
// console.log(that.form_fields);
|
|
||||||
res.status(200).send('Form submission successfully saved');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,8 +181,8 @@ exports.create = function(req, res) {
|
||||||
var form = new Form(req.body.form);
|
var form = new Form(req.body.form);
|
||||||
|
|
||||||
form.admin = req.user;
|
form.admin = req.user;
|
||||||
console.log(form);
|
// console.log(form);
|
||||||
console.log(req.user);
|
// console.log(req.user);
|
||||||
|
|
||||||
form.save(function(err) {
|
form.save(function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -182,7 +191,7 @@ exports.create = function(req, res) {
|
||||||
message: errorHandler.getErrorMessage(err)
|
message: errorHandler.getErrorMessage(err)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
res.status(200).send('form created');
|
res.json(form);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -201,13 +210,16 @@ exports.read = function(req, res) {
|
||||||
exports.update = function(req, res) {
|
exports.update = function(req, res) {
|
||||||
console.log('in form.update()');
|
console.log('in form.update()');
|
||||||
|
|
||||||
console.log(req.body.form.form_fields);
|
// console.log(req.body.form.form_fields);
|
||||||
|
|
||||||
var form = req.form;
|
var form = req.form;
|
||||||
delete req.body.form.__v;
|
delete req.body.form.__v;
|
||||||
delete req.body.form._id;
|
delete req.body.form._id;
|
||||||
delete req.body.form.created;
|
delete req.body.form.created;
|
||||||
delete req.body.form.lastModified;
|
delete req.body.form.lastModified;
|
||||||
|
delete req.body.form.admin;
|
||||||
|
|
||||||
|
// console.log(form.admin);
|
||||||
|
|
||||||
//Unless we have 'admin' priviledges, updating form admin is disabled
|
//Unless we have 'admin' priviledges, updating form admin is disabled
|
||||||
if(req.user.roles.indexOf('admin') === -1) delete req.body.form.admin;
|
if(req.user.roles.indexOf('admin') === -1) delete req.body.form.admin;
|
||||||
|
@ -216,7 +228,7 @@ exports.update = function(req, res) {
|
||||||
// console.log(req.body.form);
|
// console.log(req.body.form);
|
||||||
// form.form_fields = req.body.form.form_fields;
|
// form.form_fields = req.body.form.form_fields;
|
||||||
|
|
||||||
form.save(function(err) {
|
form.save(function(err, form) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
|
@ -224,7 +236,7 @@ exports.update = function(req, res) {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('updated form');
|
console.log('updated form');
|
||||||
res.status(200).send('updated form');
|
res.json(form);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -287,6 +299,11 @@ exports.formByID = function(req, res, next, id) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if(!form.username){
|
||||||
|
form.admin = req.user;
|
||||||
|
}
|
||||||
|
// console.log(creaform.admin);
|
||||||
|
|
||||||
//Remove sensitive information from User object
|
//Remove sensitive information from User object
|
||||||
form.admin.password = null;
|
form.admin.password = null;
|
||||||
form.admin.created = null;
|
form.admin.created = null;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* Module dependencies.
|
* Module dependencies.
|
||||||
*/
|
*/
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
|
nev = require('email-verification'),
|
||||||
errorHandler = require('../errors.server.controller'),
|
errorHandler = require('../errors.server.controller'),
|
||||||
mongoose = require('mongoose'),
|
mongoose = require('mongoose'),
|
||||||
passport = require('passport'),
|
passport = require('passport'),
|
||||||
|
@ -11,89 +12,36 @@ var _ = require('lodash'),
|
||||||
config = require('../../../config/config'),
|
config = require('../../../config/config'),
|
||||||
nodemailer = require('nodemailer'),
|
nodemailer = require('nodemailer'),
|
||||||
crypto = require('crypto'),
|
crypto = require('crypto'),
|
||||||
|
nev = require('email-verification'),
|
||||||
User = mongoose.model('User');
|
User = mongoose.model('User');
|
||||||
|
|
||||||
var smtpTransport = nodemailer.createTransport(config.mailer.options);
|
var smtpTransport = nodemailer.createTransport(config.mailer.options);
|
||||||
|
|
||||||
|
// NEV configuration =====================
|
||||||
|
nev.configure({
|
||||||
|
persistentUserModel: User,
|
||||||
|
expirationTime: 600, // 10 minutes
|
||||||
|
|
||||||
/**
|
verificationURL: config.baseUrl+'/#!/verify/${URL}',
|
||||||
* Reset password GET from email token
|
transportOptions: config.mailer.options,
|
||||||
*/
|
verifyMailOptions: {
|
||||||
exports.validateResetToken = function(req, res) {
|
from: config.mailer.from,
|
||||||
User.findOne({
|
subject: 'Confirm your account',
|
||||||
resetPasswordToken: req.params.token,
|
html: '<p>Please verify your account by clicking <a href="${URL}">this link</a>. If you are unable to do so, copy and ' +
|
||||||
resetPasswordExpires: {
|
'paste the following link into your browser:</p><p>${URL}</p>',
|
||||||
$gt: Date.now()
|
text: 'Please verify your account by clicking the following link, or by copying and pasting it into your browser: ${URL}'
|
||||||
}
|
},
|
||||||
}, function(err, user) {
|
|
||||||
if (!user) {
|
|
||||||
return res.redirect('/#!/password/reset/invalid');
|
|
||||||
}
|
|
||||||
|
|
||||||
res.redirect('/#!/password/reset/' + req.params.token);
|
confirmMailOptions: {
|
||||||
});
|
from: config.mailer.from,
|
||||||
};
|
subject: 'Successfully verified!',
|
||||||
|
html: '<p>Your account has been successfully verified.</p>',
|
||||||
|
text: 'Your account has been successfully verified.'
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
});
|
||||||
* Send verification email
|
|
||||||
*/
|
|
||||||
var sendVerificationEmail = function(req, res, next) {
|
|
||||||
// Init Variables
|
|
||||||
var passwordDetails = req.body;
|
|
||||||
|
|
||||||
async.waterfall([
|
nev.generateTempUserModel(User);
|
||||||
// Generate random token
|
|
||||||
function(done) {
|
|
||||||
crypto.randomBytes(20, function(err, buffer) {
|
|
||||||
var token = buffer.toString('hex');
|
|
||||||
done(err, token);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(token, done) {
|
|
||||||
// For security measurement we remove the roles from the req.body object
|
|
||||||
delete req.body.roles;
|
|
||||||
|
|
||||||
// Init Variables
|
|
||||||
var user = new User(req.body);
|
|
||||||
user.resetPasswordToken = token;
|
|
||||||
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
|
|
||||||
|
|
||||||
// Add missing user fields
|
|
||||||
user.provider = 'local';
|
|
||||||
user.displayName = user.firstName + ' ' + user.lastName;
|
|
||||||
|
|
||||||
// Then save the user
|
|
||||||
user.save(function(err) {
|
|
||||||
done(err, token, user);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(token, user, done) {
|
|
||||||
res.render('templates/verify-account-email', {
|
|
||||||
name: user.displayName,
|
|
||||||
url: 'http://' + req.headers.host + '/auth/activate/' + token,
|
|
||||||
appName: config.app.title
|
|
||||||
}, function(err, emailHTML) {
|
|
||||||
done(err, emailHTML, user);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
// If valid email, send reset email using service
|
|
||||||
function(emailHTML, user, done) {
|
|
||||||
var mailOptions = {
|
|
||||||
to: user.email,
|
|
||||||
from: config.mailer.from,
|
|
||||||
subject: 'Please verify your email',
|
|
||||||
html: emailHTML
|
|
||||||
};
|
|
||||||
|
|
||||||
smtpTransport.sendMail(mailOptions, function(err) {
|
|
||||||
done(err, 'done');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
], function(err) {
|
|
||||||
if (err) return next(err);
|
|
||||||
res.status(200).send('new user successfully registered');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signup
|
* Signup
|
||||||
|
@ -104,32 +52,44 @@ exports.signup = function(req, res) {
|
||||||
|
|
||||||
// Init Variables
|
// Init Variables
|
||||||
var user = new User(req.body);
|
var user = new User(req.body);
|
||||||
var message = null;
|
|
||||||
|
|
||||||
// Add missing user fields
|
// Add missing user fields
|
||||||
user.provider = 'local';
|
user.provider = 'local';
|
||||||
|
user.username = user.email;
|
||||||
user.displayName = user.firstName + ' ' + user.lastName;
|
user.displayName = user.firstName + ' ' + user.lastName;
|
||||||
|
|
||||||
// Then save the user
|
// Then save the temporary user
|
||||||
user.save(function(err) {
|
nev.createTempUser(user, function(newTempUser) {
|
||||||
if (err) {
|
// new user created
|
||||||
return res.status(400).send({
|
if (newTempUser) {
|
||||||
message: errorHandler.getErrorMessage(err)
|
nev.registerTempUser(newTempUser);
|
||||||
});
|
res.status(200).send('An email has been sent to you. Please check it to verify your account.');
|
||||||
} else {
|
} else {
|
||||||
// Remove sensitive data before login
|
res.status(400).send('Error: Temp user could NOT be created!');
|
||||||
user.password = undefined;
|
}
|
||||||
user.salt = undefined;
|
});
|
||||||
res.status(200).send('new user successfully registered');
|
};
|
||||||
|
|
||||||
// req.login(user, function(err) {
|
exports.validateVerificationToken = function(req, res, next){
|
||||||
// if (err) {
|
|
||||||
// res.status(400).send(err);
|
nev.confirmTempUser(req.params.token, function(user) {
|
||||||
// } else {
|
if (user){
|
||||||
// res.status(200).send('new user successfully registered');
|
res.status(200).send('User successfully verified');
|
||||||
// }
|
}else {
|
||||||
// });
|
// redirect to resend verification email
|
||||||
}
|
res.status(401).send('Verification token is invalid or has expired');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.resendVerificationEmail = function(req, res, next){
|
||||||
|
nev.resendVerificationEmail(req.body.email, function(user) {
|
||||||
|
if (user){
|
||||||
|
res.status(200).send('User successfully verified');
|
||||||
|
}else {
|
||||||
|
// user hasn't been found yet
|
||||||
|
res.status(400).send( {message: 'Error: User could NOT be verified'} );
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
45
app/controllers/users/users.verify.server.controller.js
Normal file
45
app/controllers/users/users.verify.server.controller.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('users').controller('VerifyController', ['$scope', '$location', '$state', '$rootScope', 'User', 'Auth',
|
||||||
|
function($scope, $location, $state, $rootScope, User, Auth) {
|
||||||
|
|
||||||
|
$scope = $rootScope;
|
||||||
|
$scope.credentials = {};
|
||||||
|
$scope.error = null;
|
||||||
|
$scope.success = null;
|
||||||
|
|
||||||
|
// If user is signed in then redirect back home
|
||||||
|
if ($scope.authentication.isAuthenticated()) $state.go('home');
|
||||||
|
|
||||||
|
$scope.validateVerifyToken = function(){
|
||||||
|
$scope.success = $scope.error = null;
|
||||||
|
User.validateVerifyToken($stateParams.token).then(
|
||||||
|
function(response){
|
||||||
|
// If successful show success message and clear form
|
||||||
|
$scope.success = response.message;
|
||||||
|
$scope.passwordDetails = null;
|
||||||
|
},
|
||||||
|
function(error){
|
||||||
|
$scope.error = error.message || error;
|
||||||
|
$scope.passwordDetails = null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Submit forgotten password account id
|
||||||
|
$scope.resendVerifyEmail = function() {
|
||||||
|
User.resendVerifyEmail($scope.email).then(
|
||||||
|
function(response){
|
||||||
|
$scope.success = response.message;
|
||||||
|
$scope.credentials = null;
|
||||||
|
},
|
||||||
|
function(error){
|
||||||
|
$scope.error = error;
|
||||||
|
$scope.credentials = null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
]);
|
|
@ -12,9 +12,10 @@ var mongoose = require('mongoose'),
|
||||||
config = require('../../config/config'),
|
config = require('../../config/config'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
fs = require('fs-extra'),
|
fs = require('fs-extra'),
|
||||||
async = require('async');
|
async = require('async'),
|
||||||
var Field = mongoose.model('Field', FieldSchema);
|
Field = mongoose.model('Field', FieldSchema),
|
||||||
var FormSubmission = mongoose.model('FormSubmission', FormSubmissionSchema);
|
FormSubmission = mongoose.model('FormSubmission', FormSubmissionSchema),
|
||||||
|
_original;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,7 +34,7 @@ var FormSchema = new Schema({
|
||||||
type: String,
|
type: String,
|
||||||
trim: true,
|
trim: true,
|
||||||
unique: true,
|
unique: true,
|
||||||
required: 'Title cannot be blank'
|
required: 'Title cannot be blank',
|
||||||
},
|
},
|
||||||
language: {
|
language: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -47,10 +48,6 @@ var FormSchema = new Schema({
|
||||||
},
|
},
|
||||||
form_fields: {
|
form_fields: {
|
||||||
type: [FieldSchema],
|
type: [FieldSchema],
|
||||||
set: function(form_fields) {
|
|
||||||
this._previousFormFields = this.form_fields;
|
|
||||||
return form_fields;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
submissions: [{
|
submissions: [{
|
||||||
|
@ -89,10 +86,6 @@ var FormSchema = new Schema({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
FormSchema.post('init', function() {
|
|
||||||
this._original = this.toObject();
|
|
||||||
});
|
|
||||||
|
|
||||||
//Delete template PDF of current Form
|
//Delete template PDF of current Form
|
||||||
FormSchema.pre('remove', function (next) {
|
FormSchema.pre('remove', function (next) {
|
||||||
if(this.pdf){
|
if(this.pdf){
|
||||||
|
@ -104,6 +97,21 @@ FormSchema.pre('remove', function (next) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Set _original
|
||||||
|
FormSchema.pre('save', function (next) {
|
||||||
|
this.constructor // ≈ mongoose.model('…', FieldSchema).findById
|
||||||
|
.findOne({title: this.title}, function(err, original){
|
||||||
|
if(err) next(err);
|
||||||
|
else {
|
||||||
|
_original = original;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Update lastModified and created everytime we save
|
//Update lastModified and created everytime we save
|
||||||
FormSchema.pre('save', function (next) {
|
FormSchema.pre('save', function (next) {
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
|
@ -114,29 +122,12 @@ FormSchema.pre('save', function (next) {
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
//Concatenate submission and form's form_fields
|
|
||||||
// FormSchema.pre('save', function (next) {
|
|
||||||
// if(this.isModified('form_fields')){
|
|
||||||
|
|
||||||
// if(this.submissions.length){
|
|
||||||
// for(var i=0; i<this.submissions.length; i++){
|
|
||||||
// var submission = this.submissions[i];
|
|
||||||
// console.log(submission.form_fields);
|
|
||||||
// this.submissions[i].form_fields = submission.form_fields.concat(_.difference(this.form_fields, this._previousFormFields));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this.form_fields = this._previousFormFields.concat(_.difference(this.form_fields, this._previousFormFields));
|
|
||||||
// }
|
|
||||||
// next();
|
|
||||||
// });
|
|
||||||
|
|
||||||
function getDeletedIndexes(needle, haystack){
|
function getDeletedIndexes(needle, haystack){
|
||||||
var deletedIndexes = [];
|
var deletedIndexes = [];
|
||||||
|
|
||||||
if(haystack.length > 0){
|
if(haystack.length > 0){
|
||||||
for(var i = 0; i < needle.length; i++){
|
for(var i = 0; i < needle.length; i++){
|
||||||
if(haystack.indexOf(needle[i]) <= -1){
|
if(haystack.indexOf(needle[i]) === -1){
|
||||||
deletedIndexes.push(i);
|
deletedIndexes.push(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,100 +135,6 @@ function getDeletedIndexes(needle, haystack){
|
||||||
return deletedIndexes;
|
return deletedIndexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FormSchema.pre('save', function (next) {
|
|
||||||
if(this.isModified('form_fields')){
|
|
||||||
|
|
||||||
var old_form_fields = this._original.form_fields,
|
|
||||||
old_ids = _.pluck(this.form_fields, '_id'),
|
|
||||||
new_ids = _.pluck(old_form_fields, '_id'),
|
|
||||||
deletedIds = getDeletedIndexes(old_ids, new_ids),
|
|
||||||
that = this;
|
|
||||||
|
|
||||||
// console.log(deletedIds);
|
|
||||||
// console.log('old_ids\n--------');
|
|
||||||
// console.log(old_ids);
|
|
||||||
// console.log('new_ids\n--------');
|
|
||||||
// console.log(new_ids);
|
|
||||||
|
|
||||||
//Preserve fields that have at least one submission
|
|
||||||
if( deletedIds.length > 0 ){
|
|
||||||
|
|
||||||
var modifiedSubmissions;
|
|
||||||
|
|
||||||
async.forEachOfSeries(deletedIds, function (deletedIdIndex, key, callback) {
|
|
||||||
|
|
||||||
var deleted_id = old_ids[deletedIdIndex];
|
|
||||||
|
|
||||||
//Search for submissions with deleted form_field
|
|
||||||
FormSubmission.
|
|
||||||
find({ form: that, admin: that.admin, form_fields: {$elemMatch: {_id: deleted_id} } }).
|
|
||||||
exec(function(err, submissions){
|
|
||||||
if(err){
|
|
||||||
console.error(err);
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Delete field if there are no submission(s) found
|
|
||||||
if(submissions.length > 0) {
|
|
||||||
//Push old form_field to start of array
|
|
||||||
that.form_fields.unshift(old_form_fields[deletedIdIndex]);
|
|
||||||
modifiedSubmissions.push.apply(modifiedSubmissions, submissions);
|
|
||||||
console.log(modifiedSubmissions);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, modifiedSubmissions);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}, function (err, submissions) {
|
|
||||||
if(err){
|
|
||||||
console.error(err.message);
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('preserved deleted fields');
|
|
||||||
console.log(submissions);
|
|
||||||
|
|
||||||
async.forEachOfSeries(modifiedSubmissions, function (submission, key, callback) {
|
|
||||||
|
|
||||||
for(var i = 0; i < deletedIds.length; i++){
|
|
||||||
var tmpField = _.find(submission.form_fields, function(field){
|
|
||||||
return field._id === deletedIds[i];
|
|
||||||
});
|
|
||||||
|
|
||||||
var index = submission.form_fields.indexOf(tmpField);
|
|
||||||
|
|
||||||
if(tmpField){
|
|
||||||
//Delete old form_field
|
|
||||||
submission.form_fields.splice(index, 1);
|
|
||||||
|
|
||||||
//Move old form_field to start
|
|
||||||
submission.form_fields.unshift(tmpField);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
submission.save(function (err) {
|
|
||||||
if (err) callback(err);
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
|
|
||||||
}, function (err) {
|
|
||||||
if(err){
|
|
||||||
console.error(err.message);
|
|
||||||
next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
next();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
//Move PDF to permanent location after new template is uploaded
|
//Move PDF to permanent location after new template is uploaded
|
||||||
FormSchema.pre('save', function (next) {
|
FormSchema.pre('save', function (next) {
|
||||||
|
|
||||||
|
@ -245,7 +142,7 @@ FormSchema.pre('save', function (next) {
|
||||||
var that = this;
|
var that = this;
|
||||||
async.series([
|
async.series([
|
||||||
function(callback){
|
function(callback){
|
||||||
if(that.isModified('pdf')){
|
if(that.isModified('pdf') && that.pdf.path){
|
||||||
|
|
||||||
var new_filename = that.title.replace(/ /g,'')+'_template.pdf';
|
var new_filename = that.title.replace(/ /g,'')+'_template.pdf';
|
||||||
|
|
||||||
|
@ -258,21 +155,25 @@ FormSchema.pre('save', function (next) {
|
||||||
fs.mkdirSync(newDestination);
|
fs.mkdirSync(newDestination);
|
||||||
}
|
}
|
||||||
if (stat && !stat.isDirectory()) {
|
if (stat && !stat.isDirectory()) {
|
||||||
callback( new Error('Directory cannot be created because an inode of a different type exists at "' + config.pdfUploadPath + '"'), null);
|
return callback( new Error('Directory cannot be created because an inode of a different type exists at "' + config.pdfUploadPath + '"'), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.move(that.pdf.path, path.join(newDestination, new_filename), function (err) {
|
var old_path = that.pdf.path;
|
||||||
|
fs.move(old_path, path.join(newDestination, new_filename), {clobber: true}, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
callback( new Error(err.message), null);
|
callback( new Error(err.message), 'task1');
|
||||||
}
|
}else {
|
||||||
that.pdf.path = path.join(newDestination, new_filename);
|
that.pdf.path = path.join(newDestination, new_filename);
|
||||||
that.pdf.name = new_filename;
|
that.pdf.name = new_filename;
|
||||||
|
|
||||||
callback(null,'task1');
|
callback(null,'task1');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
}else {
|
||||||
|
callback(null,'task1');
|
||||||
}
|
}
|
||||||
callback(null,'task1');
|
|
||||||
},
|
},
|
||||||
function(callback){
|
function(callback){
|
||||||
if(that.isGenerated){
|
if(that.isGenerated){
|
||||||
|
@ -288,7 +189,7 @@ FormSchema.pre('save', function (next) {
|
||||||
'Radio': 'radio'
|
'Radio': 'radio'
|
||||||
};
|
};
|
||||||
|
|
||||||
// console.log('autogenerating form');
|
console.log('autogenerating form');
|
||||||
// console.log(that.pdf.path);
|
// console.log(that.pdf.path);
|
||||||
|
|
||||||
pdfFiller.generateFieldJson(that.pdf.path, function(err, _form_fields){
|
pdfFiller.generateFieldJson(that.pdf.path, function(err, _form_fields){
|
||||||
|
@ -298,6 +199,7 @@ FormSchema.pre('save', function (next) {
|
||||||
callback( new Error('Generated formfields is empty'), null);
|
callback( new Error('Generated formfields is empty'), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// console.log(_form_fields);
|
||||||
//Map PDF field names to FormField field names
|
//Map PDF field names to FormField field names
|
||||||
for(var i = 0; i < _form_fields.length; i++){
|
for(var i = 0; i < _form_fields.length; i++){
|
||||||
var field = _form_fields[i];
|
var field = _form_fields[i];
|
||||||
|
@ -315,10 +217,11 @@ FormSchema.pre('save', function (next) {
|
||||||
// console.log('NEW FORM_FIELDS: ');
|
// console.log('NEW FORM_FIELDS: ');
|
||||||
// console.log(_form_fields);
|
// console.log(_form_fields);
|
||||||
|
|
||||||
|
that.form_fields = that.form_fields.concat(_form_fields);
|
||||||
|
|
||||||
// console.log('\n\nOLD FORM_FIELDS: ');
|
// console.log('\n\nOLD FORM_FIELDS: ');
|
||||||
// console.log(that.form_fields);
|
// console.log(that.form_fields);
|
||||||
|
that.isGenerated = false;
|
||||||
that.form_fields.concat(_form_fields);
|
|
||||||
callback(null, 'task2');
|
callback(null, 'task2');
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
|
@ -335,78 +238,151 @@ FormSchema.pre('save', function (next) {
|
||||||
next();
|
next();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
}else if(_original){
|
||||||
|
if(_original.pdf){
|
||||||
|
fs.remove(_original.pdf.path, function (err) {
|
||||||
|
if(err) next(err);
|
||||||
|
console.log('file at '+_original.pdf.path+' successfully deleted');
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Autogenerate Form_fields from PDF if 'isGenerated' flag is set
|
FormSchema.pre('save', function (next) {
|
||||||
// FormSchema.pre('save', function (next) {
|
// console.log(this.form_fields);
|
||||||
// var field, _form_fields;
|
|
||||||
|
// console.log('_original\n------------\n\n');
|
||||||
|
// console.log(_original);
|
||||||
|
// console.log(this.isModified('form_fields') && !!this.form_fields && !!_original);
|
||||||
|
if(this.isModified('form_fields') && this.form_fields && _original){
|
||||||
|
|
||||||
|
var old_form_fields = _original.form_fields,
|
||||||
|
new_ids = _.map(_.pluck(this.form_fields, '_id'), function(id){ return ''+id;}),
|
||||||
|
old_ids = _.map(_.pluck(old_form_fields, '_id'), function(id){ return ''+id;}),
|
||||||
|
deletedIds = getDeletedIndexes(old_ids, new_ids),
|
||||||
|
that = this;
|
||||||
|
|
||||||
|
// console.log('deletedId Indexes\n--------');
|
||||||
|
// console.log(deletedIds);
|
||||||
|
// console.log('old_ids\n--------');
|
||||||
|
// console.log(old_ids);
|
||||||
|
// console.log('new_ids\n--------');
|
||||||
|
// console.log(new_ids);
|
||||||
|
|
||||||
|
//Preserve fields that have at least one submission
|
||||||
|
if( deletedIds.length > 0 ){
|
||||||
|
|
||||||
|
var modifiedSubmissions = [];
|
||||||
|
|
||||||
|
async.forEachOfSeries(deletedIds,
|
||||||
|
function (deletedIdIndex, key, callback) {
|
||||||
|
|
||||||
|
var deleted_id = old_ids[deletedIdIndex];
|
||||||
|
|
||||||
|
//Search for submissions with deleted form_field
|
||||||
|
// if(submissions.length){
|
||||||
|
// submissionsWithDeletedField = _.select(form.submissions, function(submission){
|
||||||
|
// var field = _(submission.form_fields).filter(function(field) { return field._id === deleted_id; })
|
||||||
|
// return !!field;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// //Push old form_field to start of array
|
||||||
|
// if(submissionsWithDeletedField.length){
|
||||||
|
// that.form_fields.unshift(old_form_fields[deletedIdIndex]);
|
||||||
|
// modifiedSubmissions.push.apply(modifiedSubmissions, submissionsWithDeletedField);
|
||||||
|
// console.log(modifiedSubmissions);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// callback(null, modifiedSubmissions);
|
||||||
|
// } else{
|
||||||
|
FormSubmission.
|
||||||
|
find({ form: that._id, admin: that.admin, form_fields: {$elemMatch: {_id: deleted_id} } }).
|
||||||
|
exec(function(err, submissions){
|
||||||
|
if(err){
|
||||||
|
console.error(err);
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
// console.log(submissions);
|
||||||
|
|
||||||
// if(this.pdf){
|
|
||||||
// if(this.isGenerated){
|
|
||||||
|
|
||||||
// var _typeConvMap = {
|
//Delete field if there are no submission(s) found
|
||||||
// 'Multiline': 'textarea',
|
if(submissions.length) {
|
||||||
// 'Text': 'textfield',
|
//Push old form_field to start of array
|
||||||
// 'Button': 'checkbox',
|
// that.form_fields.unshift(old_form_fields[deletedIdIndex]);
|
||||||
// 'Choice': 'radio',
|
modifiedSubmissions.push.apply(modifiedSubmissions, submissions);
|
||||||
// 'Password': 'password',
|
}
|
||||||
// 'FileSelect': 'filefield',
|
|
||||||
// 'Radio': 'radio'
|
|
||||||
// };
|
|
||||||
|
|
||||||
// var that = this;
|
callback(null);
|
||||||
// console.log('autogenerating form');
|
});
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
function (err) {
|
||||||
|
if(err){
|
||||||
|
console.error(err.message);
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
|
||||||
// try {
|
// console.log('modifiedSubmissions\n---------\n\n');
|
||||||
// pdfFiller.generateFieldJson(this.pdf.path, function(_form_fields){
|
// console.log(modifiedSubmissions);
|
||||||
|
|
||||||
// //Map PDF field names to FormField field names
|
// console.log('preserved deleted fields');
|
||||||
// for(var i = 0; i < _form_fields.length; i++){
|
// console.log(submissions);
|
||||||
// field = _form_fields[i];
|
|
||||||
|
|
||||||
// //Convert types from FDF to 'FormField' types
|
async.forEachOfSeries(modifiedSubmissions, function (submission, key, callback) {
|
||||||
// if(_typeConvMap[ field.fieldType+'' ]){
|
|
||||||
// field.fieldType = _typeConvMap[ field.fieldType+'' ];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// field.fieldValue = '';
|
for(var i = 0; i < deletedIds.length; i++){
|
||||||
// field.created = Date.now();
|
|
||||||
// field.required = true;
|
|
||||||
// field.disabled = false;
|
|
||||||
|
|
||||||
// // field = new Field(field);
|
var index = _.findIndex(submission.form_fields, function(field) {
|
||||||
// // field.save(function(err) {
|
var tmp_id = field._id+'';
|
||||||
// // if (err) {
|
// console.log(tmp_id === old_ids[ deletedIds[i] ]);
|
||||||
// // console.error(err.message);
|
return tmp_id === old_ids[ deletedIds[i] ];
|
||||||
// // throw new Error(err.message);
|
});
|
||||||
// // });
|
|
||||||
// // } else {
|
|
||||||
// // _form_fields[i] = this;
|
|
||||||
// // }
|
|
||||||
// // });
|
|
||||||
// _form_fields[i] = field;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// console.log('NEW FORM_FIELDS: ');
|
// console.log('index: '+index);
|
||||||
// console.log(_form_fields);
|
|
||||||
|
|
||||||
// console.log('\n\nOLD FORM_FIELDS: ');
|
var tmpField = submission.form_fields[index];
|
||||||
// console.log(that.form_fields);
|
|
||||||
|
|
||||||
// that.form_fields = _form_fields;
|
if(tmpField){
|
||||||
// next();
|
// console.log('tmpField\n-------\n\n');
|
||||||
// });
|
// console.log(tmpField);
|
||||||
// } catch(err){
|
//Delete old form_field
|
||||||
// next( new Error(err.message) );
|
submission.form_fields.splice(index, 1);
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// next();
|
tmpField.deletePreserved = true;
|
||||||
// });
|
//Move old form_field to start
|
||||||
|
submission.form_fields.unshift(tmpField);
|
||||||
|
|
||||||
|
that.form_fields.unshift(tmpField);
|
||||||
|
// console.log('form.form_fields\n--------\n\n');
|
||||||
|
// console.log(that.form_fields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
submission.save(function (err) {
|
||||||
|
if(err) callback(err);
|
||||||
|
else callback(null);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
if(err){
|
||||||
|
console.error(err.message);
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
// console.log('form.form_fields\n--------\n\n');
|
||||||
|
// console.log(that.form_fields);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
FormSchema.methods.generateFDFTemplate = function() {
|
FormSchema.methods.generateFDFTemplate = function() {
|
||||||
var _keys = _.pluck(this.form_fields, 'title'),
|
var _keys = _.pluck(this.form_fields, 'title'),
|
||||||
|
|
|
@ -41,14 +41,14 @@ function validateFormFieldType(value) {
|
||||||
* Question Schema
|
* Question Schema
|
||||||
*/
|
*/
|
||||||
var FormFieldSchema = new Schema({
|
var FormFieldSchema = new Schema({
|
||||||
created: {
|
// created: {
|
||||||
type: Date,
|
// type: Date,
|
||||||
default: Date.now
|
// default: Date.now
|
||||||
},
|
// },
|
||||||
lastModified: {
|
// lastModified: {
|
||||||
type: Date,
|
// type: Date,
|
||||||
default: Date.now
|
// default: Date.now
|
||||||
},
|
// },
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
|
@ -70,6 +70,11 @@ var FormFieldSchema = new Schema({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
deletePreserved: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
fieldType: {
|
fieldType: {
|
||||||
type: String,
|
type: String,
|
||||||
required: 'Field type cannot be blank',
|
required: 'Field type cannot be blank',
|
||||||
|
|
|
@ -10,15 +10,15 @@ var mongoose = require('mongoose'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
config = require('../../config/config'),
|
config = require('../../config/config'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
fs = require('fs-extra');
|
fs = require('fs-extra'),
|
||||||
|
FieldSchema = require('./form_field.server.model.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form Submission Schema
|
* Form Submission Schema
|
||||||
*/
|
*/
|
||||||
var FormSubmissionSchema = new Schema({
|
var FormSubmissionSchema = new Schema({
|
||||||
title: {
|
title:{
|
||||||
type: String,
|
type: String
|
||||||
required: true,
|
|
||||||
},
|
},
|
||||||
created: {
|
created: {
|
||||||
type: Date,
|
type: Date,
|
||||||
|
@ -28,17 +28,17 @@ var FormSubmissionSchema = new Schema({
|
||||||
admin: {
|
admin: {
|
||||||
type: Schema.Types.ObjectId,
|
type: Schema.Types.ObjectId,
|
||||||
ref: 'User',
|
ref: 'User',
|
||||||
|
required: true
|
||||||
},
|
},
|
||||||
form_fields: [{type: Schema.Types.Mixed}],
|
form_fields: [Schema.Types.Mixed],//[FieldSchema],
|
||||||
form: {
|
form: {
|
||||||
type: Schema.Types.ObjectId,
|
type:Schema.Types.ObjectId,
|
||||||
ref: 'Form',
|
ref:'Form',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
ipAddr: {
|
ipAddr: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false
|
|
||||||
},
|
},
|
||||||
geoLocation: {
|
geoLocation: {
|
||||||
type: Schema.Types.Mixed,
|
type: Schema.Types.Mixed,
|
||||||
|
@ -47,6 +47,9 @@ var FormSubmissionSchema = new Schema({
|
||||||
pdfFilePath: {
|
pdfFilePath: {
|
||||||
type: Schema.Types.Mixed,
|
type: Schema.Types.Mixed,
|
||||||
},
|
},
|
||||||
|
pdf: {
|
||||||
|
type: Schema.Types.Mixed,
|
||||||
|
},
|
||||||
fdfData: {
|
fdfData: {
|
||||||
type: Schema.Types.Mixed,
|
type: Schema.Types.Mixed,
|
||||||
},
|
},
|
||||||
|
@ -57,62 +60,58 @@ var FormSubmissionSchema = new Schema({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//Check for IP Address of submitting person
|
//Mongoose Relationship initialization
|
||||||
// FormSubmissionSchema.pre('save', function (next){
|
// FormSubmissionSchema.plugin(relationship, { relationshipPathName:'form' });
|
||||||
// if(this.ipAddr){
|
|
||||||
// if(this.ipAddr.modified){
|
|
||||||
// satelize.satelize({ip: this.ipAddr}, function(err, geoData){
|
|
||||||
// if (err) next( new Error(err.message) );
|
|
||||||
|
|
||||||
// this.geoLocation = JSON.parse(geoData);
|
|
||||||
// next();
|
//Check for IP Address of submitting person
|
||||||
// });
|
FormSubmissionSchema.pre('save', function (next){
|
||||||
// }
|
if(this.ipAddr){
|
||||||
// }
|
if(this.ipAddr.modified){
|
||||||
// console.log('ipAddr check');
|
satelize.satelize({ip: this.ipAddr}, function(err, geoData){
|
||||||
// next();
|
if (err) next( new Error(err.message) );
|
||||||
// });
|
|
||||||
|
this.geoLocation = JSON.parse(geoData);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('ipAddr check');
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
//Generate autofilled PDF if flags are set
|
//Generate autofilled PDF if flags are set
|
||||||
FormSubmissionSchema.pre('save', function (next) {
|
FormSubmissionSchema.pre('save', function (next) {
|
||||||
// debugger;
|
var fdfData, dest_filename, dest_path,
|
||||||
var fdfData, dest_filename, dest_path;
|
that = this,
|
||||||
var that = this;
|
_form = this.form;
|
||||||
var _form = this.form;
|
console.log(this.pdf);
|
||||||
|
|
||||||
// Form.findById(that.form, function(err, _form){
|
if(this.pdf.path){
|
||||||
// if(err) next( new Error(err.mesasge) );
|
|
||||||
|
|
||||||
that.title = _form.title;
|
|
||||||
// console.log(_form);
|
|
||||||
|
|
||||||
if(_form.autofillPDFs){
|
dest_filename = that.title.replace(/ /g,'')+'_submission_'+Date.now()+'.pdf';
|
||||||
|
var __path = this.pdf.path.split('/').slice(0,this.pdf.path.split('/').length-1).join('/');
|
||||||
|
dest_path = path.join(__path, dest_filename);
|
||||||
|
|
||||||
dest_filename = _form.title.replace(/ /g,'')+'_submission_'+Date.now()+'.pdf';
|
that.pdfFilePath = dest_path;
|
||||||
dest_path = path.join(config.pdfUploadPath, dest_filename);
|
|
||||||
|
|
||||||
this.pdfFilePath = dest_path;
|
pdfFiller.fillForm(that.pdf.path, dest_path, that.fdfData, function(err){
|
||||||
|
console.log('fdfData: \n');
|
||||||
|
console.log(that.fdfData);
|
||||||
|
|
||||||
|
// console.log('_form.pdf.path: '+_form.pdf.path);
|
||||||
|
// console.log('dest_path: '+dest_path);
|
||||||
|
|
||||||
pdfFiller.fillForm(_form.pdf.path, dest_path, that.fdfData, function(err){
|
if(err) {
|
||||||
console.log('fdfData: \n');
|
console.log('\n err.message: '+err.message);
|
||||||
console.log(that.fdfData);
|
next( new Error(err.message) );
|
||||||
|
}
|
||||||
// console.log('_form.pdf.path: '+_form.pdf.path);
|
console.log('Field data from Form: '+that.title.replace(/ /g,'')+' outputed to new PDF: '+dest_path);
|
||||||
// console.log('dest_path: '+dest_path);
|
|
||||||
|
|
||||||
if(err) {
|
|
||||||
console.log('\n err.message: '+err.message);
|
|
||||||
next( new Error(err.message) );
|
|
||||||
}
|
|
||||||
console.log('Field data from Form: '+_form.title.replace(/ /g,'')+' outputed to new PDF: '+dest_path);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
next();
|
next();
|
||||||
}
|
});
|
||||||
|
} else {
|
||||||
// });
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -47,14 +47,15 @@ var UserSchema = new Schema({
|
||||||
email: {
|
email: {
|
||||||
type: String,
|
type: String,
|
||||||
trim: true,
|
trim: true,
|
||||||
default: '',
|
unique: 'Account already exists with email',
|
||||||
|
required: 'Please enter your email',
|
||||||
validate: [validateLocalStrategyProperty, 'Please fill in your email'],
|
validate: [validateLocalStrategyProperty, 'Please fill in your email'],
|
||||||
match: [/.+\@.+\..+/, 'Please fill a valid email address']
|
match: [/.+\@.+\..+/, 'Please fill a valid email address']
|
||||||
},
|
},
|
||||||
username: {
|
username: {
|
||||||
type: String,
|
type: String,
|
||||||
unique: 'Username already exists',
|
unique: true,
|
||||||
required: 'Please fill in a username',
|
required: true,
|
||||||
trim: true
|
trim: true
|
||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
|
@ -84,21 +85,13 @@ var UserSchema = new Schema({
|
||||||
default: 'english',
|
default: 'english',
|
||||||
required: 'User must have a language'
|
required: 'User must have a language'
|
||||||
},
|
},
|
||||||
updated: {
|
lastModified: {
|
||||||
type: Date
|
type: Date
|
||||||
},
|
},
|
||||||
created: {
|
created: {
|
||||||
type: Date,
|
type: Date,
|
||||||
default: Date.now
|
default: Date.now
|
||||||
},
|
},
|
||||||
|
|
||||||
/* For account activation */
|
|
||||||
activationToken: {
|
|
||||||
type: String
|
|
||||||
},
|
|
||||||
activationTokenExpires: {
|
|
||||||
type: Date
|
|
||||||
},
|
|
||||||
|
|
||||||
/* For reset password */
|
/* For reset password */
|
||||||
resetPasswordToken: {
|
resetPasswordToken: {
|
||||||
|
@ -112,6 +105,9 @@ var UserSchema = new Schema({
|
||||||
|
|
||||||
//Create folder for user's pdfs
|
//Create folder for user's pdfs
|
||||||
UserSchema.pre('save', function (next) {
|
UserSchema.pre('save', function (next) {
|
||||||
|
if(!this.username || this.username !== this.email){
|
||||||
|
this.username = this.email;
|
||||||
|
}
|
||||||
var newDestination = path.join(config.pdfUploadPath, this.username.replace(/ /g,'')),
|
var newDestination = path.join(config.pdfUploadPath, this.username.replace(/ /g,'')),
|
||||||
stat = null;
|
stat = null;
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@ module.exports = function(app) {
|
||||||
.delete(users.requiresLogin, forms.hasAuthorization, forms.delete);
|
.delete(users.requiresLogin, forms.hasAuthorization, forms.delete);
|
||||||
|
|
||||||
app.route('/forms/:formId([a-zA-Z0-9]+)/submissions')
|
app.route('/forms/:formId([a-zA-Z0-9]+)/submissions')
|
||||||
.get(users.requiresLogin, forms.hasAuthorization, forms.listSubmissions);
|
.get(users.requiresLogin, forms.hasAuthorization, forms.listSubmissions)
|
||||||
|
.delete(users.requiresLogin, forms.hasAuthorization, forms.deleteSubmissions);
|
||||||
|
|
||||||
// Finish by binding the form middleware
|
// Finish by binding the form middleware
|
||||||
app.param('formId', forms.formByID);
|
app.param('formId', forms.formByID);
|
||||||
|
|
|
@ -14,9 +14,9 @@ module.exports = function(app) {
|
||||||
app.route('/users').put(users.requiresLogin, users.update);
|
app.route('/users').put(users.requiresLogin, users.update);
|
||||||
app.route('/users/accounts').delete(users.requiresLogin, users.removeOAuthProvider);
|
app.route('/users/accounts').delete(users.requiresLogin, users.removeOAuthProvider);
|
||||||
|
|
||||||
// Account activation reset token
|
// Setting up the users account verification api
|
||||||
app.route('/auth/reset/:token').get(users.validateResetToken);
|
app.route('/auth/verify').post(users.resendVerificationEmail);
|
||||||
app.route('/auth/reset/:token').post(users.reset);
|
app.route('/auth/verify/:token').get(users.validateVerificationToken);
|
||||||
|
|
||||||
// Setting up the users password api
|
// Setting up the users password api
|
||||||
app.route('/users/password').post(users.requiresLogin, users.changePassword);
|
app.route('/users/password').post(users.requiresLogin, users.changePassword);
|
||||||
|
|
|
@ -1,64 +1,64 @@
|
||||||
'use strict';
|
// 'use strict';
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Module dependencies.
|
// * Module dependencies.
|
||||||
*/
|
// */
|
||||||
var should = require('should'),
|
// var should = require('should'),
|
||||||
mongoose = require('mongoose'),
|
// mongoose = require('mongoose'),
|
||||||
User = mongoose.model('User'),
|
// User = mongoose.model('User'),
|
||||||
Article = mongoose.model('Article');
|
// Article = mongoose.model('Article');
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Globals
|
// * Globals
|
||||||
*/
|
// */
|
||||||
var user, article;
|
// var user, article;
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Unit tests
|
// * Unit tests
|
||||||
*/
|
// */
|
||||||
describe('Article Model Unit Tests:', function() {
|
// describe('Article Model Unit Tests:', function() {
|
||||||
beforeEach(function(done) {
|
// beforeEach(function(done) {
|
||||||
user = new User({
|
// user = new User({
|
||||||
firstName: 'Full',
|
// firstName: 'Full',
|
||||||
lastName: 'Name',
|
// lastName: 'Name',
|
||||||
displayName: 'Full Name',
|
// displayName: 'Full Name',
|
||||||
email: 'test@test.com',
|
// email: 'test@test.com',
|
||||||
username: 'username',
|
// username: 'username',
|
||||||
password: 'password'
|
// password: 'password'
|
||||||
});
|
// });
|
||||||
|
|
||||||
user.save(function() {
|
// user.save(function() {
|
||||||
article = new Article({
|
// article = new Article({
|
||||||
title: 'Article Title',
|
// title: 'Article Title',
|
||||||
content: 'Article Content',
|
// content: 'Article Content',
|
||||||
user: user
|
// user: user
|
||||||
});
|
// });
|
||||||
|
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe('Method Save', function() {
|
// describe('Method Save', function() {
|
||||||
it('should be able to save without problems', function(done) {
|
// it('should be able to save without problems', function(done) {
|
||||||
return article.save(function(err) {
|
// return article.save(function(err) {
|
||||||
should.not.exist(err);
|
// should.not.exist(err);
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should be able to show an error when try to save without title', function(done) {
|
// it('should be able to show an error when try to save without title', function(done) {
|
||||||
article.title = '';
|
// article.title = '';
|
||||||
|
|
||||||
return article.save(function(err) {
|
// return article.save(function(err) {
|
||||||
should.exist(err);
|
// should.exist(err);
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
afterEach(function(done) {
|
// afterEach(function(done) {
|
||||||
Article.remove().exec(function() {
|
// Article.remove().exec(function() {
|
||||||
User.remove().exec(done);
|
// User.remove().exec(done);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
|
@ -1,280 +1,280 @@
|
||||||
'use strict';
|
// 'use strict';
|
||||||
|
|
||||||
var should = require('should'),
|
// var should = require('should'),
|
||||||
request = require('supertest'),
|
// request = require('supertest'),
|
||||||
app = require('../../server'),
|
// app = require('../../server'),
|
||||||
mongoose = require('mongoose'),
|
// mongoose = require('mongoose'),
|
||||||
User = mongoose.model('User'),
|
// User = mongoose.model('User'),
|
||||||
Article = mongoose.model('Article'),
|
// Article = mongoose.model('Article'),
|
||||||
agent = request.agent(app);
|
// agent = request.agent(app);
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Globals
|
// * Globals
|
||||||
*/
|
// */
|
||||||
var credentials, user, article;
|
// var credentials, user, article;
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Article routes tests
|
// * Article routes tests
|
||||||
*/
|
// */
|
||||||
describe('Article CRUD tests', function() {
|
// describe('Article CRUD tests', function() {
|
||||||
beforeEach(function(done) {
|
// beforeEach(function(done) {
|
||||||
// Create user credentials
|
// // Create user credentials
|
||||||
credentials = {
|
// credentials = {
|
||||||
username: 'username',
|
// username: 'username',
|
||||||
password: 'password'
|
// password: 'password'
|
||||||
};
|
// };
|
||||||
|
|
||||||
// Create a new user
|
// // Create a new user
|
||||||
user = new User({
|
// user = new User({
|
||||||
firstName: 'Full',
|
// firstName: 'Full',
|
||||||
lastName: 'Name',
|
// lastName: 'Name',
|
||||||
displayName: 'Full Name',
|
// displayName: 'Full Name',
|
||||||
email: 'test@test.com',
|
// email: 'test@test.com',
|
||||||
username: credentials.username,
|
// username: credentials.username,
|
||||||
password: credentials.password,
|
// password: credentials.password,
|
||||||
provider: 'local'
|
// provider: 'local'
|
||||||
});
|
// });
|
||||||
|
|
||||||
// Save a user to the test db and create new article
|
// // Save a user to the test db and create new article
|
||||||
user.save(function() {
|
// user.save(function() {
|
||||||
article = {
|
// article = {
|
||||||
title: 'Article Title',
|
// title: 'Article Title',
|
||||||
content: 'Article Content'
|
// content: 'Article Content'
|
||||||
};
|
// };
|
||||||
|
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should be able to save an article if logged in', function(done) {
|
// it('should be able to save an article if logged in', function(done) {
|
||||||
agent.post('/auth/signin')
|
// agent.post('/auth/signin')
|
||||||
.send(credentials)
|
// .send(credentials)
|
||||||
.expect(200)
|
// .expect(200)
|
||||||
.end(function(signinErr, signinRes) {
|
// .end(function(signinErr, signinRes) {
|
||||||
// Handle signin error
|
// // Handle signin error
|
||||||
if (signinErr) done(signinErr);
|
// if (signinErr) done(signinErr);
|
||||||
|
|
||||||
// Get the userId
|
// // Get the userId
|
||||||
var userId = user.id;
|
// var userId = user.id;
|
||||||
|
|
||||||
// Save a new article
|
// // Save a new article
|
||||||
agent.post('/articles')
|
// agent.post('/articles')
|
||||||
.send(article)
|
// .send(article)
|
||||||
.expect(200)
|
// .expect(200)
|
||||||
.end(function(articleSaveErr, articleSaveRes) {
|
// .end(function(articleSaveErr, articleSaveRes) {
|
||||||
// Handle article save error
|
// // Handle article save error
|
||||||
if (articleSaveErr) done(articleSaveErr);
|
// if (articleSaveErr) done(articleSaveErr);
|
||||||
|
|
||||||
// Get a list of articles
|
// // Get a list of articles
|
||||||
agent.get('/articles')
|
// agent.get('/articles')
|
||||||
.end(function(articlesGetErr, articlesGetRes) {
|
// .end(function(articlesGetErr, articlesGetRes) {
|
||||||
// Handle article save error
|
// // Handle article save error
|
||||||
if (articlesGetErr) done(articlesGetErr);
|
// if (articlesGetErr) done(articlesGetErr);
|
||||||
|
|
||||||
// Get articles list
|
// // Get articles list
|
||||||
var articles = articlesGetRes.body;
|
// var articles = articlesGetRes.body;
|
||||||
|
|
||||||
// Set assertions
|
// // Set assertions
|
||||||
(articles[0].user._id).should.equal(userId);
|
// (articles[0].user._id).should.equal(userId);
|
||||||
(articles[0].title).should.match('Article Title');
|
// (articles[0].title).should.match('Article Title');
|
||||||
|
|
||||||
// Call the assertion callback
|
// // Call the assertion callback
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should not be able to save an article if not logged in', function(done) {
|
// it('should not be able to save an article if not logged in', function(done) {
|
||||||
agent.post('/articles')
|
// agent.post('/articles')
|
||||||
.send(article)
|
// .send(article)
|
||||||
.expect(401)
|
// .expect(401)
|
||||||
.end(function(articleSaveErr, articleSaveRes) {
|
// .end(function(articleSaveErr, articleSaveRes) {
|
||||||
// Call the assertion callback
|
// // Call the assertion callback
|
||||||
done(articleSaveErr);
|
// done(articleSaveErr);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should not be able to save an article if no title is provided', function(done) {
|
// it('should not be able to save an article if no title is provided', function(done) {
|
||||||
// Invalidate title field
|
// // Invalidate title field
|
||||||
article.title = '';
|
// article.title = '';
|
||||||
|
|
||||||
agent.post('/auth/signin')
|
// agent.post('/auth/signin')
|
||||||
.send(credentials)
|
// .send(credentials)
|
||||||
.expect(200)
|
// .expect(200)
|
||||||
.end(function(signinErr, signinRes) {
|
// .end(function(signinErr, signinRes) {
|
||||||
// Handle signin error
|
// // Handle signin error
|
||||||
if (signinErr) done(signinErr);
|
// if (signinErr) done(signinErr);
|
||||||
|
|
||||||
// Get the userId
|
// // Get the userId
|
||||||
var userId = user.id;
|
// var userId = user.id;
|
||||||
|
|
||||||
// Save a new article
|
// // Save a new article
|
||||||
agent.post('/articles')
|
// agent.post('/articles')
|
||||||
.send(article)
|
// .send(article)
|
||||||
.expect(400)
|
// .expect(400)
|
||||||
.end(function(articleSaveErr, articleSaveRes) {
|
// .end(function(articleSaveErr, articleSaveRes) {
|
||||||
// Set message assertion
|
// // Set message assertion
|
||||||
(articleSaveRes.body.message).should.match('Title cannot be blank');
|
// (articleSaveRes.body.message).should.match('Title cannot be blank');
|
||||||
|
|
||||||
// Handle article save error
|
// // Handle article save error
|
||||||
done(articleSaveErr);
|
// done(articleSaveErr);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should be able to update an article if signed in', function(done) {
|
// it('should be able to update an article if signed in', function(done) {
|
||||||
agent.post('/auth/signin')
|
// agent.post('/auth/signin')
|
||||||
.send(credentials)
|
// .send(credentials)
|
||||||
.expect(200)
|
// .expect(200)
|
||||||
.end(function(signinErr, signinRes) {
|
// .end(function(signinErr, signinRes) {
|
||||||
// Handle signin error
|
// // Handle signin error
|
||||||
if (signinErr) done(signinErr);
|
// if (signinErr) done(signinErr);
|
||||||
|
|
||||||
// Get the userId
|
// // Get the userId
|
||||||
var userId = user.id;
|
// var userId = user.id;
|
||||||
|
|
||||||
// Save a new article
|
// // Save a new article
|
||||||
agent.post('/articles')
|
// agent.post('/articles')
|
||||||
.send(article)
|
// .send(article)
|
||||||
.expect(200)
|
// .expect(200)
|
||||||
.end(function(articleSaveErr, articleSaveRes) {
|
// .end(function(articleSaveErr, articleSaveRes) {
|
||||||
// Handle article save error
|
// // Handle article save error
|
||||||
if (articleSaveErr) done(articleSaveErr);
|
// if (articleSaveErr) done(articleSaveErr);
|
||||||
|
|
||||||
// Update article title
|
// // Update article title
|
||||||
article.title = 'WHY YOU GOTTA BE SO MEAN?';
|
// article.title = 'WHY YOU GOTTA BE SO MEAN?';
|
||||||
|
|
||||||
// Update an existing article
|
// // Update an existing article
|
||||||
agent.put('/articles/' + articleSaveRes.body._id)
|
// agent.put('/articles/' + articleSaveRes.body._id)
|
||||||
.send(article)
|
// .send(article)
|
||||||
.expect(200)
|
// .expect(200)
|
||||||
.end(function(articleUpdateErr, articleUpdateRes) {
|
// .end(function(articleUpdateErr, articleUpdateRes) {
|
||||||
// Handle article update error
|
// // Handle article update error
|
||||||
if (articleUpdateErr) done(articleUpdateErr);
|
// if (articleUpdateErr) done(articleUpdateErr);
|
||||||
|
|
||||||
// Set assertions
|
// // Set assertions
|
||||||
(articleUpdateRes.body._id).should.equal(articleSaveRes.body._id);
|
// (articleUpdateRes.body._id).should.equal(articleSaveRes.body._id);
|
||||||
(articleUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?');
|
// (articleUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?');
|
||||||
|
|
||||||
// Call the assertion callback
|
// // Call the assertion callback
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should be able to get a list of articles if not signed in', function(done) {
|
// it('should be able to get a list of articles if not signed in', function(done) {
|
||||||
// Create new article model instance
|
// // Create new article model instance
|
||||||
var articleObj = new Article(article);
|
// var articleObj = new Article(article);
|
||||||
|
|
||||||
// Save the article
|
// // Save the article
|
||||||
articleObj.save(function() {
|
// articleObj.save(function() {
|
||||||
// Request articles
|
// // Request articles
|
||||||
request(app).get('/articles')
|
// request(app).get('/articles')
|
||||||
.end(function(req, res) {
|
// .end(function(req, res) {
|
||||||
// Set assertion
|
// // Set assertion
|
||||||
res.body.should.be.an.Array.with.lengthOf(1);
|
// res.body.should.be.an.Array.with.lengthOf(1);
|
||||||
|
|
||||||
// Call the assertion callback
|
// // Call the assertion callback
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
|
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
|
|
||||||
it('should be able to get a single article if not signed in', function(done) {
|
// it('should be able to get a single article if not signed in', function(done) {
|
||||||
// Create new article model instance
|
// // Create new article model instance
|
||||||
var articleObj = new Article(article);
|
// var articleObj = new Article(article);
|
||||||
|
|
||||||
// Save the article
|
// // Save the article
|
||||||
articleObj.save(function() {
|
// articleObj.save(function() {
|
||||||
request(app).get('/articles/' + articleObj._id)
|
// request(app).get('/articles/' + articleObj._id)
|
||||||
.end(function(req, res) {
|
// .end(function(req, res) {
|
||||||
// Set assertion
|
// // Set assertion
|
||||||
res.body.should.be.an.Object.with.property('title', article.title);
|
// res.body.should.be.an.Object.with.property('title', article.title);
|
||||||
|
|
||||||
// Call the assertion callback
|
// // Call the assertion callback
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should return proper error for single article which doesnt exist, if not signed in', function(done) {
|
// it('should return proper error for single article which doesnt exist, if not signed in', function(done) {
|
||||||
request(app).get('/articles/test')
|
// request(app).get('/articles/test')
|
||||||
.end(function(req, res) {
|
// .end(function(req, res) {
|
||||||
// Set assertion
|
// // Set assertion
|
||||||
res.body.should.be.an.Object.with.property('message', 'Article is invalid');
|
// res.body.should.be.an.Object.with.property('message', 'Article is invalid');
|
||||||
|
|
||||||
// Call the assertion callback
|
// // Call the assertion callback
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should be able to delete an article if signed in', function(done) {
|
// it('should be able to delete an article if signed in', function(done) {
|
||||||
agent.post('/auth/signin')
|
// agent.post('/auth/signin')
|
||||||
.send(credentials)
|
// .send(credentials)
|
||||||
.expect(200)
|
// .expect(200)
|
||||||
.end(function(signinErr, signinRes) {
|
// .end(function(signinErr, signinRes) {
|
||||||
// Handle signin error
|
// // Handle signin error
|
||||||
if (signinErr) done(signinErr);
|
// if (signinErr) done(signinErr);
|
||||||
|
|
||||||
// Get the userId
|
// // Get the userId
|
||||||
var userId = user.id;
|
// var userId = user.id;
|
||||||
|
|
||||||
// Save a new article
|
// // Save a new article
|
||||||
agent.post('/articles')
|
// agent.post('/articles')
|
||||||
.send(article)
|
// .send(article)
|
||||||
.expect(200)
|
// .expect(200)
|
||||||
.end(function(articleSaveErr, articleSaveRes) {
|
// .end(function(articleSaveErr, articleSaveRes) {
|
||||||
// Handle article save error
|
// // Handle article save error
|
||||||
if (articleSaveErr) done(articleSaveErr);
|
// if (articleSaveErr) done(articleSaveErr);
|
||||||
|
|
||||||
// Delete an existing article
|
// // Delete an existing article
|
||||||
agent.delete('/articles/' + articleSaveRes.body._id)
|
// agent.delete('/articles/' + articleSaveRes.body._id)
|
||||||
.send(article)
|
// .send(article)
|
||||||
.expect(200)
|
// .expect(200)
|
||||||
.end(function(articleDeleteErr, articleDeleteRes) {
|
// .end(function(articleDeleteErr, articleDeleteRes) {
|
||||||
// Handle article error error
|
// // Handle article error error
|
||||||
if (articleDeleteErr) done(articleDeleteErr);
|
// if (articleDeleteErr) done(articleDeleteErr);
|
||||||
|
|
||||||
// Set assertions
|
// // Set assertions
|
||||||
(articleDeleteRes.body._id).should.equal(articleSaveRes.body._id);
|
// (articleDeleteRes.body._id).should.equal(articleSaveRes.body._id);
|
||||||
|
|
||||||
// Call the assertion callback
|
// // Call the assertion callback
|
||||||
done();
|
// done();
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
it('should not be able to delete an article if not signed in', function(done) {
|
// it('should not be able to delete an article if not signed in', function(done) {
|
||||||
// Set article user
|
// // Set article user
|
||||||
article.user = user;
|
// article.user = user;
|
||||||
|
|
||||||
// Create new article model instance
|
// // Create new article model instance
|
||||||
var articleObj = new Article(article);
|
// var articleObj = new Article(article);
|
||||||
|
|
||||||
// Save the article
|
// // Save the article
|
||||||
articleObj.save(function() {
|
// articleObj.save(function() {
|
||||||
// Try deleting article
|
// // Try deleting article
|
||||||
request(app).delete('/articles/' + articleObj._id)
|
// request(app).delete('/articles/' + articleObj._id)
|
||||||
.expect(401)
|
// .expect(401)
|
||||||
.end(function(articleDeleteErr, articleDeleteRes) {
|
// .end(function(articleDeleteErr, articleDeleteRes) {
|
||||||
// Set message assertion
|
// // Set message assertion
|
||||||
(articleDeleteRes.body.message).should.match('User is not logged in');
|
// (articleDeleteRes.body.message).should.match('User is not logged in');
|
||||||
|
|
||||||
// Handle article error error
|
// // Handle article error error
|
||||||
done(articleDeleteErr);
|
// done(articleDeleteErr);
|
||||||
});
|
// });
|
||||||
|
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
afterEach(function(done) {
|
// afterEach(function(done) {
|
||||||
User.remove().exec(function() {
|
// User.remove().exec(function() {
|
||||||
Article.remove().exec(done);
|
// Article.remove().exec(done);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
|
@ -6,13 +6,14 @@
|
||||||
var should = require('should'),
|
var should = require('should'),
|
||||||
mongoose = require('mongoose'),
|
mongoose = require('mongoose'),
|
||||||
User = mongoose.model('User'),
|
User = mongoose.model('User'),
|
||||||
Form = mongoose.model('Form');
|
Form = mongoose.model('Form'),
|
||||||
|
_ = require('lodash'),
|
||||||
|
FormSubmission = mongoose.model('FormSubmission');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
var user, Form,
|
var user, myForm, mySubmission, FormFDF;
|
||||||
FormFDF;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests
|
* Unit tests
|
||||||
|
@ -29,10 +30,15 @@ describe('Form Model Unit Tests:', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
user.save(function() {
|
user.save(function() {
|
||||||
Form = new Form({
|
myForm = new Form({
|
||||||
title: 'Form Title',
|
title: 'Form Title',
|
||||||
admin: user,
|
admin: user,
|
||||||
form_fields: [{'title':'Short Text2','fieldType':'textfield','fieldValue':'','disabled':false},{'disabled':false,'created':1435952663586,'fieldValue':'','fieldFlags':'0','fieldType':'checkbox','title':'nascar'},{'disabled':false,'created':1435952663586,'fieldValue':'','fieldFlags':'0','fieldType':'checkbox','title':'hockey'}]
|
language: 'english',
|
||||||
|
form_fields: [
|
||||||
|
{'fieldType':'textfield', 'title':'First Name', 'fieldValue': ''},
|
||||||
|
{'fieldType':'checkbox', 'title':'nascar', 'fieldValue': ''},
|
||||||
|
{'fieldType':'checkbox', 'title':'hockey', 'fieldValue': ''}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
@ -41,38 +47,112 @@ describe('Form Model Unit Tests:', function() {
|
||||||
|
|
||||||
describe('Method Save', function() {
|
describe('Method Save', function() {
|
||||||
it('should be able to save without problems', function(done) {
|
it('should be able to save without problems', function(done) {
|
||||||
return Form.save(function(err) {
|
return myForm.save(function(err) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to show an error when try to save without title', function(done) {
|
it('should be able to show an error when try to save without title', function(done) {
|
||||||
Form.title = '';
|
myForm.title = '';
|
||||||
|
|
||||||
return Form.save(function(err) {
|
return myForm.save(function(err) {
|
||||||
should.exist(err);
|
should.exist(err);
|
||||||
|
should.equal(err.errors.title.message, 'Title cannot be blank');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Method generateFDFTemplate', function() {
|
describe('Test FormField and Submission Logic', function() {
|
||||||
it('should be able to generate one that is correct', function(done) {
|
var new_form_fields_add1, new_form_fields_del, submission_fields, old_fields;
|
||||||
return Form.generateFDFTemplate(function(err) {
|
|
||||||
should.not.exist(err);
|
before(function(done){
|
||||||
|
new_form_fields_add1 = _.clone(myForm.form_fields);
|
||||||
|
new_form_fields_add1.push(
|
||||||
|
{'fieldType':'textfield', 'title':'Last Name', 'fieldValue': ''}
|
||||||
|
);
|
||||||
|
|
||||||
|
new_form_fields_del = _.clone(myForm.form_fields);
|
||||||
|
new_form_fields_del.splice(0, 1);
|
||||||
|
|
||||||
|
submission_fields = _.clone(myForm.toObject().form_fields);
|
||||||
|
submission_fields[0].fieldValue = 'David';
|
||||||
|
submission_fields[1].fieldValue = true;
|
||||||
|
submission_fields[2].fieldValue = true;
|
||||||
|
|
||||||
|
mySubmission = new FormSubmission({
|
||||||
|
form_fields: submission_fields,
|
||||||
|
admin: user,
|
||||||
|
form: myForm._id,
|
||||||
|
timeElapsed: 17.55
|
||||||
|
});
|
||||||
|
|
||||||
|
mySubmission.save(function(){
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to show an error when try to save without title', function(done) {
|
after(function(done){
|
||||||
Form.title = '';
|
mySubmission.remove(function(){
|
||||||
|
|
||||||
return Form.save(function(err) {
|
|
||||||
should.exist(err);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
beforeEach(function(done){
|
||||||
|
old_fields = myForm.toObject().form_fields;
|
||||||
|
// console.log(old_fields);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should preserve deleted form_fields that have submissions without any problems', function(done) {
|
||||||
|
|
||||||
|
var expected_fields = old_fields.slice(1,3).concat(old_fields.slice(0,1));
|
||||||
|
|
||||||
|
// console.log(old_fields);
|
||||||
|
|
||||||
|
myForm.form_fields = new_form_fields_del;
|
||||||
|
return myForm.save(function(err, form) {
|
||||||
|
should.not.exist(err);
|
||||||
|
var actual_fields = form.toObject();
|
||||||
|
|
||||||
|
should.deepEqual(form.toObject().form_fields, expected_fields, 'old form_fields not equal to newly saved form_fields');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// it('should delete \'preseved\' form_fields whose submissions have been removed without any problems', function(done) {
|
||||||
|
|
||||||
|
// myForm.form_fields = new_form_fields_del;
|
||||||
|
// myForm.save(function(err, form) {
|
||||||
|
// should.not.exist(err);
|
||||||
|
// (form.form_fields).should.be.eql(old_fields, 'old form_fields not equal to newly saved form_fields');
|
||||||
|
|
||||||
|
// //Remove submission
|
||||||
|
// mySubmission.remove(function(err){
|
||||||
|
// myForm.submissions.should.have.length(0);
|
||||||
|
// myForm.form_fields.should.not.containDeep(old_fields[0]);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Method generateFDFTemplate', function() {
|
||||||
|
beforeEach(function(done){
|
||||||
|
FormFDF = {
|
||||||
|
'First Name': '',
|
||||||
|
'nascar': '',
|
||||||
|
'hockey': ''
|
||||||
|
};
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to generate a FDF template without any problems', function(done) {
|
||||||
|
var fdfTemplate = myForm.generateFDFTemplate();
|
||||||
|
(fdfTemplate).should.be.eql(FormFDF);
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function(done) {
|
afterEach(function(done) {
|
||||||
|
|
2
config/env/all.js
vendored
2
config/env/all.js
vendored
|
@ -9,6 +9,8 @@ module.exports = {
|
||||||
port: process.env.PORT || 3000,
|
port: process.env.PORT || 3000,
|
||||||
templateEngine: 'swig',
|
templateEngine: 'swig',
|
||||||
|
|
||||||
|
baseUrl: '',
|
||||||
|
|
||||||
//Sentry DSN Client Key
|
//Sentry DSN Client Key
|
||||||
DSN: 'http://db01e03015ce48e2b68240ea8254b17c:5d878e9bb6c6488fbb70fb81295ee700@sentry.polydaic.com/1',
|
DSN: 'http://db01e03015ce48e2b68240ea8254b17c:5d878e9bb6c6488fbb70fb81295ee700@sentry.polydaic.com/1',
|
||||||
|
|
||||||
|
|
10
config/env/development.js
vendored
10
config/env/development.js
vendored
|
@ -14,7 +14,7 @@ module.exports = {
|
||||||
// Stream defaults to process.stdout
|
// Stream defaults to process.stdout
|
||||||
// Uncomment to enable logging to a log on the file system
|
// Uncomment to enable logging to a log on the file system
|
||||||
options: {
|
options: {
|
||||||
//stream: 'access.log'
|
// stream: 'access.log'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
app: {
|
app: {
|
||||||
|
@ -46,12 +46,12 @@ module.exports = {
|
||||||
callbackURL: '/auth/github/callback'
|
callbackURL: '/auth/github/callback'
|
||||||
},
|
},
|
||||||
mailer: {
|
mailer: {
|
||||||
from: process.env.MAILER_FROM || 'MAILER_FROM',
|
from: process.env.MAILER_FROM || 'hi@example.com',
|
||||||
options: {
|
options: {
|
||||||
service: process.env.MAILER_SERVICE_PROVIDER || 'MAILER_SERVICE_PROVIDER',
|
service: process.env.MAILER_SERVICE_PROVIDER || 'Mandrill',
|
||||||
auth: {
|
auth: {
|
||||||
user: process.env.MAILER_EMAIL_ID || 'MAILER_EMAIL_ID',
|
user: process.env.MAILER_EMAIL_ID || 'hackouver@gmail.com',
|
||||||
pass: process.env.MAILER_PASSWORD || 'MAILER_PASSWORD'
|
pass: process.env.MAILER_PASSWORD || 'ehOLuSXCBFxLjipRalBxVg'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ module.exports = function(db) {
|
||||||
// Initialize express app
|
// Initialize express app
|
||||||
var app = express();
|
var app = express();
|
||||||
|
|
||||||
|
|
||||||
// Globbing model files
|
// Globbing model files
|
||||||
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
|
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
|
||||||
require(path.resolve(modelPath));
|
require(path.resolve(modelPath));
|
||||||
|
@ -52,7 +53,10 @@ module.exports = function(db) {
|
||||||
|
|
||||||
// Passing the request url to environment locals
|
// Passing the request url to environment locals
|
||||||
app.use(function(req, res, next) {
|
app.use(function(req, res, next) {
|
||||||
res.locals.url = req.protocol + '://' + req.headers.host + req.url;
|
if(config.baseUrl === ''){
|
||||||
|
config.baseUrl = req.protocol + '://' + req.headers.host;
|
||||||
|
}
|
||||||
|
res.locals.url = req.protocol + '://' + req.headers.host + req.url;
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -103,7 +107,8 @@ module.exports = function(db) {
|
||||||
app.disable('x-powered-by');
|
app.disable('x-powered-by');
|
||||||
|
|
||||||
// Setting the app router and static folder
|
// Setting the app router and static folder
|
||||||
app.use(express.static(path.resolve('./public')));
|
app.use('/', express.static(path.resolve('./public')));
|
||||||
|
app.use('/uploads', express.static(path.resolve('./uploads')));
|
||||||
|
|
||||||
var formCtrl = require('../app/controllers/forms.server.controller');
|
var formCtrl = require('../app/controllers/forms.server.controller');
|
||||||
// Setting the pdf upload route and folder
|
// Setting the pdf upload route and folder
|
||||||
|
|
|
@ -3,7 +3,12 @@
|
||||||
/**
|
/**
|
||||||
* Module dependencies.
|
* Module dependencies.
|
||||||
*/
|
*/
|
||||||
var applicationConfiguration = require('./config/config');
|
var applicationConfiguration = require('./config/config'),
|
||||||
|
bowerFiles = require('main-bower-files');
|
||||||
|
|
||||||
|
var bowerDep = bowerFiles('**/**.js');
|
||||||
|
|
||||||
|
console.log(bowerDep);
|
||||||
|
|
||||||
// Karma configuration
|
// Karma configuration
|
||||||
module.exports = function(config) {
|
module.exports = function(config) {
|
||||||
|
@ -12,7 +17,7 @@ module.exports = function(config) {
|
||||||
frameworks: ['jasmine'],
|
frameworks: ['jasmine'],
|
||||||
|
|
||||||
// List of files / patterns to load in the browser
|
// List of files / patterns to load in the browser
|
||||||
files: applicationConfiguration.assets.lib.js.concat(applicationConfiguration.assets.js, applicationConfiguration.assets.tests),
|
files: bowerDep.concat(applicationConfiguration.assets.js, applicationConfiguration.assets.tests),
|
||||||
|
|
||||||
// Test results reporter to use
|
// Test results reporter to use
|
||||||
// Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
|
// Possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
|
||||||
|
@ -39,7 +44,7 @@ module.exports = function(config) {
|
||||||
// - Safari (only Mac)
|
// - Safari (only Mac)
|
||||||
// - PhantomJS
|
// - PhantomJS
|
||||||
// - IE (only Windows)
|
// - IE (only Windows)
|
||||||
browsers: ['Chrome'],
|
browsers: ['PhantomJS'],
|
||||||
|
|
||||||
// If browser does not capture in given timeout [ms], kill it
|
// If browser does not capture in given timeout [ms], kill it
|
||||||
captureTimeout: 60000,
|
captureTimeout: 60000,
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
"connect-mongo": "~0.4.1",
|
"connect-mongo": "~0.4.1",
|
||||||
"consolidate": "~0.10.0",
|
"consolidate": "~0.10.0",
|
||||||
"cookie-parser": "~1.3.2",
|
"cookie-parser": "~1.3.2",
|
||||||
|
"email-verification": "^0.1.9",
|
||||||
"express": "~4.10.1",
|
"express": "~4.10.1",
|
||||||
"express-session": "~1.9.1",
|
"express-session": "~1.9.1",
|
||||||
"forever": "~0.11.0",
|
"forever": "~0.11.0",
|
||||||
|
@ -64,6 +65,7 @@
|
||||||
"mocha": ">=1.20.0",
|
"mocha": ">=1.20.0",
|
||||||
"mongoose": "~3.8.8",
|
"mongoose": "~3.8.8",
|
||||||
"mongoose-datatable": "^1.0.2",
|
"mongoose-datatable": "^1.0.2",
|
||||||
|
"mongoose-relationship": "^0.1.4",
|
||||||
"morgan": "~1.4.1",
|
"morgan": "~1.4.1",
|
||||||
"multer": "~0.1.8",
|
"multer": "~0.1.8",
|
||||||
"nodemailer": "~1.3.0",
|
"nodemailer": "~1.3.0",
|
||||||
|
|
2
public/dist/application.min.css
vendored
2
public/dist/application.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -8,27 +8,30 @@ angular.module('forms').run(['Menus',
|
||||||
}
|
}
|
||||||
]).filter('formValidity',
|
]).filter('formValidity',
|
||||||
function(){
|
function(){
|
||||||
|
|
||||||
return function(formObj){
|
return function(formObj){
|
||||||
//get keys
|
if(formObj && formObj.form_fields && formObj.visible_form_fields){
|
||||||
var formKeys = Object.keys(formObj);
|
|
||||||
|
//get keys
|
||||||
|
var formKeys = Object.keys(formObj);
|
||||||
|
|
||||||
//we only care about things that don't start with $
|
//we only care about things that don't start with $
|
||||||
var fieldKeys = formKeys.filter(function(key){
|
var fieldKeys = formKeys.filter(function(key){
|
||||||
return key[0] !== '$';
|
return key[0] !== '$';
|
||||||
});
|
});
|
||||||
|
|
||||||
var fields = formObj.form_fields;
|
var fields = formObj.form_fields;
|
||||||
// fieldKeys.map(function(key){
|
// fieldKeys.map(function(key){
|
||||||
// return formObj[key];
|
// return formObj[key];
|
||||||
// });
|
// });
|
||||||
|
|
||||||
var valid_count = fields.filter(function(field){
|
var valid_count = fields.filter(function(field){
|
||||||
if(typeof field === 'object'){
|
if(typeof field === 'object'){
|
||||||
return !!(field.fieldValue);
|
return !!(field.fieldValue);
|
||||||
}
|
}
|
||||||
}).length;
|
}).length;
|
||||||
return valid_count;
|
return valid_count - (formObj.form_fields.length - formObj.visible_form_fields.length);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
};
|
};
|
||||||
}).config(['$provide', function ($provide){
|
}).config(['$provide', function ($provide){
|
||||||
$provide.decorator('accordionDirective', function($delegate) {
|
$provide.decorator('accordionDirective', function($delegate) {
|
||||||
|
|
|
@ -10,10 +10,6 @@ angular.module('forms').config(['$stateProvider',
|
||||||
url: '/forms',
|
url: '/forms',
|
||||||
templateUrl: 'modules/forms/views/list-forms.client.view.html',
|
templateUrl: 'modules/forms/views/list-forms.client.view.html',
|
||||||
}).
|
}).
|
||||||
state('createForm', {
|
|
||||||
url: '/forms/create',
|
|
||||||
templateUrl: 'modules/forms/views/create-form.client.view.html',
|
|
||||||
}).
|
|
||||||
state('viewForm', {
|
state('viewForm', {
|
||||||
url: '/forms/:formId/admin',
|
url: '/forms/:formId/admin',
|
||||||
templateUrl: 'modules/forms/views/view-form.client.view.html',
|
templateUrl: 'modules/forms/views/view-form.client.view.html',
|
||||||
|
@ -27,10 +23,6 @@ angular.module('forms').config(['$stateProvider',
|
||||||
data: {
|
data: {
|
||||||
hideNav: true,
|
hideNav: true,
|
||||||
},
|
},
|
||||||
}).
|
|
||||||
state('editForm', {
|
|
||||||
url: '/forms/:formId/edit',
|
|
||||||
templateUrl: 'modules/forms/views/create-form.client.view.html',
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
]);
|
]);
|
|
@ -1,122 +0,0 @@
|
||||||
// 'use strict';
|
|
||||||
|
|
||||||
// angular.module('forms').controller('EditFormController', ['$scope', '$state', '$rootScope', 'Upload', '$stateParams', 'FormFields', 'Forms', 'CurrentForm', '$modal', '$location', '$http',
|
|
||||||
// function ($scope, $state, $rootScope, Upload, $stateParams, FormFields, Forms, CurrentForm, $modal, $location, $http) {
|
|
||||||
// $scope.form = {};
|
|
||||||
// $scope.isNewForm = false;
|
|
||||||
// $scope.log = '';
|
|
||||||
// $scope.pdfLoading = false;
|
|
||||||
// var _current_upload = null;
|
|
||||||
|
|
||||||
// // Get current form if it exists, or create new one
|
|
||||||
// if($stateParams.formId){
|
|
||||||
// Forms.get({ formId: $stateParams.formId}, function(form){
|
|
||||||
// $scope.form = angular.fromJson(angular.toJson(form));
|
|
||||||
// console.log($scope.form);
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// $scope.form.form_fields = [];
|
|
||||||
// $scope.isNewForm = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //PDF Functions
|
|
||||||
// $scope.cancelUpload = function(){
|
|
||||||
// _current_upload.abort();
|
|
||||||
// $scope.pdfLoading = false;
|
|
||||||
// $scope.removePDF();
|
|
||||||
// };
|
|
||||||
|
|
||||||
// $scope.removePDF = function(){
|
|
||||||
// $scope.form.pdf = null;
|
|
||||||
// $scope.form.isGenerated = false;
|
|
||||||
// $scope.form.autofillPDFs = false;
|
|
||||||
|
|
||||||
// console.log('form.pdf: '+$scope.form.pdf+' REMOVED');
|
|
||||||
// };
|
|
||||||
|
|
||||||
// $scope.uploadPDF = function(files) {
|
|
||||||
|
|
||||||
// if (files && files.length) {
|
|
||||||
// // for (var i = 0; i < files.length; i++) {
|
|
||||||
// var file = files[0];
|
|
||||||
// _current_upload = Upload.upload({
|
|
||||||
// url: '/upload/pdf',
|
|
||||||
// fields: {
|
|
||||||
// 'user': $scope.user,
|
|
||||||
// 'form': $scope.form
|
|
||||||
// },
|
|
||||||
// file: file
|
|
||||||
// }).progress(function (evt) {
|
|
||||||
// var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
|
|
||||||
// $scope.log = 'progress: ' + progressPercentage + '% ' +
|
|
||||||
// evt.config.file.name + '\n' + $scope.log;
|
|
||||||
// $scope.pdfLoading = true;
|
|
||||||
// }).success(function (data, status, headers, config) {
|
|
||||||
// $scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
|
|
||||||
// console.log($scope.form.pdf);
|
|
||||||
// $scope.form.pdf = angular.fromJson(angular.toJson(data));
|
|
||||||
// $scope.pdfLoading = false;
|
|
||||||
|
|
||||||
// console.log($scope.log);
|
|
||||||
// console.log('$scope.pdf: '+$scope.form.pdf.name);
|
|
||||||
// if(!$scope.$$phase){
|
|
||||||
// $scope.$apply();
|
|
||||||
// }
|
|
||||||
// }).error(function(err){
|
|
||||||
// $scope.pdfLoading = false;
|
|
||||||
// console.log('Error occured during upload.\n');
|
|
||||||
// console.log(err);
|
|
||||||
// });
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// $rootScope.goToWithId = function(route, id) {
|
|
||||||
// $state.go(route, {'formId': id}, {reload: true});
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Create new Form
|
|
||||||
// $rootScope.createOrUpdate = function() {
|
|
||||||
|
|
||||||
// if($scope.isNewForm){
|
|
||||||
// // Create new Form object
|
|
||||||
// var form = new Forms($scope.form);
|
|
||||||
|
|
||||||
// $http.post('/forms', {form: $scope.form})
|
|
||||||
// .success(function(data, status, headers){
|
|
||||||
// console.log('form created');
|
|
||||||
|
|
||||||
// // Clear form fields
|
|
||||||
// $scope.form = {};
|
|
||||||
// // Redirect after save
|
|
||||||
// $scope.goToWithId('viewForm', $scope.form._id);
|
|
||||||
// }).error(function(errorResponse){
|
|
||||||
// console.log(errorResponse);
|
|
||||||
// $scope.error = errorResponse;
|
|
||||||
// });
|
|
||||||
// } else{
|
|
||||||
// $scope.update(function(err){
|
|
||||||
// console.log('done updating');
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// // Update existing Form
|
|
||||||
// $rootScope.update = function(cb) {
|
|
||||||
// var form = new Forms($scope.form);
|
|
||||||
// console.log('update form');
|
|
||||||
// console.log($scope.form);
|
|
||||||
|
|
||||||
// $http.put('/forms/'+$scope.form._id, {form: $scope.form})
|
|
||||||
// .success(function(data, status, headers){
|
|
||||||
// console.log('form updated successfully');
|
|
||||||
// $scope.goToWithId('viewForm', $scope.form._id);
|
|
||||||
// cb(null);
|
|
||||||
// }).error(function(err){
|
|
||||||
// console.log('Error occured during form UPDATE.\n');
|
|
||||||
// console.log(err);
|
|
||||||
// cb(err);
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// ]);
|
|
|
@ -3,42 +3,34 @@
|
||||||
// submissions controller
|
// submissions controller
|
||||||
angular.module('forms').controller('ViewSubmissionController', ['$scope', '$stateParams', '$state', 'Submissions','$http',
|
angular.module('forms').controller('ViewSubmissionController', ['$scope', '$stateParams', '$state', 'Submissions','$http',
|
||||||
function($scope, $stateParams, $state, Submissions, $http) {
|
function($scope, $stateParams, $state, Submissions, $http) {
|
||||||
$scope.submissionId = undefined;
|
$scope.submissionId = undefined;
|
||||||
|
|
||||||
// Principal.identity().then(function(user){
|
// Return all form's submissions
|
||||||
// $scope.authentication.user = user;
|
$scope.findAll = function() {
|
||||||
// }).then(function(){
|
$scope.submissions = Submissions.query({
|
||||||
|
formId: $stateParams.formId
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Return all form's submissions
|
// Find a specific submission
|
||||||
$scope.findAll = function() {
|
$scope.findOne = function() {
|
||||||
$scope.submissions = Submissions.query({
|
$scope.submission = Submissions.get({
|
||||||
formId: $stateParams.formId
|
submissionId: $scope.submissionId,
|
||||||
});
|
formId: $stateParams.formId
|
||||||
};
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Find a specific submission
|
|
||||||
$scope.findOne = function() {
|
// Remove existing submission
|
||||||
$scope.submission = Submissions.get({
|
$scope.remove = function(submission) {
|
||||||
submissionId: $scope.submissionId,
|
if (!submission) {
|
||||||
formId: $stateParams.formId
|
submission = $scope.submission;
|
||||||
});
|
}
|
||||||
};
|
$http.delete('/forms/'+$stateParams.formId+'/submissions/'+submission._id).
|
||||||
|
success(function(data, status, headers){
|
||||||
|
console.log('submission deleted successfully');
|
||||||
// Remove existing submission
|
alert('submission deleted..');
|
||||||
$scope.remove = function(submission) {
|
});
|
||||||
if (!submission) {
|
};
|
||||||
submission = $scope.submission;
|
|
||||||
}
|
|
||||||
$http.delete('/forms/'+$stateParams.formId+'/submissions/'+submission._id).
|
|
||||||
success(function(data, status, headers){
|
|
||||||
console.log('submission deleted successfully');
|
|
||||||
alert('submission deleted..');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
]);
|
]);
|
|
@ -4,9 +4,9 @@
|
||||||
angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope', '$stateParams', '$state', 'Forms', 'CurrentForm','$http',
|
angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope', '$stateParams', '$state', 'Forms', 'CurrentForm','$http',
|
||||||
function($rootScope, $scope, $stateParams, $state, Forms, CurrentForm, $http) {
|
function($rootScope, $scope, $stateParams, $state, Forms, CurrentForm, $http) {
|
||||||
|
|
||||||
|
$scope = $rootScope;
|
||||||
$scope.myform = CurrentForm.getForm();
|
$scope.myform = CurrentForm.getForm();
|
||||||
$scope.submissions = undefined;
|
$scope.saveInProgress = false;
|
||||||
$scope.viewSubmissions = false;
|
$scope.viewSubmissions = false;
|
||||||
$scope.showCreateModal = false;
|
$scope.showCreateModal = false;
|
||||||
$scope.table = {
|
$scope.table = {
|
||||||
|
@ -34,7 +34,7 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
|
||||||
|
|
||||||
|
|
||||||
$scope.setForm = function (form) {
|
$scope.setForm = function (form) {
|
||||||
$scope.myForm = form;
|
$scope.myform = form;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Modal functions
|
//Modal functions
|
||||||
|
@ -52,6 +52,13 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
|
||||||
/*
|
/*
|
||||||
* Table Functions
|
* Table Functions
|
||||||
*/
|
*/
|
||||||
|
$scope.isAtLeastOneChecked = function(){
|
||||||
|
// console.log('isAtLeastOneChecked');
|
||||||
|
for(var i=0; i<$scope.table.rows.length; i++){
|
||||||
|
if($scope.table.rows[i].selected) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
$scope.toggleAllCheckers = function(){
|
$scope.toggleAllCheckers = function(){
|
||||||
console.log('toggleAllCheckers');
|
console.log('toggleAllCheckers');
|
||||||
for(var i=0; i<$scope.table.rows.length; i++){
|
for(var i=0; i<$scope.table.rows.length; i++){
|
||||||
|
@ -60,22 +67,56 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
|
||||||
};
|
};
|
||||||
$scope.toggleObjSelection = function($event, description) {
|
$scope.toggleObjSelection = function($event, description) {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
console.log('checkbox clicked');
|
|
||||||
};
|
};
|
||||||
$scope.rowClicked = function(obj) {
|
$scope.rowClicked = function(obj) {
|
||||||
// console.log('row clicked');
|
|
||||||
obj.selected = !obj.selected;
|
obj.selected = !obj.selected;
|
||||||
};
|
};
|
||||||
|
|
||||||
//show submissions of Form
|
/*
|
||||||
|
* Form Submission Methods
|
||||||
|
*/
|
||||||
|
//Delete selected submissions of Form
|
||||||
|
$scope.deleteSelectedSubmissions = function(){
|
||||||
|
// console.log('deleteSelectedSubmissions');
|
||||||
|
var delete_ids = [];
|
||||||
|
// for(var i=0; i<$scope.table.rows.length; i++){
|
||||||
|
// if($scope.table.rows[i].selected){
|
||||||
|
// delete_ids.push($scope.table.rows[i]._id);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
delete_ids = _.chain($scope.table.rows).filter(function(row){
|
||||||
|
return !!row.selected;
|
||||||
|
}).pluck('_id').value();
|
||||||
|
console.log(delete_ids);
|
||||||
|
|
||||||
|
$http({ url: '/forms/'+$scope.myform._id+'/submissions',
|
||||||
|
method: 'DELETE',
|
||||||
|
data: {deleted_submissions: delete_ids},
|
||||||
|
headers: {"Content-Type": "application/json;charset=utf-8"}
|
||||||
|
}).success(function(data, status, headers){
|
||||||
|
//Remove deleted ids from table
|
||||||
|
for(var i=0; i<$scope.table.rows.length; i++){
|
||||||
|
if($scope.table.rows[i].selected){
|
||||||
|
$scope.table.rows.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.error(function(err){
|
||||||
|
console.log('Could not delete form submissions.\nError: ');
|
||||||
|
console.log(err);
|
||||||
|
console.error = err;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//Fetch and display submissions of Form
|
||||||
$scope.showSubmissions = function(){
|
$scope.showSubmissions = function(){
|
||||||
$scope.viewSubmissions = true;
|
$scope.viewSubmissions = true;
|
||||||
|
|
||||||
$http.get('/forms/'+$scope.myform._id+'/submissions')
|
$http.get('/forms/'+$scope.myform._id+'/submissions')
|
||||||
.success(function(data, status, headers){
|
.success(function(data, status, headers){
|
||||||
console.log(data[0].form_fields);
|
// console.log(data[0].form_fields);
|
||||||
|
|
||||||
var _data = Array();
|
var _data = [];
|
||||||
for(var i=0; i<data.length; i++){
|
for(var i=0; i<data.length; i++){
|
||||||
|
|
||||||
var _tmpSubFormFields = JSON.parse(JSON.stringify($scope.myform.form_fields));
|
var _tmpSubFormFields = JSON.parse(JSON.stringify($scope.myform.form_fields));
|
||||||
|
@ -83,14 +124,14 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
|
||||||
for(var x=0; x<_tmpSubFormFields.length; x++){
|
for(var x=0; x<_tmpSubFormFields.length; x++){
|
||||||
|
|
||||||
var currField__id = _tmpSubFormFields[x]._id,
|
var currField__id = _tmpSubFormFields[x]._id,
|
||||||
currField = undefined;
|
currField;
|
||||||
|
|
||||||
_.find(data[i].form_fields, function(fieldItem, fieldIdx){
|
_.find(data[i].form_fields, function(fieldItem, fieldIdx){
|
||||||
if(fieldItem._id === currField__id){
|
if(fieldItem._id === currField__id){
|
||||||
currField = fieldItem;
|
currField = fieldItem;
|
||||||
console.log(fieldItem.fieldValue);
|
// console.log(fieldItem.fieldValue);
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(currField !== undefined){
|
if(currField !== undefined){
|
||||||
|
@ -101,16 +142,17 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// _tmpSubFormFields.order = i;
|
|
||||||
|
|
||||||
_data[i] = data[i];
|
_data[i] = data[i];
|
||||||
_data[i].form_fields = _tmpSubFormFields;
|
_data[i].form_fields = _tmpSubFormFields;
|
||||||
};
|
}
|
||||||
|
|
||||||
console.log(JSON.stringify(_data));
|
// console.log(JSON.stringify(_data));
|
||||||
$scope.submissions = _data;
|
$scope.submissions = _data;
|
||||||
|
|
||||||
$scope.table.rows = _data;
|
$scope.table.rows = _data;
|
||||||
|
if(!$scope.$$phase && !$scope.$digest){
|
||||||
|
$scope.$apply();
|
||||||
|
}
|
||||||
// console.log('form submissions successfully fetched');
|
// console.log('form submissions successfully fetched');
|
||||||
// console.log( JSON.parse(JSON.stringify($scope.submissions)) ) ;
|
// console.log( JSON.parse(JSON.stringify($scope.submissions)) ) ;
|
||||||
// console.log( JSON.parse(JSON.stringify($scope.myform.form_fields)) );
|
// console.log( JSON.parse(JSON.stringify($scope.myform.form_fields)) );
|
||||||
|
@ -126,8 +168,6 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
|
||||||
$scope.viewSubmissions = false;
|
$scope.viewSubmissions = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Remove existing Form
|
// Remove existing Form
|
||||||
$scope.remove = function(form_id) {
|
$scope.remove = function(form_id) {
|
||||||
var form = {};
|
var form = {};
|
||||||
|
@ -160,33 +200,32 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
|
||||||
// Create new Form
|
// Create new Form
|
||||||
$scope.createNew = function(){
|
$scope.createNew = function(){
|
||||||
var form = {};
|
var form = {};
|
||||||
form.title = $scope.myForm.name.$modelValue;
|
form.title = $scope.myform.name.$modelValue;
|
||||||
form.language = $scope.myForm.language.$modelValue;
|
form.language = $scope.myform.language.$modelValue;
|
||||||
console.log(form);
|
console.log(form);
|
||||||
$scope.showCreateModal = true;
|
$scope.showCreateModal = true;
|
||||||
|
|
||||||
console.log($scope.myForm);
|
console.log($scope.myform);
|
||||||
if($scope.myForm.$valid && $scope.myForm.$dirty){
|
if($scope.myform.$valid && $scope.myform.$dirty){
|
||||||
$http.post('/forms', {form: form})
|
$http.post('/forms', {form: form})
|
||||||
.success(function(data, status, headers){
|
.success(function(data, status, headers){
|
||||||
console.log('form created');
|
console.log('form created');
|
||||||
|
|
||||||
// Clear form fields
|
// Clear form fields
|
||||||
$scope.myForm = {};
|
$scope.myform = {};
|
||||||
// Redirect after save
|
// Redirect after save
|
||||||
$scope.goToWithId('viewForm', $scope.myform._id);
|
$scope.goToWithId('viewForm', data._id+'');
|
||||||
}).error(function(errorResponse){
|
}).error(function(errorResponse){
|
||||||
console.log(errorResponse);
|
console.log(errorResponse);
|
||||||
// $scope.error = errorResponse.data.message;
|
$scope.error = errorResponse.data.message;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Update existing Form
|
// Update existing Form
|
||||||
$scope.saveInProgress = false;
|
|
||||||
$scope.update = $rootScope.update = function(cb) {
|
$scope.update = $rootScope.update = function(cb) {
|
||||||
if(!$scope.saveInProgress){
|
if(!$rootScope.saveInProgress){
|
||||||
$scope.saveInProgress = true;
|
|
||||||
|
|
||||||
$rootScope.saveInProgress = true;
|
$rootScope.saveInProgress = true;
|
||||||
// console.log('begin updating form');
|
// console.log('begin updating form');
|
||||||
|
@ -194,15 +233,20 @@ angular.module('forms').controller('ViewFormController', ['$rootScope', '$scope'
|
||||||
|
|
||||||
$http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
|
$http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
|
||||||
.then(function(response){
|
.then(function(response){
|
||||||
// console.log('form updated successfully');
|
$rootScope.myform = $scope.myform = response.data;
|
||||||
// console.log(response.status);
|
console.log(response.data);
|
||||||
|
if(!$scope.$digest){
|
||||||
|
$scope.$apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}).catch(function(response){
|
}).catch(function(response){
|
||||||
console.log('Error occured during form UPDATE.\n');
|
console.log('Error occured during form UPDATE.\n');
|
||||||
console.log(response.data);
|
console.log(response.data);
|
||||||
err = response.data;
|
err = response.data;
|
||||||
}).finally(function() {
|
}).finally(function() {
|
||||||
// console.log('finished updating');
|
// console.log('finished updating');
|
||||||
$scope.saveInProgress = false;
|
$rootScope.saveInProgress = false;
|
||||||
cb(err);
|
cb(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,31 @@ form .row.field {
|
||||||
font-size:1.2em;
|
font-size:1.2em;
|
||||||
color:#ddd;
|
color:#ddd;
|
||||||
}
|
}
|
||||||
form.submission-form .row.field > .field-input input {
|
|
||||||
width:100%;
|
form.submission-form .select.radio > .field-input input {
|
||||||
}
|
width:20%;
|
||||||
form.submission-form .row.field .field-input > input:focus {
|
}
|
||||||
font-size:1em;
|
|
||||||
}
|
|
||||||
|
form.submission-form .select > .field-input input {
|
||||||
|
width:20%;
|
||||||
|
}
|
||||||
|
form.submission-form .select > .field-input .btn {
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom:0.7em;
|
||||||
|
}
|
||||||
|
form.submission-form .select > .field-input .btn > span {
|
||||||
|
font-size: 1.10em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
form.submission-form .row.field > .field-input input {
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
form.submission-form .row.field .field-input > input:focus {
|
||||||
|
font-size:1em;
|
||||||
|
}
|
||||||
|
|
||||||
form .row.field.textfield > .field-input > input{
|
form .row.field.textfield > .field-input > input{
|
||||||
padding:0.45em 0.9em;
|
padding:0.45em 0.9em;
|
||||||
width:100%;
|
width:100%;
|
||||||
|
@ -151,8 +170,9 @@ div.config-form > .row {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Styles for form list view (/forms) */
|
/* Styles for form list view (/forms) */
|
||||||
section > section.ng-scope {
|
section > section.public-form {
|
||||||
padding: 0 60px 20px 60px;
|
padding: 0 6em 7em 6em;
|
||||||
|
|
||||||
}
|
}
|
||||||
.form-item.row {
|
.form-item.row {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -40,7 +40,7 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$watch('myform.form_fields', function(newValue, oldValue) {
|
$scope.$watch('myform.form_fields', function(newValue, oldValue) {
|
||||||
// console.log('watchCount: '+$rootScope.watchCount);
|
console.log('watchCount: '+$rootScope.watchCount);
|
||||||
if(difference(oldValue,newValue).length === 0 || oldValue === undefined){
|
if(difference(oldValue,newValue).length === 0 || oldValue === undefined){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,9 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
|
||||||
// console.log('form_fields changed: '+difference(oldValue,newValue).length );
|
// console.log('form_fields changed: '+difference(oldValue,newValue).length );
|
||||||
// console.log('$valid: '+$formCtrl.$valid);
|
// console.log('$valid: '+$formCtrl.$valid);
|
||||||
// console.log('finishedRender: '+$scope.finishedRender);
|
// console.log('finishedRender: '+$scope.finishedRender);
|
||||||
// console.log('saveInProgress: '+$scope.saveInProgress);
|
console.log('saveInProgress: '+$rootScope.saveInProgress);
|
||||||
|
|
||||||
if($scope.finishedRender && ($formCtrl.$dirty || difference(oldValue,newValue).length !== 0) ) {
|
if($scope.finishedRender && ($formCtrl.$dirty || difference(oldValue,newValue).length !== 0) && !$rootScope.saveInProgress) {
|
||||||
$rootScope.watchCount++;
|
$rootScope.watchCount++;
|
||||||
|
|
||||||
if($rootScope.watchCount === 1) {
|
if($rootScope.watchCount === 1) {
|
||||||
|
@ -80,6 +80,8 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}, true);
|
}, true);
|
||||||
|
|
|
@ -10,16 +10,16 @@ angular.module('forms').directive('changeFocus', function() {
|
||||||
// console.log('aoeuaoeuaoeuaou');
|
// console.log('aoeuaoeuaoeuaou');
|
||||||
scope.focusUp = function(){
|
scope.focusUp = function(){
|
||||||
if(!scope.$first) {
|
if(!scope.$first) {
|
||||||
// console.log('aoeuaoeu');
|
console.log('focusUp');
|
||||||
elem[0].previousElementSibling.find('input').focus();
|
elem[0].previousElementSibling.find('input').focus();
|
||||||
}
|
}
|
||||||
scope.apply();
|
scope.apply();
|
||||||
};
|
};
|
||||||
scope.focusDown = function(){
|
scope.focusDown = function(){
|
||||||
if(!scope.$last) {
|
if(!scope.$last) {
|
||||||
elem[0].nextElementSibling.focus();
|
elem[0].nextElementSibling.focus();
|
||||||
}
|
}
|
||||||
scope.apply();
|
scope.apply();
|
||||||
};
|
};
|
||||||
|
|
||||||
//Bind 'focus-down' click event to given dom element
|
//Bind 'focus-down' click event to given dom element
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('forms').directive('configureFormDirective', ['$rootScope','$http', '$timeout', 'timeCounter', 'Auth', 'FormFields',
|
angular.module('forms').directive('configureFormDirective', ['$rootScope', '$http', 'Upload', '$timeout', 'timeCounter', 'Auth', 'FormFields',
|
||||||
function ($rootScope, $http, $timeout, timeCounter, Auth, FormFields) {
|
function ($rootScope, $http, Upload, $timeout, timeCounter, Auth, FormFields) {
|
||||||
return {
|
return {
|
||||||
controller: function($scope){
|
controller: function($scope){
|
||||||
$scope.log = '';
|
$scope.log = '';
|
||||||
|
@ -39,6 +39,8 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope','$http
|
||||||
if (files && files.length) {
|
if (files && files.length) {
|
||||||
// for (var i = 0; i < files.length; i++) {
|
// for (var i = 0; i < files.length; i++) {
|
||||||
var file = files[0];
|
var file = files[0];
|
||||||
|
console.log(file);
|
||||||
|
|
||||||
_current_upload = Upload.upload({
|
_current_upload = Upload.upload({
|
||||||
url: '/upload/pdf',
|
url: '/upload/pdf',
|
||||||
fields: {
|
fields: {
|
||||||
|
@ -53,13 +55,14 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope','$http
|
||||||
$scope.pdfLoading = true;
|
$scope.pdfLoading = true;
|
||||||
}).success(function (data, status, headers, config) {
|
}).success(function (data, status, headers, config) {
|
||||||
$scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
|
$scope.log = 'file ' + data.originalname + ' uploaded as '+ data.name +'. JSON: ' + JSON.stringify(data) + '\n' + $scope.log;
|
||||||
console.log($scope.myform.pdf);
|
|
||||||
$scope.myform.pdf = angular.fromJson(angular.toJson(data));
|
$scope.myform.pdf = angular.fromJson(angular.toJson(data));
|
||||||
|
|
||||||
|
console.log($scope.myform.pdf);
|
||||||
|
|
||||||
$scope.pdfLoading = false;
|
$scope.pdfLoading = false;
|
||||||
|
|
||||||
console.log($scope.log);
|
console.log($scope.log);
|
||||||
console.log('$scope.pdf: '+$scope.myform.pdf.name);
|
if(!$scope.$$phase && !$scope.$digest){
|
||||||
if(!$scope.$$phase){
|
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
}
|
}
|
||||||
}).error(function(err){
|
}).error(function(err){
|
||||||
|
@ -67,7 +70,6 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope','$http
|
||||||
console.log('Error occured during upload.\n');
|
console.log('Error occured during upload.\n');
|
||||||
console.log(err);
|
console.log(err);
|
||||||
});
|
});
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
|
||||||
handle: ' .handle'
|
handle: ' .handle'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log($scope.myform);
|
||||||
|
|
||||||
// $scope.draggable = {
|
// $scope.draggable = {
|
||||||
// connectWith: ".dropzone",
|
// connectWith: ".dropzone",
|
||||||
// start: function (e, ui) {
|
// start: function (e, ui) {
|
||||||
|
@ -87,7 +89,7 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
|
||||||
|
|
||||||
for(var i = 0; i < $scope.addField.types.length; i++){
|
for(var i = 0; i < $scope.addField.types.length; i++){
|
||||||
// console.log($scope.addField.types[i].name === fieldType);
|
// console.log($scope.addField.types[i].name === fieldType);
|
||||||
if($scope.addField.types[i].name === fieldType){
|
if($scope.addField.types[i].name === fieldType){
|
||||||
$scope.addField.types[i].lastAddedID++;
|
$scope.addField.types[i].lastAddedID++;
|
||||||
// console.log($scope.addField.types[i].lastAddedID);
|
// console.log($scope.addField.types[i].lastAddedID);
|
||||||
fieldTitle = $scope.addField.types[i].value+$scope.addField.types[i].lastAddedID;
|
fieldTitle = $scope.addField.types[i].value+$scope.addField.types[i].lastAddedID;
|
||||||
|
@ -99,13 +101,13 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', '$q', '$ht
|
||||||
'fieldType' : fieldType,
|
'fieldType' : fieldType,
|
||||||
'fieldValue' : '',
|
'fieldValue' : '',
|
||||||
'required' : true,
|
'required' : true,
|
||||||
'disabled' : false
|
'disabled' : false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// put newField into fields array
|
// put newField into fields array
|
||||||
$scope.myform.form_fields.unshift(newField);
|
$scope.myform.form_fields.unshift(newField);
|
||||||
console.log('\n\n---------\nAdded field CLIENT');
|
// console.log('\n\n---------\nAdded field CLIENT');
|
||||||
console.log(Date.now());
|
// console.log(Date.now());
|
||||||
// console.log($scope.myform.form_fields.length);
|
// console.log($scope.myform.form_fields.length);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@ angular.module('forms').directive('fieldDirective', function($http, $compile) {
|
||||||
'dropdown',
|
'dropdown',
|
||||||
'hidden',
|
'hidden',
|
||||||
'password',
|
'password',
|
||||||
'radio'
|
'radio',
|
||||||
|
'legal'
|
||||||
];
|
];
|
||||||
if (__indexOf.call(supported_fields, type) >= 0) {
|
if (__indexOf.call(supported_fields, type) >= 0) {
|
||||||
return templateUrl += type + '.html';
|
return templateUrl += type + '.html';
|
||||||
|
@ -32,7 +33,7 @@ angular.module('forms').directive('fieldDirective', function($http, $compile) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var linker = function(scope, element) {
|
var linker = function(scope, element) {
|
||||||
scope.field.required = scope.required;
|
// scope.field.required = scope.required;
|
||||||
|
|
||||||
//Set format only if field is a date
|
//Set format only if field is a date
|
||||||
if(scope.field.fieldType === 'date'){
|
if(scope.field.fieldType === 'date'){
|
||||||
|
|
|
@ -25,16 +25,16 @@ angular.module('forms').directive('formDirective', ['$http', '$timeout', 'timeCo
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.cancel = function(){
|
|
||||||
alert('Form canceled..');
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.reloadForm = function(){
|
$scope.reloadForm = function(){
|
||||||
$scope.form.submitted = false;
|
$scope.form.submitted = false;
|
||||||
|
$scope.form.form_fields = _.chain($scope.form.form_fields).map(function(field){
|
||||||
|
field.fieldValue = '';
|
||||||
|
return field;
|
||||||
|
}).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
templateUrl: './modules/forms/views/directiveViews/form/form.html',
|
templateUrl: './modules/forms/views/directiveViews/form/submit-form.html',
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: {
|
scope: {
|
||||||
form:'='
|
form:'='
|
|
@ -9,6 +9,27 @@ angular.module('forms').factory('Forms', ['$resource',
|
||||||
'query' : {
|
'query' : {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
isArray: true,
|
isArray: true,
|
||||||
|
transformResponse: function(data, header) {
|
||||||
|
var forms = angular.fromJson(data);
|
||||||
|
angular.forEach(forms, function(form, idx) {
|
||||||
|
form.visible_form_fields = _.filter(form.form_fields, function(field){
|
||||||
|
return field.deletePreserved === false;
|
||||||
|
}); //<-- replace each item with an instance of the resource object
|
||||||
|
});
|
||||||
|
return forms;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'get' : {
|
||||||
|
method: 'GET',
|
||||||
|
transformResponse: function(data, header) {
|
||||||
|
var form = angular.fromJson(data);
|
||||||
|
|
||||||
|
form.visible_form_fields = _.filter(form.form_fields, function(field){
|
||||||
|
return field.deletePreserved === false;
|
||||||
|
}); //<-- replace each item with an instance of the resource object
|
||||||
|
console.log(form);
|
||||||
|
return form;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
'update': {
|
'update': {
|
||||||
method: 'PUT'
|
method: 'PUT'
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="field row">
|
<div class="field row">
|
||||||
<div class="col-xs-5 field-title field-title">{{field.title}} </div>
|
<div class="col-xs-5 field-title field-title">{{field.title}} </div>
|
||||||
<div class="col-xs-7 field-input field-input">
|
<div class="col-xs-7 field-input field-input">
|
||||||
<input ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" id="{{field.client_id}}" type="checkbox" ng-init="field.fieldValue = false" ng-required="field.required" ng-disabled="field.disabled"/>
|
<input ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" type="checkbox" ng-init="field.fieldValue = false" ng-required="field.required" ng-disabled="field.disabled"/>
|
||||||
<span class="required-error" ng-show="field.required && field.fieldValue == 0">(* required)</span>
|
<span class="required-error" ng-show="field.required && field.fieldValue == 0">(* required)</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="field row">
|
<div class="field row">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="field row dropdown">
|
<div class="field row dropdown" ng-if="field.fieldOptions.length > 0">
|
||||||
<div class="col-xs-5 field-title">{{field.title}} </div>
|
<div class="col-xs-5 field-title">{{field.title}} </div>
|
||||||
<div class="col-xs-7 field-input ">
|
<div class="col-xs-7 field-input ">
|
||||||
<select ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" ng-required="field.required" ng-disabled="field.disabled">
|
<select ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" ng-required="field.required" ng-disabled="field.disabled">
|
||||||
|
|
21
public/modules/forms/views/directiveViews/field/legal.html
Normal file
21
public/modules/forms/views/directiveViews/field/legal.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<div class="field row radio legal">
|
||||||
|
<div class="col-xs-12 field-title">
|
||||||
|
{{field.title}}
|
||||||
|
<br>
|
||||||
|
<p>{{field.description}}</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-3 field-input container">
|
||||||
|
<div class="row-fluid">
|
||||||
|
<label class="btn col-xs-12">
|
||||||
|
<input type="radio" value="true" ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" ng-required="field.required" ng-disabled="field.disabled"/>
|
||||||
|
<span> I accept </span>
|
||||||
|
</label>
|
||||||
|
<label class="btn col-xs-12">
|
||||||
|
<input type="radio" value="false" ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" ng-required="field.required" ng-disabled="field.disabled"/>
|
||||||
|
<span>I don't accept </span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<span class="required-error" ng-show="field.required && !field.fieldValue">* required</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
|
@ -1,10 +1,10 @@
|
||||||
<div class="field row">
|
<div class="field row radio" ng-if="field.fieldOptions.length > 0">
|
||||||
<div class="col-xs-5 field-title">{{field.title}} </div>
|
<div class="col-xs-5 field-title">{{field.title}} </div>
|
||||||
<div class="col-xs-7 field-input">
|
<div class="col-xs-7 field-input">
|
||||||
<div ng-repeat="option in field.fieldOptions" class="row-fluid">
|
<div ng-repeat="option in field.fieldOptions" class="row-fluid">
|
||||||
<label>
|
<label class="btn col-xs-12">
|
||||||
<input type="radio" value="{{option.option_value}}" ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" ng-required="field.required" ng-disabled="field.disabled"/>
|
<input type="radio" value="{{option.option_value}}" ng-model="field.fieldValue" ng-model-options="{ debounce: 250 }" ng-required="field.required" ng-disabled="field.disabled" ng-init="field.fieldValue = field.fieldOptions[0].option_value"/>
|
||||||
<span ng-bind="option.option_title"></span>
|
<span ng-bind="option.option_title"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<span class="required-error" ng-show="field.required && !field.fieldValue">* required</span>
|
<span class="required-error" ng-show="field.required && !field.fieldValue">* required</span>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-10 col-xs-offset-2 field-title field-input">
|
<div class="col-xs-10 col-xs-offset-2 field-title field-input">
|
||||||
<i class="fa fa-quote-left fa-3"></i>
|
<i class="fa fa-quote-left fa-3"></i>
|
||||||
<p>{{field.fieldValue}} </p>
|
<p>{{field.description}} </p>
|
||||||
<i class="fa fa-quote-right fa-3"></i>
|
<i class="fa fa-quote-right fa-3"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -30,9 +30,10 @@
|
||||||
<div class="col-xs-10">
|
<div class="col-xs-10">
|
||||||
<accordion close-others="accordion.oneAtATime" ui-sortable="dropzone" ng-model="myform.form_fields" class="dropzone">
|
<accordion close-others="accordion.oneAtATime" ui-sortable="dropzone" ng-model="myform.form_fields" class="dropzone">
|
||||||
|
|
||||||
<accordion-group ng-repeat="field in myform.form_fields" is-open="accordion[$index].isOpen" on-finish-render="setFormValid()">
|
<accordion-group ng-repeat="field in myform.form_fields" is-open="accordion[$index].isOpen" on-finish-render="setFormValid()" ng-show="!field.deletePreserved">
|
||||||
|
|
||||||
<accordion-heading>
|
<accordion-heading>
|
||||||
|
|
||||||
<div class="handle">
|
<div class="handle">
|
||||||
<span class="pull-left" ng-switch="field.fieldType">
|
<span class="pull-left" ng-switch="field.fieldType">
|
||||||
<field-icon-directive type-name="{{field.fieldType}}"></field-icon-directive>
|
<field-icon-directive type-name="{{field.fieldType}}"></field-icon-directive>
|
||||||
|
@ -46,7 +47,6 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</accordion-heading>
|
</accordion-heading>
|
||||||
|
|
||||||
<div class="accordion-edit container">
|
<div class="accordion-edit container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<ul class="col-xs-4 container" style="list-style:none;border:2px lightgray solid;">
|
<ul class="col-xs-4 container" style="list-style:none;border:2px lightgray solid;">
|
||||||
<field-directive field="field" required="">
|
<field-directive field="field">
|
||||||
</field-directive>
|
</field-directive>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -70,6 +70,10 @@
|
||||||
<div class="col-xs-2">Field Title:</div>
|
<div class="col-xs-2">Field Title:</div>
|
||||||
<div class="col-xs-4"><input type="text" ng-model="field.title" value="{{field.title}}" required></div>
|
<div class="col-xs-4"><input type="text" ng-model="field.title" value="{{field.title}}" required></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-2">Field Decription:</div>
|
||||||
|
<div class="col-xs-4"><textarea type="text" ng-model="field.title" value="{{field.description}}"></textarea> </div>
|
||||||
|
</div>
|
||||||
<br><br>
|
<br><br>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="row" ng-show="showAddOptions(field)">
|
<div class="row" ng-show="showAddOptions(field)">
|
||||||
|
@ -116,8 +120,7 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</accordion-group>
|
</accordion-group>
|
||||||
|
|
||||||
|
@ -133,7 +136,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-1" style="padding:0 5px;" >
|
<div class="col-xs-1" style="padding:0 5px;" >
|
||||||
<div class="panel-group tool-panel text-center">
|
<div class="panel-group tool-panel text-center">
|
||||||
<div class="panel panel-default" ng-repeat="field in myform.form_fields">
|
<div class="panel panel-default" ng-repeat="field in myform.form_fields" ng-if="!field.deletePreserved">
|
||||||
<div class="panel-heading" style="padding: 10px 10px; height: 37px;" ng-click="deleteField(field.$$hashKey)">
|
<div class="panel-heading" style="padding: 10px 10px; height: 37px;" ng-click="deleteField(field.$$hashKey)">
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
<a href="" class="fa fa-trash-o"></a>
|
<a href="" class="fa fa-trash-o"></a>
|
||||||
|
@ -144,7 +147,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-1" style="padding:0 5px;">
|
<div class="col-xs-1" style="padding:0 5px;">
|
||||||
<div class="panel-group tool-panel text-center">
|
<div class="panel-group tool-panel text-center">
|
||||||
<div class="panel panel-default" ng-repeat="field in myform.form_fields">
|
<div class="panel panel-default" ng-repeat="field in myform.form_fields" ng-if="!field.deletePreserved">
|
||||||
<div class="panel-heading" style="padding: 10px 10px; height: 37px;" ng-click="duplicateField(field, $index)">
|
<div class="panel-heading" style="padding: 10px 10px; height: 37px;" ng-click="duplicateField(field, $index)">
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
<a href="" class="fa fa-files-o"></a>
|
<a href="" class="fa fa-files-o"></a>
|
||||||
|
|
|
@ -1,26 +1,22 @@
|
||||||
<div ng-hide="form.submitted">
|
<div ng-hide="form.submitted">
|
||||||
|
|
||||||
<div class="field row">
|
<div class="field row" style="padding-bottom:5em;">
|
||||||
<div class="col-sm-10 col-sm-offset-1"><h1>{{ form.title }}</h1>
|
<div class="col-sm-10 col-sm-offset-1">
|
||||||
<hr>
|
<h1>{{ form.title }}</h1>
|
||||||
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<form name="form" class="submission-form col-sm-offset-1 col-sm-10" name="form" ng-model="form" ng-repeat="field in form.form_fields" >
|
<form name="form" class="submission-form col-sm-offset-1 col-sm-10" name="form" ng-model="form" ng-repeat="field in form.form_fields" >
|
||||||
<field-directive field="field">
|
<field-directive field="field" ng-if="!field.deletePreserved">
|
||||||
</field-directive>
|
</field-directive>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
<div class="row form-actions">
|
<div class="row form-actions">
|
||||||
<button class="btn btn-success col-sm-2 col-sm-offset-5" type="button" ng-disabled="myForm.$valid" ng-click="submit()" style="font-size: 1.6em;">
|
<button class="btn btn-success col-sm-2 col-sm-offset-5" type="button" ng-disabled="myForm.$valid" ng-click="submit()" style="font-size: 1.6em;">
|
||||||
<i class="icon-edit icon-white"></i> submit
|
<i class="icon-edit icon-white"></i> submit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -50,10 +46,4 @@
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- <div ng-repeat="field in form.form_fields">
|
|
||||||
Field Title: {{ field.title }} <br>
|
|
||||||
Field Value: {{ field.fieldValue }} <br><br>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
|
@ -33,9 +33,8 @@
|
||||||
Language
|
Language
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-5 field-input">
|
<div class="col-xs-5 field-input">
|
||||||
<select style="color:black;" name="language" required ng-model="formLanguage">
|
<select style="color:black;" name="language" required ng-model="formLanguage" ng-init="formLanguage = user.language">
|
||||||
<option ng-repeat="language in languages"
|
<option ng-repeat="language in languages" value="{{language}}">
|
||||||
value="{{language}}" ng-selected="language == formLanguage">
|
|
||||||
{{language}}
|
{{language}}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -46,6 +46,13 @@
|
||||||
View Submissions
|
View Submissions
|
||||||
</tab-heading>
|
</tab-heading>
|
||||||
<div class="submissions-table" ng-show="viewSubmissions">
|
<div class="submissions-table" ng-show="viewSubmissions">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-1">
|
||||||
|
<button class="btn btn-danger" ng-click="deleteSelectedSubmissions()" ng-disabled="!isAtLeastOneChecked();"><i class="fa fa-trash-o"></i> Delete Selected</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
<table class="table table-striped table-hover table-condensed">
|
<table class="table table-striped table-hover table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -83,7 +90,7 @@
|
||||||
{{row.created | date:'yyyy-MM-dd HH:mm:ss'}}
|
{{row.created | date:'yyyy-MM-dd HH:mm:ss'}}
|
||||||
</td>
|
</td>
|
||||||
<td ng-if="row.pdf">
|
<td ng-if="row.pdf">
|
||||||
<a href="{{row.pdf.path}}">Generated PDF</a>
|
<a href="{{row.pdfFilePath}}" download="{{row.pdf.name}}" target="_self">Generated PDF</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -93,51 +100,4 @@
|
||||||
</tabset>
|
</tabset>
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="row">
|
|
||||||
<div class="col-xs-8">
|
|
||||||
<div>
|
|
||||||
<edit-form-directive form="form" user="user"></edit-form-directive>
|
|
||||||
<p ng-show="form.form_fields.length == 0">No fields added yet.</p>
|
|
||||||
</p>
|
|
||||||
<accordion class="col-xs-10" close-others="accordion.oneAtATime">
|
|
||||||
<accordion-group heading="{{field.title}} (is a {{field.fieldType}})" ng-repeat="field in form.form_fields">
|
|
||||||
</accordion-group>
|
|
||||||
</accordion>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-xs-3 col-xs-offset-1 container text-right form-controls" data-ng-show="authentication.user._id == form.user._id">
|
|
||||||
<div class="row">
|
|
||||||
<a class="col-xs-12 btn btn-default" href="/#!/forms/{{form._id}}/edit">
|
|
||||||
<i class="glyphicon glyphicon-edit"></i> Edit Form
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<a class="col-xs-12 btn btn-danger" data-ng-click="remove();">
|
|
||||||
<i class="glyphicon glyphicon-trash"></i> Delete Form
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<a class="col-xs-12 btn btn-default" data-ng-click="showSubmissions();" ng-hide="viewSubmissions">
|
|
||||||
View Form Submissions
|
|
||||||
</a>
|
|
||||||
<a class="col-xs-12 btn btn-primary" data-ng-click="hideSubmissions();" ng-show="viewSubmissions">
|
|
||||||
Back to Main View
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
<!-- <div class="row">
|
|
||||||
<small class="col-xs-12">
|
|
||||||
<em class="text-muted">
|
|
||||||
Created on
|
|
||||||
<span data-ng-bind="form.created | date:'mediumDate'"></span>
|
|
||||||
by
|
|
||||||
<span data-ng-bind="form.admin.displayName"></span>
|
|
||||||
</em>
|
|
||||||
</small>
|
|
||||||
</div> -->
|
|
||||||
<!-- <p class="lead" data-ng-bind="form.content"></p> -->
|
|
||||||
</section>
|
</section>
|
|
@ -1,22 +1,23 @@
|
||||||
<link rel="stylesheet" href="./modules/forms/css/form.css">
|
<link rel="stylesheet" href="./modules/forms/css/form.css">
|
||||||
|
|
||||||
<section data-ng-controller="SubmitFormController">
|
<section data-ng-controller="SubmitFormController" class="public-form">
|
||||||
|
|
||||||
<form-directive form="form"></form-directive>
|
<form-directive form="form"></form-directive>
|
||||||
|
|
||||||
<section ng-if="!form.hideFooter" class="navbar navbar-fixed-bottom" style="background-color:rgba(242,242,242,0.5); padding-top:15px;">
|
<section ng-if="!form.hideFooter" class="navbar navbar-fixed-bottom" style="background-color:rgba(242,242,242,0.5); padding-top:15px;">
|
||||||
<div class="container" >
|
<div class="container" >
|
||||||
<nav role="navigation">
|
<nav role="navigation">
|
||||||
<ul class="nav navbar-nav navbar-left" >
|
<ul class="nav navbar-nav navbar-left" >
|
||||||
<li class="">
|
<li ng-show="!form.submitted">
|
||||||
<!-- <p class="lead">{{form | formValidity}} out of {{form.form_fields.length}} answered</p> -->
|
<p class="lead">{{form | formValidity}} out of {{form.visible_form_fields.length}} answered</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li style="padding-right:20px" >
|
<li style="padding-right:20px" >
|
||||||
<a href="/forms/create" class="btn btn-default" ng-hide="authentication.user">create a Medform</a>
|
<a href="/#!/forms" class="btn btn-default" ng-hide="authentication.isAuthenticated()">create a Medform</a>
|
||||||
</li>
|
</li>
|
||||||
<li style="padding-right:20px" ng-show="authentication.user">
|
<li style="padding-right:20px" ng-show="authentication.isAuthenticated()">
|
||||||
<a href="/forms/{{form._id}}/edit" class="btn btn-default">edit this Medform</a>
|
<a href="/#!/forms/{{form._id}}/admin" class="btn btn-default">edit this Medform</a>
|
||||||
</li>
|
</li>
|
||||||
<li style="padding-left:5px">
|
<li style="padding-left:5px">
|
||||||
<div class="btn btn-info" id="focusDownButton">\/</div>
|
<div class="btn btn-info" id="focusDownButton">\/</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@ angular.module('users').config(['$httpProvider',
|
||||||
$httpProvider.interceptors.push(function($q, $location) {
|
$httpProvider.interceptors.push(function($q, $location) {
|
||||||
return {
|
return {
|
||||||
responseError: function(response) {
|
responseError: function(response) {
|
||||||
if( $location.path() !== '/users/me' && $location.path() !== '/'){
|
if( $location.path() !== '/users/me' && $location.path() !== '/' && $location.path() !== '/signup' && response.config){
|
||||||
|
|
||||||
console.log('intercepted rejection of ', response.config.url, response.status);
|
console.log('intercepted rejection of ', response.config.url, response.status);
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
|
|
|
@ -30,10 +30,6 @@ angular.module('users').config(['$stateProvider',
|
||||||
// Users state routing
|
// Users state routing
|
||||||
$stateProvider.
|
$stateProvider.
|
||||||
state('profile', {
|
state('profile', {
|
||||||
// parent: 'restricted',
|
|
||||||
// data: {
|
|
||||||
// roles: ['user', 'admin'],
|
|
||||||
// },
|
|
||||||
resolve: {
|
resolve: {
|
||||||
loggedin: checkLoggedin
|
loggedin: checkLoggedin
|
||||||
},
|
},
|
||||||
|
@ -41,13 +37,6 @@ angular.module('users').config(['$stateProvider',
|
||||||
templateUrl: 'modules/users/views/settings/edit-profile.client.view.html'
|
templateUrl: 'modules/users/views/settings/edit-profile.client.view.html'
|
||||||
}).
|
}).
|
||||||
state('password', {
|
state('password', {
|
||||||
// resolve: {
|
|
||||||
// checkLoggedin: Authorization.authorize
|
|
||||||
// },
|
|
||||||
// parent: 'restricted',
|
|
||||||
// data: {
|
|
||||||
// roles: ['user', 'admin'],
|
|
||||||
// },
|
|
||||||
resolve: {
|
resolve: {
|
||||||
loggedin: checkLoggedin
|
loggedin: checkLoggedin
|
||||||
},
|
},
|
||||||
|
@ -55,10 +44,6 @@ angular.module('users').config(['$stateProvider',
|
||||||
templateUrl: 'modules/users/views/settings/change-password.client.view.html'
|
templateUrl: 'modules/users/views/settings/change-password.client.view.html'
|
||||||
}).
|
}).
|
||||||
state('accounts', {
|
state('accounts', {
|
||||||
// parent: 'restricted',
|
|
||||||
// data: {
|
|
||||||
// roles: ['user', 'admin'],
|
|
||||||
// },
|
|
||||||
resolve: {
|
resolve: {
|
||||||
loggedin: checkLoggedin
|
loggedin: checkLoggedin
|
||||||
},
|
},
|
||||||
|
@ -83,6 +68,15 @@ angular.module('users').config(['$stateProvider',
|
||||||
templateUrl: 'modules/users/views/authentication/access-denied.client.view.html'
|
templateUrl: 'modules/users/views/authentication/access-denied.client.view.html'
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
state('resendVerifyEmail', {
|
||||||
|
url: '/verify',
|
||||||
|
templateUrl: 'modules/users/views/verify/resend-verify-email.client.view.html'
|
||||||
|
}).
|
||||||
|
state('verify', {
|
||||||
|
url: '/verify/:token',
|
||||||
|
templateUrl: 'modules/users/views/verify/verify-account.client.view.html'
|
||||||
|
}).
|
||||||
|
|
||||||
state('forgot', {
|
state('forgot', {
|
||||||
url: '/password/forgot',
|
url: '/password/forgot',
|
||||||
templateUrl: 'modules/users/views/password/forgot-password.client.view.html'
|
templateUrl: 'modules/users/views/password/forgot-password.client.view.html'
|
||||||
|
|
|
@ -3,104 +3,66 @@
|
||||||
angular.module('users').controller('AuthenticationController', ['$scope', '$location', '$state', '$rootScope', 'User', 'Auth',
|
angular.module('users').controller('AuthenticationController', ['$scope', '$location', '$state', '$rootScope', 'User', 'Auth',
|
||||||
function($scope, $location, $state, $rootScope, User, Auth) {
|
function($scope, $location, $state, $rootScope, User, Auth) {
|
||||||
|
|
||||||
$scope = $rootScope;
|
$scope = $rootScope;
|
||||||
$scope.credentials = {};
|
$scope.credentials = {};
|
||||||
$scope.error = null;
|
$scope.error = null;
|
||||||
|
|
||||||
// If user is signed in then redirect back home
|
// If user is signed in then redirect back home
|
||||||
if ($scope.authentication.isAuthenticated()) $state.go('home');
|
if ($scope.authentication.isAuthenticated()) $state.go('home');
|
||||||
|
|
||||||
$scope.signin = function() {
|
$scope.signin = function() {
|
||||||
Auth.currentUser = User.login($scope.credentials).then(
|
Auth.currentUser = User.login($scope.credentials).then(
|
||||||
function(response) {
|
function(response) {
|
||||||
Auth.login(response);
|
Auth.login(response);
|
||||||
$scope.user = $rootScope.user = Auth.ensureHasCurrentUser(User);
|
$scope.user = $rootScope.user = Auth.ensureHasCurrentUser(User);
|
||||||
|
|
||||||
if($state.previous.name !== 'home' && $state.previous.name !== ''){
|
if($state.previous.name !== 'home' && $state.previous.name !== ''){
|
||||||
$state.go($state.previous.name);
|
$state.go($state.previous.name);
|
||||||
}else{
|
}else{
|
||||||
$state.go('home');
|
$state.go('home');
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
$rootScope.user = Auth.ensureHasCurrentUser(User);
|
||||||
|
$scope.user = $rootScope.user;
|
||||||
|
|
||||||
|
$scope.error = error;
|
||||||
|
console.log('loginError: '+error);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
},
|
};
|
||||||
function(error) {
|
|
||||||
$rootScope.user = Auth.ensureHasCurrentUser(User);
|
|
||||||
$scope.user = $rootScope.user;
|
|
||||||
|
|
||||||
$scope.error = error;
|
$scope.signup = function() {
|
||||||
console.log('loginError: '+error);
|
User.signup($scope.credentials).then(
|
||||||
}
|
function(response) {
|
||||||
);
|
console.log('signup-success');
|
||||||
};
|
$state.go('signup-success');
|
||||||
|
},
|
||||||
$scope.signup = function() {
|
function(error) {
|
||||||
User.signup($scope.credentials).then(
|
if(error) {
|
||||||
function(response) {
|
$scope.error = error;
|
||||||
console.log('signup-success');
|
}else {
|
||||||
$state.go('signup-success');
|
console.log('No response received');
|
||||||
},
|
}
|
||||||
function(error) {
|
}
|
||||||
if(error) {
|
);
|
||||||
$scope.error = error;
|
};
|
||||||
}else {
|
|
||||||
console.log('No response received');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// $scope.signup = function() {
|
// Submit forgotten password account id
|
||||||
// Principal.signup($scope.credentials).then(
|
$scope.resendVerifyEmail = function() {
|
||||||
// function(result){
|
User.resendVerifyEmail($scope.email).then(
|
||||||
// $state.go('home');
|
function(response){
|
||||||
// },
|
$scope.success = response.message;
|
||||||
// function(rejection_reason){
|
$scope.credentials = null;
|
||||||
// $scope.error = rejection_reason;
|
},
|
||||||
// }
|
function(error){
|
||||||
// );
|
$scope.error = error;
|
||||||
// // $http.post('/auth/signup', $scope.credentials).success(function(response) {
|
$scope.credentials = null;
|
||||||
// // // If successful we assign the response to the global user model
|
}
|
||||||
// // $scope.authentication.user = response;
|
);
|
||||||
// // Principal.authenticate(response);
|
};
|
||||||
|
|
||||||
// // // And redirect to the index page
|
|
||||||
// // $location.path('/');
|
|
||||||
// // }).error(function(response) {
|
|
||||||
// // $scope.error = response.message;
|
|
||||||
// // });
|
|
||||||
// };
|
|
||||||
|
|
||||||
// $scope.signin = function() {
|
|
||||||
// console.log('signin');
|
|
||||||
|
|
||||||
// Principal.signin($scope.credentials).then(
|
|
||||||
// function(result){
|
|
||||||
// $state.go('home');
|
|
||||||
// },
|
|
||||||
// function(rejection_reason){
|
|
||||||
// $scope.error = rejection_reason;
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// // var response_obj = Principal.signin($scope.credentials);
|
|
||||||
// // if( angular.isDefined(response_obj.error) ){
|
|
||||||
// // $scope.error = response_obj.error;
|
|
||||||
// // $location.path('/signin');
|
|
||||||
// // } else{
|
|
||||||
// // $location.path('/');
|
|
||||||
// // }
|
|
||||||
// // $http.post('/auth/signin', $scope.credentials).success(function(response) {
|
|
||||||
// // // If successful we assign the response to the global user model
|
|
||||||
// // $scope.authentication.user = response;
|
|
||||||
// // Principal.authenticate(response);
|
|
||||||
|
|
||||||
// // // And redirect to the index page
|
|
||||||
// // $location.path('/');
|
|
||||||
// // }).error(function(response) {
|
|
||||||
// // Principal.authenticate(null);
|
|
||||||
// // $scope.error = response.message;
|
|
||||||
// // });
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
]);
|
]);
|
|
@ -1,47 +0,0 @@
|
||||||
// 'use strict';
|
|
||||||
|
|
||||||
// angular.module('users').factory('Authorization', ['$rootScope', '$http', '$q', '$state', 'Principal',
|
|
||||||
// function($rootScope, $http, $q, $state, Principal) {
|
|
||||||
// var service = {
|
|
||||||
// authorize: function(){
|
|
||||||
// var deferred = $q.defer();
|
|
||||||
// $http.get('/user/me').success(function(response) {
|
|
||||||
|
|
||||||
|
|
||||||
// //user is logged in
|
|
||||||
// if(response.data !== null){
|
|
||||||
// deferred.resolve();
|
|
||||||
// }else {
|
|
||||||
// $rootScope.message = 'You need to log in.';
|
|
||||||
// deferred.reject();
|
|
||||||
// $state.go('/login');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// });
|
|
||||||
// return deferred.promise();
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// return service;
|
|
||||||
// // this.authorize = function() {
|
|
||||||
// // return Principal.identity().then(function(){
|
|
||||||
// // var isAuthenticated = Principal.isAuthenticated();
|
|
||||||
// // if( angular.isDefined($rootScope.toState.data) ){
|
|
||||||
// // // if ($rootScope.toState.data.roles && $rootScope.toState.data.roles.length > 0 && !principal.isInAnyRole($rootScope.toState.data.roles)) {
|
|
||||||
// // if (!isAuthenticated){ //$location.path('/access_denied'); // user is signed in but not authorized for desired state
|
|
||||||
// // // console.log('isAuthenticated: '+isAuthenticated);
|
|
||||||
|
|
||||||
// // // else {
|
|
||||||
// // // user is not authenticated. so the state they wanted before you
|
|
||||||
// // // send them to the signin state, so you can return them when you're done
|
|
||||||
// // $rootScope.returnToState = $rootScope.toState;
|
|
||||||
// // $rootScope.returnToStateParams = $rootScope.toStateParams;
|
|
||||||
|
|
||||||
// // // now, send them to the signin state so they can log in
|
|
||||||
// // $location.path('/signin');
|
|
||||||
// // }
|
|
||||||
// // // }
|
|
||||||
// // }
|
|
||||||
// // });
|
|
||||||
// // };
|
|
||||||
// }
|
|
||||||
// ]);
|
|
|
@ -54,6 +54,18 @@ angular.module('users').factory('User', ['$window', '$q', '$timeout', '$http', '
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
resendVerifyEmail: function(email) {
|
||||||
|
var deferred = $q.defer();
|
||||||
|
$http.post('/auth/verify/'+token, email).success(function(response) {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
}).error(function(error) {
|
||||||
|
deferred.reject(error.message || error);
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
},
|
||||||
|
|
||||||
resetPassword: function(passwordDetails, token) {
|
resetPassword: function(passwordDetails, token) {
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
$http.get('/auth/password/'+token, passwordDetails).success(function(response) {
|
$http.get('/auth/password/'+token, passwordDetails).success(function(response) {
|
||||||
|
|
|
@ -38,11 +38,6 @@
|
||||||
<label for="email">Email</label>
|
<label for="email">Email</label>
|
||||||
<input type="email" id="email" name="email" class="form-control" data-ng-model="credentials.email" placeholder="Email">
|
<input type="email" id="email" name="email" class="form-control" data-ng-model="credentials.email" placeholder="Email">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label for="username">Username</label>
|
|
||||||
<input type="text" id="username" name="username" class="form-control" data-ng-model="credentials.username" placeholder="Username">
|
|
||||||
</div>
|
|
||||||
<hr>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<input type="password" id="password" name="password" class="form-control" data-ng-model="credentials.password" placeholder="Password">
|
<input type="password" id="password" name="password" class="form-control" data-ng-model="credentials.password" placeholder="Password">
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<section class="auth row" data-ng-controller="VerifyController">
|
||||||
|
<h3 class="col-md-12 text-center">Resend your account verification email</h3>
|
||||||
|
<p class="small text-center">Enter your account email.</p>
|
||||||
|
<div class="col-xs-offset-2 col-xs-8 col-md-offset-3 col-md-6">
|
||||||
|
<form data-ng-submit="resendVerifyEmail()" class="signin form-horizontal" autocomplete="off">
|
||||||
|
<fieldset>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="username" name="email" class="form-control" data-ng-model="email" placeholder="bob@example.com">
|
||||||
|
</div>
|
||||||
|
<div class="text-center form-group">
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</div>
|
||||||
|
<div data-ng-show="error" class="text-center text-danger">
|
||||||
|
<strong>{{error}}</strong>
|
||||||
|
</div>
|
||||||
|
<div data-ng-show="success" class="text-center text-success">
|
||||||
|
<strong>{{success}}</strong>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<section class="row text-center" data-ng-controller="VerifyController" ng-init="validateVerifyToken()">
|
||||||
|
|
||||||
|
<section class="row text-center" ng-if="success">
|
||||||
|
<h3 class="col-md-12">Password successfully reset</h3>
|
||||||
|
<a href="/#!/" class="col-md-12">Continue to home page</a>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="row text-center" ng-if="!success">
|
||||||
|
<h3 class="col-md-12">Verification link is invalid or has expired</h3>
|
||||||
|
<a href="/#!/verify" class="col-md-6">Resend your verification email</a>
|
||||||
|
<a href="/#!/signin" class="col-md-6">Signin to your account</a>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</section>
|
20
test.js
Normal file
20
test.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
var nodemailer = require('nodemailer'),
|
||||||
|
config = require('./config/config');
|
||||||
|
console.log('Start script');
|
||||||
|
|
||||||
|
var transporter = nodemailer.createTransport(config.mailer.options);
|
||||||
|
|
||||||
|
var verifyMailOptions = {
|
||||||
|
to: '1nsphq+9hg2ghgtblstc@sharklasers.com',
|
||||||
|
from: 'Do Not Reply <user@gmail.com>',
|
||||||
|
subject: 'Confirm your account',
|
||||||
|
html: '<p>Please verify your account by clicking <a href="${URL}">this link</a>. If you are unable to do so, copy and ' +
|
||||||
|
'paste the following link into your browser:</p><p>${URL}</p>',
|
||||||
|
text: 'Please verify your account by clicking the following link, or by copying and pasting it into your browser: ${URL}'
|
||||||
|
};
|
||||||
|
|
||||||
|
transporter.sendMail(verifyMailOptions , function(err, info){
|
||||||
|
if (err) console.log(err.message);
|
||||||
|
else console.log(info.response);
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in a new issue