added multiple choice default options

This commit is contained in:
David Baldwynn 2016-05-31 18:06:45 -07:00
parent 29667e5537
commit 6131f7de94
16 changed files with 522 additions and 124 deletions

View file

@ -210,7 +210,6 @@ exports.createSubmission = function(req, res) {
}
submission.save(function(err, submission){
// console.log('in submissions.save()\n submission: '+JSON.stringify(submission) )
if(err){
console.log(err.message);
res.status(400).send({

View file

@ -65,10 +65,8 @@ var FormSchema = new Schema({
type: String,
default: ''
},
form_fields: {
type: [FieldSchema]
},
form_fields: [FieldSchema],
submissions: [{
type: Schema.Types.ObjectId,
ref: 'FormSubmission'

View file

@ -4,6 +4,7 @@
* Module dependencies.
*/
var mongoose = require('mongoose'),
util = require('util'),
mUtilities = require('mongoose-utilities'),
_ = require('lodash'),
Schema = mongoose.Schema;
@ -23,85 +24,184 @@ var FieldOptionSchema = new Schema({
}
});
var RatingFieldSchema = new Schema({
steps: {
type: Number
},
shape: {
type: String,
enum: [
'Heart',
'Star',
'thumbs-up',
'thumbs-down',
'Circle',
'Square',
'Check Circle',
'Smile Outlined',
'Hourglass',
'bell',
'Paper Plane',
'Comment',
'Trash'
]
},
validShapes: {
type: [String]
}
});
/**
* FormField Schema
*/
var FormFieldSchema = new Schema({
title: {
type: String,
trim: true,
required: 'Field Title cannot be blank'
},
description: {
type: String,
default: ''
},
function BaseFieldSchema(){
Schema.apply(this, arguments);
logicJump: {
type: Schema.Types.ObjectId,
ref: 'LogicJump'
},
this.add({
title: {
type: String,
trim: true,
required: 'Field Title cannot be blank'
},
description: {
type: String,
default: ''
},
fieldOptions: [FieldOptionSchema],
required: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
},
logicJump: {
type: Schema.Types.ObjectId,
ref: 'LogicJump'
},
deletePreserved: {
type: Boolean,
default: false
},
validFieldTypes: {
type: [String]
},
fieldType: {
type: String,
required: true,
enum: [
'textfield',
'date',
'email',
'link',
'legal',
'url',
'textarea',
'statement',
'welcome',
'thankyou',
'file',
'dropdown',
'scale',
'rating',
'radio',
'checkbox',
'hidden',
'yes_no',
'natural',
'number'
]
},
fieldValue: Schema.Types.Mixed
});
ratingOptions: {
type: RatingFieldSchema,
required: false,
default: {}
},
fieldOptions: [FieldOptionSchema],
required: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
},
FormFieldSchema.plugin(mUtilities.timestamp, {
createdPath: 'created',
modifiedPath: 'lastModified',
useVirtual: false
});
deletePreserved: {
type: Boolean,
default: false
},
validFieldTypes: {
type: [String]
},
fieldType: {
type: String,
required: true,
enum: [
'textfield',
'date',
'email',
'link',
'legal',
'url',
'textarea',
'statement',
'welcome',
'thankyou',
'file',
'dropdown',
'scale',
'rating',
'radio',
'checkbox',
'hidden',
'yes_no',
'natural',
'number'
]
},
fieldValue: Schema.Types.Mixed
});
FormFieldSchema.pre('save', function (next){
this.validFieldTypes = mongoose.model('Field').schema.path('fieldType').enumValues;
next();
this.plugin(mUtilities.timestamp, {
createdPath: 'created',
modifiedPath: 'lastModified',
useVirtual: false
});
this.pre('save', function (next) {
this.validFieldTypes = mongoose.model('Field').schema.path('fieldType').enumValues;
if(this.fieldType === 'rating' && this.ratingOptions.validShapes.length === 0){
this.ratingOptions.validShapes = mongoose.model('RatingOptions').schema.path('shape').enumValues;
}
next();
});
}
util.inherits(BaseFieldSchema, Schema);
var FormFieldSchema = new BaseFieldSchema();
FormFieldSchema.pre('validate', function(next) {
var error = new mongoose.Error.ValidationError(this);
//If field is rating check that it has ratingOptions
if(this.fieldType !== 'rating'){
if(this.ratingOptions && this.ratingOptions.steps && this.ratingOptions.shape){
error.errors.ratingOptions = new mongoose.Error.ValidatorError({path: 'ratingOptions', message: 'ratingOptions is only allowed for type \'rating\' fields.', type: 'notvalid', value: this.ratingOptions});
return(next(error));
}
}else{
//Setting default values for ratingOptions
if(!this.ratingOptions.steps){
this.ratingOptions.steps = 10;
}
if(!this.ratingOptions.shape){
this.ratingOptions.shape = 'Star';
}
//Checking that the fieldValue is between 0 and ratingOptions.steps
if(this.fieldValue+0 > this.ratingOptions.steps || this.fieldValue+0 < 0){
this.fieldValue = 1;
//error.errors.fieldValue = mongoose.Error.ValidatorError({path:'fieldValue', message: 'fieldValue is not within proper range for rating field.', type: 'notvalid', value: this.fieldValue});
//return(next(error));
}
}
//If field is multiple choice check that it has ratingOptions
if(this.fieldType !== 'dropdown' && this.fieldType !== 'radio' && this.fieldType === 'checkbox'){
if(!this.fieldOptions || this.fieldOptions.length !== 0){
error.errors.ratingOptions = new mongoose.Error.ValidatorError({path:'fieldOptions', message: 'fieldOptions are only allowed for type dropdown, checkbox or radio fields.', type: 'notvalid', value: this.ratingOptions});
return(next(error));
}
}
if(error)
return next();
});
mongoose.model('Field', FormFieldSchema);
//Validate and convert dropdown value to fieldValue
FormFieldSchema.pre('validate', function (next) {
return next();
/*
if(this.fieldType === 'dropdown' && this.fieldOptions.length > 0){
for(var i = 0; i<this.fieldOptions.length; i++){
}
}*/
});
var Field = mongoose.model('Field', FormFieldSchema);
var RatingOptions = mongoose.model('RatingOptions', RatingFieldSchema);
module.exports = FormFieldSchema;

View file

@ -33,7 +33,8 @@
"angular-busy": "^4.1.3",
"angular-input-stars": "https://github.com/whitef0x0/angular-input-stars.git#master",
"raven-js": "^3.0.4",
"tableExport.jquery.plugin": "^1.5.1"
"tableExport.jquery.plugin": "^1.5.1",
"js-yaml": "^3.6.1"
},
"resolutions": {
"angular-bootstrap": "^0.14.0",

View file

@ -63,7 +63,7 @@
"math": "0.0.3",
"method-override": "~2.3.0",
"mkdirp": "^0.5.1",
"mongoose": "3.8.40",
"mongoose": "~4.4.19",
"mongoose-utilities": "~0.1.1",
"morgan": "~1.6.1",
"multer": "~1.1.0",

View file

@ -57,7 +57,7 @@ angular.module('NodeForm.templates', []).run(['$templateCache', function($templa
$templateCache.put("../public/modules/forms/views/directiveViews/field/radio.html",
"<div class=\"field row radio\" on-enter-key=nextField() key-to-option field=field ng-if=\"field.fieldOptions.length > 0\"><div class=\"col-xs-12 field-title\" ng-style=\"{'color': design.colors.questionColor}\"><h3><small class=field-number>{{index+1}} <i class=\"fa fa-angle-double-right\" aria-hidden=true></i></small> {{field.title}} <span class=required-error ng-show=!field.required>optional</span></h3></div><div class=\"col-xs-12 field-input\"><div ng-repeat=\"option in field.fieldOptions\" class=row-fluid><label class=\"btn col-md-4 col-xs-12 col-sm-12\" style=\"margin: 0.5em; padding-left:30px\" ng-class=\"{activeBtn: field.fieldValue == field.fieldOptions[$index].option_value}\"><div class=letter style=float:left>{{$index+1}}</div><input ng-style=\"{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}\" type=radio class=focusOn ng-focus=\"setActiveField(field._id, index, true)\" value={{option.option_value}} ng-model=field.fieldValue ng-model-options=\"{ debounce: 250 }\" ng-required=field.required ng-disabled=field.disabled ng-change=\"$root.nextField()\"> <span ng-bind=option.option_value></span></label></div></div></div><br>");
$templateCache.put("../public/modules/forms/views/directiveViews/field/rating.html",
"<div class=\"textfield field row\" on-enter-key=nextField()><div class=\"col-xs-12 field-title\" ng-style=\"{'color': design.colors.questionColor}\"><h3><small class=field-number>{{index+1}} <i class=\"fa fa-angle-double-right\" aria-hidden=true></i></small> {{field.title}} <span class=required-error ng-show=!field.required>optional</span></h3></div><div class=\"col-xs-12 field-input\"><input-stars max=5 ng-init=\"field.fieldValue = 1\" on-star-click=$root.nextField() icon-full=fa-star icon-base=\"fa fa-3x\" icon-empty=fa-star-o ng-model=field.fieldValue ng-model-options=\"{ debounce: 250 }\" ng-required=field.required ng-disabled=field.disabled class=\"angular-input-stars focusOn\"></input-stars></div></div>");
"<div class=\"textfield field row\" on-enter-key=nextField()><div class=\"col-xs-12 field-title\" ng-style=\"{'color': design.colors.questionColor}\"><h3><small class=field-number>{{index+1}} <i class=\"fa fa-angle-double-right\" aria-hidden=true></i></small> {{field.title}} <span class=required-error ng-show=!field.required>optional</span></h3></div><div class=\"col-xs-12 field-input\"><input-stars max=5 ng-init=\"field.fieldValue = 1\" on-star-click=$root.nextField() ratingshapeicon=Trash icon-base=\"fa fa-3x\" ng-model=field.fieldValue ng-model-options=\"{ debounce: 250 }\" ng-required=field.required ng-disabled=field.disabled class=\"angular-input-stars focusOn\"></input-stars></div></div>");
$templateCache.put("../public/modules/forms/views/directiveViews/field/statement.html",
"<div class=\"statement field row\" on-enter-key=$root.nextField() ng-focus=\"setActiveField(field._id, index, true)\"><div class=\"row field-title field-title\"><div class=col-xs-1><i class=\"fa fa-quote-left fa-1\"></i></div><h2 class=\"text-left col-xs-9\">{{field.title}}</h2></div><div class=\"row field-title field-input\"><p class=col-xs-12 ng-if=field.description.length>{{field.description}}</p><br><div class=\"col-xs-offset-1 col-xs-11\"><button class=\"btn focusOn\" ng-style=\"{'font-size': '1.3em', 'background-color':design.colors.buttonColor, 'color':design.colors.buttonTextColor}\" ng-focused=\"setActiveField(field._id, index, true)\" ng-click=$root.nextField()>Continue</button></div></div></div>");
$templateCache.put("../public/modules/forms/views/directiveViews/field/textarea.html",
@ -1616,7 +1616,7 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
'use strict';
angular.module('forms').directive('fieldIconDirective', function() {
return {
template: '<i class="{{typeIcon}}"></i>',
restrict: 'E',
@ -1643,9 +1643,10 @@ angular.module('forms').directive('fieldIconDirective', function() {
'number': 'fa fa-slack'
};
$scope.typeIcon = iconTypeMap[$scope.typeName];
}],
}]
};
});
'use strict';
// coffeescript's for in loop
@ -1656,8 +1657,8 @@ var __indexOf = [].indexOf || function(item) {
return -1;
};
angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$rootScope', '$templateCache',
function($http, $compile, $rootScope, $templateCache) {
angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$rootScope', '$templateCache', 'FontAwesomeIcons',
function($http, $compile, $rootScope, $templateCache, FontAwesomeIcons) {
var getTemplateUrl = function(fieldType) {
var type = fieldType;
@ -1677,7 +1678,7 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
'number',
'natural'
];
if (__indexOf.call(supported_fields, type) >= 0) {
if (__indexOf.call(supported_fields, type) >= 0) {
templateUrl = templateUrl+type+'.html';
}
return $templateCache.get('../public/'+templateUrl);
@ -1695,6 +1696,14 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
},
link: function(scope, element) {
FontAwesomeIcons.get(function(data){
console.log('font awesome icons');
console.log(data);
console.log(data.iconCategoryList);
console.log(data.iconList);
console.log(data.iconMap);
});
$rootScope.chooseDefaultOption = scope.chooseDefaultOption = function(type) {
if(type === 'yes_no'){
scope.field.fieldValue = 'true';
@ -1756,26 +1765,21 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
angular.module('forms').directive('keyToOption', function(){
return {
restrict: 'AE',
transclude: true,
restrict: 'A',
scope: {
field: '&'
field: '='
},
link: function($scope, $element, $attrs, $select) {
$element.bind('keydown keypress', function(event) {
var keyCode = event.which || event.keyCode;
var index = parseInt(String.fromCharCode(keyCode))-1;
console.log($scope.field);
//console.log($scope.field);
if (index < $scope.field.fieldOptions.length) {
event.preventDefault();
$scope.$apply(function () {
$scope.field.fieldValue = $scope.field.fieldOptions[index].option_value;
if($attrs.type === 'dropdown'){
$select.selected.option_value = $scope.field.fieldOptions[index].option_value;
}
console.log($scope);
});
}
@ -1864,6 +1868,64 @@ angular.module('forms').directive('onFinishRender', ["$rootScope", "$timeout", f
'use strict';
angular.module('forms').directive('ratingShapeIcon', ['FontAwesomeIcons', function(FontAwesomeIcons) {
var getRatingShape = function (fieldType, iconData) {
var iconObj = {
full: "",
base: "fa fa-3x",
empty: ""
};
var supported_fields = [
'Heart',
'Star',
'thumbs-up',
'thumbs-down',
'Circle',
'Square',
'Check Circle',
'Smile Outlined',
'Hourglass',
'bell',
'Paper Plane',
'Comment',
'Trash'
];
if (__indexOf.call(iconData.iconList, fieldType) >= 0) {
var iconName = __indexOf.call(iconData.iconList, fieldType);
iconObj.full = "fa-"+iconData.iconMap[iconName];
iconObj.empty = "fa-"+iconData.iconMap[iconName]+"-o";
if(iconName == "thumbs-up" || iconName == "thumbs-down"){
iconObj.empty = "fa-"+iconData.iconMap[iconName].split("-")[0]+"-o-"+iconData.iconMap[iconName].split("-")[1];
}else if(iconName == "Smile Outlined"){
iconObj.empty = "fa-frown-o";
}
return iconObj;
} else {
throw new Error("Error no shape of type: " + fieldType + " for rating input");
}
};
return {
restrict: 'A',
priority: 10000,
terminal: true,
scope: {
ratingShapeIcon: '@'
},
link: function(scope, element, attrs) {
var attrData = getRatingShape(attrs.ratingShapeIcon);
attrs.$set('icon-full', attrData.full);
attrs.$set('icon-empty', attrData.empty);
$compile(element)(scope);
}
};
}]);
'use strict';
angular.module('forms').directive('submitFormDirective', ['$http', 'TimeCounter', '$filter', '$rootScope', 'Auth',
function ($http, TimeCounter, $filter, $rootScope, Auth) {
return {
@ -2083,6 +2145,44 @@ angular.module('forms').service('CurrentForm',
);
'use strict';
//Font-awesome-icon service used for fetching and mapping icon class names
angular.module('forms').service('FontAwesomeIcons', ['$http', '$q', '$resource',
function($http, $q, $resource){
var iconData = {};
this.get = function(callback){
//Fetch icon list from font-awesome repo
$http.get('https://raw.githubusercontent.com/FortAwesome/Font-Awesome/gh-pages/icons.yml').success(function (data) {
var parsedData = jsyaml.load(data);
var parsedIconData = {
iconMap: {},
iconList: [],
iconCategoryList: []
};
var icons = parsedData.icons;
for (var i = 0; i < icons.length; i++) {
parsedIconData.iconMap[icons[i].name] = icons[i].id;
parsedIconData.iconList.push(icons[i].name);
for (var x = 0; x < icons[i].categories.length; x++) {
if (!parsedIconData.iconCategoryList[icons[i].categories[x]]) parsedIconData.iconCategoryList[icons[i].categories[x]] = [];
parsedIconData.iconCategoryList[icons[i].categories[x]].push(icons[i].name);
}
}
callback(parsedIconData);
});
}
}
]);
'use strict';
//TODO: DAVID: URGENT: Make this a $resource that fetches valid field types from server
angular.module('forms').service('FormFields', [
function() {
@ -2166,7 +2266,7 @@ angular.module('forms').factory('Forms', ['$resource',
}, {
'query' : {
method: 'GET',
isArray: true,
isArray: true
//DAVID: TODO: Do we really need to get visible_form_fields for a Query?
// transformResponse: function(data, header) {
// var forms = angular.fromJson(data);
@ -2182,7 +2282,6 @@ angular.module('forms').factory('Forms', ['$resource',
method: 'GET',
transformResponse: function(data, header) {
var form = angular.fromJson(data);
//console.log(form);
form.visible_form_fields = _.filter(form.form_fields, function(field){
return (field.deletePreserved === false);

File diff suppressed because one or more lines are too long

View file

@ -79,7 +79,7 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
}
});
//Autosave Form when model (specificed in $attrs.autoSaveWatch) changes
//Autosave Form when model (specified in $attrs.autoSaveWatch) changes
$scope.$watch($attrs.autoSaveWatch, function(newValue, oldValue) {
newValue = angular.copy(newValue);

View file

@ -24,8 +24,25 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
forcePlaceholderSize: true
};
console.log($scope.sortableOptions);
/*
** Setup Angular-Input-Star Shape Dropdown
*/
//Populate Name to Font-awesomeName Conversion Map
$scope.select2FA = {
'Heart': 'Heart',
'Star': 'Star',
'thumbs-up': 'Thumbs Up',
'thumbs-down':'Thumbs Down',
'Circle': 'Circle',
'Square':'Square',
'Check Circle': 'Checkmark',
'Smile Outlined': 'Smile',
'Hourglass': 'Hourglass',
'bell': 'Bell',
'Paper Plane': 'Paper Plane',
'Comment': 'Chat Bubble',
'Trash': 'Trash Can'
};
//Populate AddField with all available form field types
$scope.addField = {};
@ -98,9 +115,17 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
disabled: false,
deletePreserved: false
};
// console.log('\n\n---------\nAdded field CLIENT');
// console.log(newField);
// newField._id = _.uniqueId();
if($scope.showAddOptions(newField)){
newField.fieldOptions = [];
newField.fieldOptions.push({
'option_id' : Math.floor(100000*Math.random()),
'option_title' : 'Option 0',
'option_value' : 'Option 0'
});
}
console.log(newField);
// put newField into fields array
if(modifyForm){
@ -168,20 +193,17 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
// add new option to the field
$scope.addOption = function(field_index){
var currField = $scope.myform.form_fields[field_index];
console.log(field_index);
console.log(currField);
//console.log(field_index);
//console.log(currField);
if(currField.fieldType === 'checkbox' || currField.fieldType === 'dropdown' || currField.fieldType === 'radio'){
if(!currField.fieldOptions) $scope.myform.form_fields[field_index].fieldOptions = [];
if(!currField.fieldOptions){
$scope.myform.form_fields[field_index].fieldOptions = [];
}
var lastOptionID = 0;
if(currField.fieldOptions[currField.fieldOptions.length-1]){
lastOptionID = currField.fieldOptions[currField.fieldOptions.length-1].option_id;
}
var lastOptionID = $scope.myform.form_fields[field_index].fieldOptions.length+1;
// new option's id
var option_id = lastOptionID + 1;
var newOption = {
'option_id' : Math.floor(100000*Math.random()),
@ -219,7 +241,17 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
}
};
}
// decides whether field options block will be shown (true for dropdown and radio fields)
$scope.showRatingOptions = function (field){
if(field.fieldType === 'rating'){
return true;
} else {
return false;
}
};
}
};
}

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('forms').directive('fieldIconDirective', function() {
return {
template: '<i class="{{typeIcon}}"></i>',
restrict: 'E',
@ -28,6 +28,6 @@ angular.module('forms').directive('fieldIconDirective', function() {
'number': 'fa fa-slack'
};
$scope.typeIcon = iconTypeMap[$scope.typeName];
},
}
};
});
});

View file

@ -29,7 +29,7 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
'number',
'natural'
];
if (__indexOf.call(supported_fields, type) >= 0) {
if (__indexOf.call(supported_fields, type) >= 0) {
templateUrl = templateUrl+type+'.html';
}
return $templateCache.get('../public/'+templateUrl);
@ -38,7 +38,7 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
return {
template: '<div>{{field.title}}</div>',
restrict: 'E',
scope: {
scope: {
field: '=',
required: '&',
design: '=',
@ -46,7 +46,7 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
forms: '='
},
link: function(scope, element) {
$rootScope.chooseDefaultOption = scope.chooseDefaultOption = function(type) {
if(type === 'yes_no'){
scope.field.fieldValue = 'true';
@ -99,7 +99,17 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
}
var template = getTemplateUrl(fieldType);
element.html(template).show();
$compile(element.contents())(scope);
if(scope.field.fieldType === 'rating'){
//while($filter('toFaIcon')('Heart', false) == '-') {
//angular.element('input-stars').attr('icon-full', $filter('toFaIcon')('Heart', false));
//angular.element('input-stars').attr('icon-empty', $filter('toFaIcon')('Heart', true));
//console.log($filter('toFaIcon')('Heart', false));
//}
}
var output = $compile(element.contents())(scope);
}
};
}]);

View file

@ -0,0 +1,91 @@
// 'use strict';
//
// angular.module('forms').filter('toFaIcon', ['FontAwesomeIcons', '$timeout', function(FontAwesomeIcons, $timeout) {
// var data = null, // DATA RECEIVED ASYNCHRONOUSLY AND CACHED HERE
// serviceInvoked = false;
//
// var getRatingShape = function (fieldType, iconData) {
// var iconObj = {
// full: "",
// empty: ""
// };
// var supported_fields = [
// 'Heart',
// 'Star',
// 'thumbs-up',
// 'thumbs-down',
// 'Circle',
// 'Square',
// 'Check Circle',
// 'Smile Outlined',
// 'Hourglass',
// 'bell',
// 'Paper Plane',
// 'Comment',
// 'Trash'
// ];
// if (__indexOf.call(iconData.iconList, fieldType) >= 0) {
//
// iconObj.full = "fa-"+iconData.iconMap[fieldType];
// iconObj.empty = "fa-"+iconData.iconMap[fieldType]+"-o";
// if(fieldType == "thumbs-up" || fieldType == "thumbs-down"){
// iconObj.empty = "fa-"+iconData.iconMap[fieldType].split("-")[0]+"-o-"+iconData.iconMap[fieldType].split("-")[1];
// }else if(fieldType == "Smile Outlined"){
// iconObj.empty = "fa-frown-o";
// }
//
// return iconObj;
// } else {
// throw new Error("Error no shape of type: " + fieldType + " for rating input");
// }
// };
//
//
// var realFilter = function initialFilter(shapeType, isEmpty) {
// console.log('oldFilter');
// if(isEmpty) return "fa-star-o"; // PLACEHOLDER
// else return "fa-star";
// };
//
// // function filterStub(shapeType, isEmpty){
// // if( data === null ) {
// // if (!serviceInvoked) {
// // serviceInvoked = true;
// //$timeout(function () {
// FontAwesomeIcons.get().then(function (result) {
// data = result;
//
//
// realFilter = function newFilter(shapeType, isEmpty) {
// console.log('newFilter');
// var faData = getRatingShape(shapeType, data);
// if (isEmpty) return faData.empty;
// return faData.full;
// };
//
// }, function (err) {
// throw new Error("toShapeIcon Error: " + err.message || err);
// });
// /*realFilter = function newFilter(shapeType, isEmpty) {
// console.log('newFilter');
// if(isEmpty) return "fa-heart-o"; // PLACEHOLDER
// else return "fa-heart";
// }*/
// //}, 1000);
// // }
// // return "-";
// // //if(isEmpty) return "fa-star-o"; // PLACEHOLDER
// // //else return "fa-star";
// // } else return realFilter(shapeType, isEmpty);
// // }
// // filterStub.$stateful = true;
// // return filterStub;
//
// function tempFilter(shapeType, isEmpty) {
// return realFilter(shapeType, isEmpty);
// }
// tempFilter.$stateful = true;
//
// return tempFilter;
//
// }]);

View file

@ -0,0 +1,46 @@
// 'use strict';
//
// //Font-awesome-icon service used for fetching and mapping icon class names
// angular.module('forms').service('FontAwesomeIcons', ['$http', '$q',
// function($http, $q){
//
// var iconData = {};
// this.get = function(callback){
//
// var deferred = $q.defer();
//
// //Fetch icon list from font-awesome repo
// $http.get('https://raw.githubusercontent.com/FortAwesome/Font-Awesome/gh-pages/icons.yml').then(function (response) {
// var parsedData = jsyaml.load(response.data);
//
// var parsedIconData = {
// iconMap: {},
// iconList: [],
// iconCategoryList: []
// };
//
// var icons = parsedData.icons;
//
// for (var i = 0; i < icons.length; i++) {
// parsedIconData.iconMap[icons[i].name] = icons[i].id;
// parsedIconData.iconList.push(icons[i].name);
//
// for (var x = 0; x < icons[i].categories.length; x++) {
// if (!parsedIconData.iconCategoryList[icons[i].categories[x]]) parsedIconData.iconCategoryList[icons[i].categories[x]] = [];
// parsedIconData.iconCategoryList[icons[i].categories[x]].push(icons[i].name);
// }
// }
//
// deferred.resolve(parsedIconData);
// },
// //Error Callback Function
// function(data){
// var error = response.data || "Request failed";
// deferred.reject(error);
// });
//
// return deferred.promise;
// }
//
// }
// ]);

View file

@ -8,7 +8,7 @@ angular.module('forms').factory('Forms', ['$resource',
}, {
'query' : {
method: 'GET',
isArray: true,
isArray: true
//DAVID: TODO: Do we really need to get visible_form_fields for a Query?
// transformResponse: function(data, header) {
// var forms = angular.fromJson(data);
@ -24,9 +24,9 @@ angular.module('forms').factory('Forms', ['$resource',
method: 'GET',
transformResponse: function(data, header) {
var form = angular.fromJson(data);
//console.log(form);
form.visible_form_fields = _.filter(form.form_fields, function(field){
console.log(form.form_fields);
form.visible_form_fields = _.filter(form.form_fields, function(field){
return (field.deletePreserved === false);
});
return form;

View file

@ -6,17 +6,18 @@
{{index+1}}
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
</small>
{{field.title}}
{{field.title}}
<span class="required-error" ng-show="!field.required">optional</span>
</h3>
</div>
<div class="col-xs-12 field-input">
<input-stars max="5"
<input-stars max="{{field.ratingOptions.steps}}"
ng-init="field.fieldValue = 1"
on-star-click="$root.nextField()"
icon-full="fa-star"
icon-full="{{field.ratingOptions.shape}}"
icon-base="fa fa-3x"
icon-empty="fa-star-o"
icon-empty="{{field.ratingOptions.shape}}"
ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }"
ng-required="field.required"

View file

@ -220,13 +220,13 @@
<div class="row"><br></div>
<div class="row description">
<div class="row description" ng-hide="showRatingOptions(field)">
<div class="col-md-4 col-sm-12">Description:</div>
<div class="col-md-8 col-sm-12"><textarea type="text" ng-model="field.description" name="description{{field._id}}"value="{{field.description}}"></textarea> </div>
</div>
<div class="row" ng-show="showAddOptions(field)"><br></div>
<div class="row options" ng-show="showAddOptions(field)">
<div class="row options" ng-if="showAddOptions(field)">
<div class="col-md-4 col-xs-12">Options:</div>
<div class="col-md-8 col-xs-12">
<div ng-repeat="option in field.fieldOptions track by option.option_id" class="row">
@ -244,6 +244,27 @@
</div>
</div>
<div class="row" ng-show="showRatingOptions(field)"><br></div>
<div class="row" ng-if="showRatingOptions(field)">
<div class="col-md-9 col-sm-9">Number of Steps:</div>
<div class="col-md-3 col-sm-3">
<input style="width:100%" type="number" ng-model="field.ratingOptions.steps" name="ratingOptions_steps{{field._id}}" ng-value="{{field.ratingOptions.steps}}" required>
</div>
<br>
<div class="col-md-5 col-sm-9">Shape:</div>
<div class="col-md-7 col-sm-3">
<select style="width:100%" ng-model="field.ratingOptions.shape"
value="{{field.ratingOptions.steps}}"
name="ratingOptions_shape{{field._id}}" required>
<option ng-repeat="shapeType in field.ratingOptions.validShapes"
value="{{shapeType}}">
{{select2FA[shapeType]}}
</option>
</select>
</div>
</div>
<div class="row"><br></div>
<div class="row">