Merge branch 'customizeRating' into stage
This commit is contained in:
commit
0a50653def
|
@ -210,7 +210,6 @@ exports.createSubmission = function(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
submission.save(function(err, submission){
|
submission.save(function(err, submission){
|
||||||
// console.log('in submissions.save()\n submission: '+JSON.stringify(submission) )
|
|
||||||
if(err){
|
if(err){
|
||||||
console.log(err.message);
|
console.log(err.message);
|
||||||
res.status(400).send({
|
res.status(400).send({
|
||||||
|
|
|
@ -65,10 +65,8 @@ var FormSchema = new Schema({
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
form_fields: {
|
|
||||||
type: [FieldSchema]
|
|
||||||
},
|
|
||||||
|
|
||||||
|
form_fields: [FieldSchema],
|
||||||
submissions: [{
|
submissions: [{
|
||||||
type: Schema.Types.ObjectId,
|
type: Schema.Types.ObjectId,
|
||||||
ref: 'FormSubmission'
|
ref: 'FormSubmission'
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* Module dependencies.
|
* Module dependencies.
|
||||||
*/
|
*/
|
||||||
var mongoose = require('mongoose'),
|
var mongoose = require('mongoose'),
|
||||||
|
util = require('util'),
|
||||||
mUtilities = require('mongoose-utilities'),
|
mUtilities = require('mongoose-utilities'),
|
||||||
_ = require('lodash'),
|
_ = require('lodash'),
|
||||||
Schema = mongoose.Schema;
|
Schema = mongoose.Schema;
|
||||||
|
@ -23,85 +24,184 @@ var FieldOptionSchema = new Schema({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var RatingFieldSchema = new Schema({
|
||||||
|
steps: {
|
||||||
|
type: Number,
|
||||||
|
min: 1,
|
||||||
|
max: 10
|
||||||
|
},
|
||||||
|
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
|
* FormField Schema
|
||||||
*/
|
*/
|
||||||
var FormFieldSchema = new Schema({
|
function BaseFieldSchema(){
|
||||||
title: {
|
Schema.apply(this, arguments);
|
||||||
type: String,
|
|
||||||
trim: true,
|
|
||||||
required: 'Field Title cannot be blank'
|
|
||||||
},
|
|
||||||
description: {
|
|
||||||
type: String,
|
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
|
|
||||||
logicJump: {
|
this.add({
|
||||||
type: Schema.Types.ObjectId,
|
title: {
|
||||||
ref: 'LogicJump'
|
type: String,
|
||||||
},
|
trim: true,
|
||||||
|
required: 'Field Title cannot be blank'
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
|
||||||
fieldOptions: [FieldOptionSchema],
|
logicJump: {
|
||||||
required: {
|
type: Schema.Types.ObjectId,
|
||||||
type: Boolean,
|
ref: 'LogicJump'
|
||||||
default: true
|
},
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
|
|
||||||
deletePreserved: {
|
ratingOptions: {
|
||||||
type: Boolean,
|
type: RatingFieldSchema,
|
||||||
default: false
|
required: false,
|
||||||
},
|
default: {}
|
||||||
validFieldTypes: {
|
},
|
||||||
type: [String]
|
fieldOptions: [FieldOptionSchema],
|
||||||
},
|
required: {
|
||||||
fieldType: {
|
type: Boolean,
|
||||||
type: String,
|
default: true
|
||||||
required: true,
|
},
|
||||||
enum: [
|
disabled: {
|
||||||
'textfield',
|
type: Boolean,
|
||||||
'date',
|
default: false
|
||||||
'email',
|
},
|
||||||
'link',
|
|
||||||
'legal',
|
|
||||||
'url',
|
|
||||||
'textarea',
|
|
||||||
'statement',
|
|
||||||
'welcome',
|
|
||||||
'thankyou',
|
|
||||||
'file',
|
|
||||||
'dropdown',
|
|
||||||
'scale',
|
|
||||||
'rating',
|
|
||||||
'radio',
|
|
||||||
'checkbox',
|
|
||||||
'hidden',
|
|
||||||
'yes_no',
|
|
||||||
'natural',
|
|
||||||
'number'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
fieldValue: Schema.Types.Mixed
|
|
||||||
});
|
|
||||||
|
|
||||||
FormFieldSchema.plugin(mUtilities.timestamp, {
|
deletePreserved: {
|
||||||
createdPath: 'created',
|
type: Boolean,
|
||||||
modifiedPath: 'lastModified',
|
default: false
|
||||||
useVirtual: 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.plugin(mUtilities.timestamp, {
|
||||||
this.validFieldTypes = mongoose.model('Field').schema.path('fieldType').enumValues;
|
createdPath: 'created',
|
||||||
next();
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//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;
|
module.exports = FormFieldSchema;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@
|
||||||
"angular-busy": "^4.1.3",
|
"angular-busy": "^4.1.3",
|
||||||
"angular-input-stars": "https://github.com/whitef0x0/angular-input-stars.git#master",
|
"angular-input-stars": "https://github.com/whitef0x0/angular-input-stars.git#master",
|
||||||
"raven-js": "^3.0.4",
|
"raven-js": "^3.0.4",
|
||||||
"tableExport.jquery.plugin": "^1.5.1"
|
"tableExport.jquery.plugin": "^1.5.1",
|
||||||
|
"js-yaml": "^3.6.1"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"angular-bootstrap": "^0.14.0",
|
"angular-bootstrap": "^0.14.0",
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
"math": "0.0.3",
|
"math": "0.0.3",
|
||||||
"method-override": "~2.3.0",
|
"method-override": "~2.3.0",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"mongoose": "3.8.40",
|
"mongoose": "~4.4.19",
|
||||||
"mongoose-utilities": "~0.1.1",
|
"mongoose-utilities": "~0.1.1",
|
||||||
"morgan": "~1.6.1",
|
"morgan": "~1.6.1",
|
||||||
"multer": "~1.1.0",
|
"multer": "~1.1.0",
|
||||||
|
|
129
public/dist/application.js
vendored
129
public/dist/application.js
vendored
|
@ -57,7 +57,7 @@ angular.module('NodeForm.templates', []).run(['$templateCache', function($templa
|
||||||
$templateCache.put("../public/modules/forms/views/directiveViews/field/radio.html",
|
$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>");
|
"<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",
|
$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",
|
$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>");
|
"<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",
|
$templateCache.put("../public/modules/forms/views/directiveViews/field/textarea.html",
|
||||||
|
@ -1643,9 +1643,10 @@ angular.module('forms').directive('fieldIconDirective', function() {
|
||||||
'number': 'fa fa-slack'
|
'number': 'fa fa-slack'
|
||||||
};
|
};
|
||||||
$scope.typeIcon = iconTypeMap[$scope.typeName];
|
$scope.typeIcon = iconTypeMap[$scope.typeName];
|
||||||
}],
|
}]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// coffeescript's for in loop
|
// coffeescript's for in loop
|
||||||
|
@ -1656,8 +1657,8 @@ var __indexOf = [].indexOf || function(item) {
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$rootScope', '$templateCache',
|
angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$rootScope', '$templateCache', 'FontAwesomeIcons',
|
||||||
function($http, $compile, $rootScope, $templateCache) {
|
function($http, $compile, $rootScope, $templateCache, FontAwesomeIcons) {
|
||||||
|
|
||||||
var getTemplateUrl = function(fieldType) {
|
var getTemplateUrl = function(fieldType) {
|
||||||
var type = fieldType;
|
var type = fieldType;
|
||||||
|
@ -1677,7 +1678,7 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
|
||||||
'number',
|
'number',
|
||||||
'natural'
|
'natural'
|
||||||
];
|
];
|
||||||
if (__indexOf.call(supported_fields, type) >= 0) {
|
if (__indexOf.call(supported_fields, type) >= 0) {
|
||||||
templateUrl = templateUrl+type+'.html';
|
templateUrl = templateUrl+type+'.html';
|
||||||
}
|
}
|
||||||
return $templateCache.get('../public/'+templateUrl);
|
return $templateCache.get('../public/'+templateUrl);
|
||||||
|
@ -1695,6 +1696,14 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
|
||||||
},
|
},
|
||||||
link: function(scope, element) {
|
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) {
|
$rootScope.chooseDefaultOption = scope.chooseDefaultOption = function(type) {
|
||||||
if(type === 'yes_no'){
|
if(type === 'yes_no'){
|
||||||
scope.field.fieldValue = 'true';
|
scope.field.fieldValue = 'true';
|
||||||
|
@ -1756,26 +1765,21 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
|
||||||
|
|
||||||
angular.module('forms').directive('keyToOption', function(){
|
angular.module('forms').directive('keyToOption', function(){
|
||||||
return {
|
return {
|
||||||
restrict: 'AE',
|
restrict: 'A',
|
||||||
transclude: true,
|
|
||||||
scope: {
|
scope: {
|
||||||
field: '&'
|
field: '='
|
||||||
},
|
},
|
||||||
link: function($scope, $element, $attrs, $select) {
|
link: function($scope, $element, $attrs, $select) {
|
||||||
$element.bind('keydown keypress', function(event) {
|
$element.bind('keydown keypress', function(event) {
|
||||||
|
|
||||||
var keyCode = event.which || event.keyCode;
|
var keyCode = event.which || event.keyCode;
|
||||||
var index = parseInt(String.fromCharCode(keyCode))-1;
|
var index = parseInt(String.fromCharCode(keyCode))-1;
|
||||||
console.log($scope.field);
|
//console.log($scope.field);
|
||||||
|
|
||||||
if (index < $scope.field.fieldOptions.length) {
|
if (index < $scope.field.fieldOptions.length) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$scope.$apply(function () {
|
$scope.$apply(function () {
|
||||||
$scope.field.fieldValue = $scope.field.fieldOptions[index].option_value;
|
$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';
|
'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',
|
angular.module('forms').directive('submitFormDirective', ['$http', 'TimeCounter', '$filter', '$rootScope', 'Auth',
|
||||||
function ($http, TimeCounter, $filter, $rootScope, Auth) {
|
function ($http, TimeCounter, $filter, $rootScope, Auth) {
|
||||||
return {
|
return {
|
||||||
|
@ -2083,6 +2145,44 @@ angular.module('forms').service('CurrentForm',
|
||||||
);
|
);
|
||||||
'use strict';
|
'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
|
//TODO: DAVID: URGENT: Make this a $resource that fetches valid field types from server
|
||||||
angular.module('forms').service('FormFields', [
|
angular.module('forms').service('FormFields', [
|
||||||
function() {
|
function() {
|
||||||
|
@ -2166,7 +2266,7 @@ angular.module('forms').factory('Forms', ['$resource',
|
||||||
}, {
|
}, {
|
||||||
'query' : {
|
'query' : {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
isArray: true,
|
isArray: true
|
||||||
//DAVID: TODO: Do we really need to get visible_form_fields for a Query?
|
//DAVID: TODO: Do we really need to get visible_form_fields for a Query?
|
||||||
// transformResponse: function(data, header) {
|
// transformResponse: function(data, header) {
|
||||||
// var forms = angular.fromJson(data);
|
// var forms = angular.fromJson(data);
|
||||||
|
@ -2182,7 +2282,6 @@ angular.module('forms').factory('Forms', ['$resource',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
transformResponse: function(data, header) {
|
transformResponse: function(data, header) {
|
||||||
var form = angular.fromJson(data);
|
var form = angular.fromJson(data);
|
||||||
//console.log(form);
|
|
||||||
|
|
||||||
form.visible_form_fields = _.filter(form.form_fields, function(field){
|
form.visible_form_fields = _.filter(form.form_fields, function(field){
|
||||||
return (field.deletePreserved === false);
|
return (field.deletePreserved === false);
|
||||||
|
|
6
public/dist/application.min.js
vendored
6
public/dist/application.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -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) {
|
$scope.$watch($attrs.autoSaveWatch, function(newValue, oldValue) {
|
||||||
|
|
||||||
newValue = angular.copy(newValue);
|
newValue = angular.copy(newValue);
|
||||||
|
|
|
@ -24,8 +24,25 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
|
||||||
forcePlaceholderSize: true
|
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
|
//Populate AddField with all available form field types
|
||||||
$scope.addField = {};
|
$scope.addField = {};
|
||||||
|
@ -98,9 +115,15 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
|
||||||
disabled: false,
|
disabled: false,
|
||||||
deletePreserved: false
|
deletePreserved: false
|
||||||
};
|
};
|
||||||
// console.log('\n\n---------\nAdded field CLIENT');
|
|
||||||
// console.log(newField);
|
if($scope.showAddOptions(newField)){
|
||||||
// newField._id = _.uniqueId();
|
newField.fieldOptions = [];
|
||||||
|
newField.fieldOptions.push({
|
||||||
|
'option_id' : Math.floor(100000*Math.random()),
|
||||||
|
'option_title' : 'Option 0',
|
||||||
|
'option_value' : 'Option 0'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// put newField into fields array
|
// put newField into fields array
|
||||||
if(modifyForm){
|
if(modifyForm){
|
||||||
|
@ -168,20 +191,17 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
|
||||||
// add new option to the field
|
// add new option to the field
|
||||||
$scope.addOption = function(field_index){
|
$scope.addOption = function(field_index){
|
||||||
var currField = $scope.myform.form_fields[field_index];
|
var currField = $scope.myform.form_fields[field_index];
|
||||||
console.log(field_index);
|
//console.log(field_index);
|
||||||
console.log(currField);
|
//console.log(currField);
|
||||||
|
|
||||||
if(currField.fieldType === 'checkbox' || currField.fieldType === 'dropdown' || currField.fieldType === 'radio'){
|
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;
|
var lastOptionID = $scope.myform.form_fields[field_index].fieldOptions.length+1;
|
||||||
|
|
||||||
if(currField.fieldOptions[currField.fieldOptions.length-1]){
|
|
||||||
lastOptionID = currField.fieldOptions[currField.fieldOptions.length-1].option_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// new option's id
|
// new option's id
|
||||||
var option_id = lastOptionID + 1;
|
|
||||||
|
|
||||||
var newOption = {
|
var newOption = {
|
||||||
'option_id' : Math.floor(100000*Math.random()),
|
'option_id' : Math.floor(100000*Math.random()),
|
||||||
|
@ -219,7 +239,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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,6 @@ angular.module('forms').directive('fieldIconDirective', function() {
|
||||||
'number': 'fa fa-slack'
|
'number': 'fa fa-slack'
|
||||||
};
|
};
|
||||||
$scope.typeIcon = iconTypeMap[$scope.typeName];
|
$scope.typeIcon = iconTypeMap[$scope.typeName];
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
|
@ -29,7 +29,7 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
|
||||||
'number',
|
'number',
|
||||||
'natural'
|
'natural'
|
||||||
];
|
];
|
||||||
if (__indexOf.call(supported_fields, type) >= 0) {
|
if (__indexOf.call(supported_fields, type) >= 0) {
|
||||||
templateUrl = templateUrl+type+'.html';
|
templateUrl = templateUrl+type+'.html';
|
||||||
}
|
}
|
||||||
return $templateCache.get('../public/'+templateUrl);
|
return $templateCache.get('../public/'+templateUrl);
|
||||||
|
@ -38,7 +38,7 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
|
||||||
return {
|
return {
|
||||||
template: '<div>{{field.title}}</div>',
|
template: '<div>{{field.title}}</div>',
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: {
|
scope: {
|
||||||
field: '=',
|
field: '=',
|
||||||
required: '&',
|
required: '&',
|
||||||
design: '=',
|
design: '=',
|
||||||
|
@ -99,7 +99,7 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
|
||||||
}
|
}
|
||||||
var template = getTemplateUrl(fieldType);
|
var template = getTemplateUrl(fieldType);
|
||||||
element.html(template).show();
|
element.html(template).show();
|
||||||
$compile(element.contents())(scope);
|
var output = $compile(element.contents())(scope);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}]);
|
}]);
|
||||||
|
|
|
@ -179,14 +179,13 @@ angular.module('forms').directive('submitFormDirective', ['$http', 'TimeCounter'
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
$scope.submitPromise = $http.post('/forms/' + $scope.myform._id, form)
|
$scope.submitPromise = $http.post('/forms/' + $scope.myform._id, form)
|
||||||
.success(function (data, status, headers) {
|
.success(function (data, status, headers) {
|
||||||
//console.log('form submitted successfully');
|
|
||||||
|
|
||||||
$scope.myform.submitted = true;
|
$scope.myform.submitted = true;
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
})
|
})
|
||||||
.error(function (error) {
|
.error(function (error) {
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
//console.log(error);
|
console.error(error);
|
||||||
$scope.error = error.message;
|
$scope.error = error.message;
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
|
@ -8,7 +8,7 @@ angular.module('forms').factory('Forms', ['$resource',
|
||||||
}, {
|
}, {
|
||||||
'query' : {
|
'query' : {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
isArray: true,
|
isArray: true
|
||||||
//DAVID: TODO: Do we really need to get visible_form_fields for a Query?
|
//DAVID: TODO: Do we really need to get visible_form_fields for a Query?
|
||||||
// transformResponse: function(data, header) {
|
// transformResponse: function(data, header) {
|
||||||
// var forms = angular.fromJson(data);
|
// var forms = angular.fromJson(data);
|
||||||
|
@ -24,9 +24,8 @@ angular.module('forms').factory('Forms', ['$resource',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
transformResponse: function(data, header) {
|
transformResponse: function(data, header) {
|
||||||
var form = angular.fromJson(data);
|
var form = angular.fromJson(data);
|
||||||
//console.log(form);
|
|
||||||
|
|
||||||
form.visible_form_fields = _.filter(form.form_fields, function(field){
|
form.visible_form_fields = _.filter(form.form_fields, function(field){
|
||||||
return (field.deletePreserved === false);
|
return (field.deletePreserved === false);
|
||||||
});
|
});
|
||||||
return form;
|
return form;
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
{{field.title}}
|
{{field.title}}
|
||||||
<span class="required-error" ng-show="!field.required && !field.fieldValue">optional</span>
|
<span class="required-error" ng-show="!field.required && !field.fieldValue">optional</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
<p class="col-xs-12">
|
||||||
|
<small>{{field.description}}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 field-input">
|
<div class="col-xs-12 field-input">
|
||||||
<div class="control-group input-append">
|
<div class="control-group input-append">
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
{{field.title}}
|
{{field.title}}
|
||||||
<span class="required-error" ng-show="!field.required">optional</span>
|
<span class="required-error" ng-show="!field.required">optional</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
<p class="col-xs-12">
|
||||||
|
<small>{{field.description}}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 field-input">
|
<div class="col-xs-12 field-input">
|
||||||
<ui-select ng-model="field.fieldValue"
|
<ui-select ng-model="field.fieldValue"
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<span class="required-error" ng-show="!field.required">optional</span>
|
<span class="required-error" ng-show="!field.required">optional</span>
|
||||||
</h3>
|
</h3>
|
||||||
<br>
|
<br>
|
||||||
<p style="color:#ddd;">{{field.description}}</p>
|
<p class="col-xs-12">{{field.description}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 field-input container">
|
<div class="col-xs-12 field-input container">
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
{{field.title}}
|
{{field.title}}
|
||||||
<span class="required-error" ng-show="!field.required">optional</span>
|
<span class="required-error" ng-show="!field.required">optional</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
<p class="col-xs-12">
|
||||||
|
<small>{{field.description}}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 field-input">
|
<div class="col-xs-12 field-input">
|
||||||
|
|
||||||
|
|
|
@ -9,14 +9,18 @@
|
||||||
{{field.title}}
|
{{field.title}}
|
||||||
<span class="required-error" ng-show="!field.required">optional</span>
|
<span class="required-error" ng-show="!field.required">optional</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
<p class="col-xs-12">
|
||||||
|
<small>{{field.description}}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 field-input">
|
<div class="col-xs-12 field-input">
|
||||||
<input-stars max="5"
|
|
||||||
|
<input-stars max="{{field.ratingOptions.steps}}"
|
||||||
ng-init="field.fieldValue = 1"
|
ng-init="field.fieldValue = 1"
|
||||||
on-star-click="$root.nextField()"
|
on-star-click="$root.nextField()"
|
||||||
icon-full="fa-star"
|
icon-full="{{field.ratingOptions.shape}}"
|
||||||
icon-base="fa fa-3x"
|
icon-base="fa fa-3x"
|
||||||
icon-empty="fa-star-o"
|
icon-empty="{{field.ratingOptions.shape}}"
|
||||||
ng-model="field.fieldValue"
|
ng-model="field.fieldValue"
|
||||||
ng-model-options="{ debounce: 250 }"
|
ng-model-options="{ debounce: 250 }"
|
||||||
ng-required="field.required"
|
ng-required="field.required"
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
<div class="row field-title field-title">
|
<div class="row field-title field-title">
|
||||||
<div class="col-xs-1"><i class="fa fa-quote-left fa-1"></i></div>
|
<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>
|
<h2 class="text-left col-xs-9">{{field.title}}</h2>
|
||||||
|
<p class="col-xs-12">
|
||||||
|
<small>{{field.description}}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="row field-title field-input">
|
<div class="row field-title field-input">
|
||||||
<p class="col-xs-12" ng-if="field.description.length">{{field.description}} </p>
|
<p class="col-xs-12" ng-if="field.description.length">{{field.description}} </p>
|
||||||
|
|
|
@ -9,9 +9,12 @@
|
||||||
{{field.title}}
|
{{field.title}}
|
||||||
<span class="required-error" ng-show="!field.required">optional</span>
|
<span class="required-error" ng-show="!field.required">optional</span>
|
||||||
</h3>
|
</h3>
|
||||||
<small>press SHIFT+ENTER to create a newline</small>
|
<p>
|
||||||
|
<small>{{field.description}}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 field-input">
|
<div class="col-xs-12 field-input">
|
||||||
|
<small style="font-size:0.6em;">Press SHIFT+ENTER to add a newline</small>
|
||||||
<textarea class="textarea focusOn" type="text"
|
<textarea class="textarea focusOn" type="text"
|
||||||
ng-model="field.fieldValue"
|
ng-model="field.fieldValue"
|
||||||
ng-model-options="{ debounce: 250 }"
|
ng-model-options="{ debounce: 250 }"
|
||||||
|
@ -20,7 +23,8 @@
|
||||||
ng-required="field.required"
|
ng-required="field.required"
|
||||||
ng-disabled="field.disabled"
|
ng-disabled="field.disabled"
|
||||||
ng-focus="setActiveField(field._id, index, true)"
|
ng-focus="setActiveField(field._id, index, true)"
|
||||||
on-enter-key="nextField()">
|
on-enter-key="nextField()"
|
||||||
|
style="border: none; border-left: lightgrey dashed 2px;">
|
||||||
</textarea>
|
</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="textfield field row"
|
<div class="textfield field row"
|
||||||
ng-click="setActiveField(field._id, index, true)">
|
ng-click="setActiveField(field._id, index, true)">
|
||||||
<div class="col-xs-12 field-title" ng-style="{'color': design.colors.questionColor}">
|
<div class="col-xs-12 field-title row-fluid" ng-style="{'color': design.colors.questionColor}">
|
||||||
<h3>
|
<h3 class="col-xs-12">
|
||||||
<small class="field-number">
|
<small class="field-number">
|
||||||
{{index+1}}
|
{{index+1}}
|
||||||
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
|
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
|
||||||
|
@ -13,6 +13,10 @@
|
||||||
(optional)
|
(optional)
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
|
<p class="col-xs-12">
|
||||||
|
<small>{{field.description}}</small>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 field-input">
|
<div class="col-xs-12 field-input">
|
||||||
<input ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}"
|
<input ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}"
|
||||||
|
|
|
@ -220,13 +220,13 @@
|
||||||
|
|
||||||
<div class="row"><br></div>
|
<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-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 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>
|
||||||
|
|
||||||
<div class="row" ng-show="showAddOptions(field)"><br></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-4 col-xs-12">Options:</div>
|
||||||
<div class="col-md-8 col-xs-12">
|
<div class="col-md-8 col-xs-12">
|
||||||
<div ng-repeat="option in field.fieldOptions track by option.option_id" class="row">
|
<div ng-repeat="option in field.fieldOptions track by option.option_id" class="row">
|
||||||
|
@ -244,6 +244,32 @@
|
||||||
</div>
|
</div>
|
||||||
</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"
|
||||||
|
min="1" max="10"
|
||||||
|
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"><br></div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
Loading…
Reference in a new issue