added diff to update

This commit is contained in:
David Baldwynn 2016-08-26 15:34:29 -07:00
commit 0a74598894
13 changed files with 311 additions and 287 deletions

View file

@ -12,6 +12,7 @@ var mongoose = require('mongoose'),
fs = require('fs-extra'),
async = require('async'),
path = require('path'),
diff = require('deep-diff'),
_ = require('lodash');
/**
@ -69,74 +70,6 @@ exports.uploadPDF = function(req, res, next) {
}
};
/**
* Upload PDF
*/
/*
exports.uploadSubmissionFile = function(req, res, next) {
console.log('inside uploadPDF');
// console.log('\n\nProperty Descriptor\n-----------');
// console.log(Object.getOwnPropertyDescriptor(req.files.file, 'path'));
console.log(req.files);
if(req.files){
var file, _user, _path;
for(var i=0; i<req.files.length; i++){
file = req.files[i];
_user = req.user;
_path = file.path;
if (file.size === 0) {
return next(new Error('File uploaded is EMPTY'));
}else if(file.size > 100000000){
return next(new Error('File uploaded exceeds MAX SIZE of 100MB'));
}else {
fs.exists(_path, function(exists) {
//If file exists move to user's form directory
if(exists) {
var newDestination = config.tmpUploadPath+_user.username;
var stat = null;
try {
stat = fs.statSync(newDestination);
} catch (err) {
fs.mkdirSync(newDestination);
}
if (stat && !stat.isDirectory()) {
console.log('Directory cannot be created');
return next(new Error('Directory cannot be created because an inode of a different type exists at "' + newDestination + '"'));
}
console.log(path.join(newDestination, pdfFile.filename));
fs.move(pdfFile.path, path.join(newDestination, pdfFile.filename), function (err) {
if (err) {
return next(new Error(err.message));
}
pdfFile.path = path.join(newDestination, pdfFile.filename);
console.log(pdfFile.filename + ' uploaded to ' + pdfFile.path);
res.json(pdfFile);
});
} else {
return next(new Error('Did NOT get your file!'));
}
});
}
}
}else {
return next(new Error('Uploaded files were NOT detected'));
}
};
*/
/**
* Delete a forms submissions
*/
@ -294,7 +227,7 @@ exports.read = function(req, res) {
});
}
return res.json(newForm);
};
/**
@ -302,22 +235,32 @@ exports.read = function(req, res) {
*/
exports.update = function(req, res) {
var form = req.form;
/*
delete req.body.form.__v;
delete req.body.form._id;
*/
//Unless we have 'admin' priviledges, updating form admin is disabled
if(req.user.roles.indexOf('admin') === -1) delete req.body.form.admin;
if(req.body.changes){
var formChanges = req.body.changes;
//Do this so we can create duplicate fields
var checkForValidId = new RegExp('^[0-9a-fA-F]{24}$');
for(var i=0; i<req.body.form.form_fields.length; i++){
var field = req.body.form.form_fields[i];
if(!checkForValidId.exec(field._id+'')){
delete field._id;
formChanges.forEach(function (change) {
diff.applyChange(form, true, change);
});
} else {
//Unless we have 'admin' privileges, updating form admin is disabled
if(req.user.roles.indexOf('admin') === -1) delete req.body.form.admin;
//Do this so we can create duplicate fields
var checkForValidId = new RegExp('^[0-9a-fA-F]{24}$');
for(var i=0; i<req.body.form.form_fields.length; i++){
var field = req.body.form.form_fields[i];
if(!checkForValidId.exec(field._id+'')){
delete field._id;
}
}
form = _.extend(form, req.body.form);
}
form = _.extend(form, req.body.form);
form.save(function(err, form) {
if (err) {

View file

@ -36,8 +36,9 @@
"js-yaml": "^3.6.1",
"angular-ui-select": "https://github.com/whitef0x0/ui-select.git#compiled",
"angular-translate": "~2.11.0",
"ng-device-detector": "~3.0.1",
"ng-translate": "*"
"ng-device-detector": "^3.0.1",
"ng-translate": "*",
"deep-diff": "^0.3.4"
},
"resolutions": {
"angular-bootstrap": "^0.14.0",

View file

@ -35,6 +35,7 @@
"connect-mongo": "~0.8.2",
"consolidate": "~0.13.1",
"cookie-parser": "~1.4.0",
"deep-diff": "^0.3.4",
"dotenv": "^2.0.0",
"email-verification": "~0.4.1",
"envfile": "^2.0.1",

View file

@ -326,7 +326,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid
SUBMIT: 'Submit',
UPLOAD_FILE: 'Upload your File'
});
}]);
'use strict';
@ -1268,7 +1268,7 @@ angular.module('users').controller('AuthenticationController', ['$scope', '$loca
angular.module('users').controller('PasswordController', ['$scope', '$stateParams', '$state', 'User',
function($scope, $stateParams, $state, User) {
$scope.error = '';
// Submit forgotten password account id
$scope.askForPasswordReset = function() {
User.askForPasswordReset($scope.credentials).then(
@ -1309,7 +1309,7 @@ angular.module('users').controller('SettingsController', ['$scope', '$rootScope'
function($scope, $rootScope, $http, $state, Users) {
$scope.user = $rootScope.user;
// Check if there are additional accounts
// Check if there are additional accounts
$scope.hasConnectedAdditionalSocialAccounts = function(provider) {
for (var i in $scope.user.additionalProvidersData) {
return true;
@ -1788,7 +1788,7 @@ angular.module('forms').controller('AdminFormController', ['$rootScope', '$scope
};
// Update existing Form
$scope.update = $rootScope.update = function(updateImmediately, cb){
$scope.update = $rootScope.update = function(updateImmediately, diffChanges, cb){
var continueUpdate = true;
if(!updateImmediately){
@ -1801,7 +1801,9 @@ angular.module('forms').controller('AdminFormController', ['$rootScope', '$scope
if(!updateImmediately){ $rootScope.saveInProgress = true; }
$scope.updatePromise = $http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
console.log(diffChanges);
$scope.updatePromise = $http.put('/forms/'+$scope.myform._id, { changes: diffChanges })
.then(function(response){
$rootScope.myform = $scope.myform = response.data;
// console.log(response.data);
@ -1954,7 +1956,6 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
$rootScope.finishedRender = false;
$scope.$on('editFormFields Started', function(ngRepeatFinishedEvent) {
// console.log('hello');
$rootScope.finishedRender = false;
});
$scope.$on('editFormFields Finished', function(ngRepeatFinishedEvent) {
@ -1974,13 +1975,11 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
return false;
};
var debounceSave = function () {
$rootScope.saveInProgress = true;
var debounceSave = function (diffChanges) {
$rootScope[$attrs.autoSaveCallback](true,
$rootScope[$attrs.autoSaveCallback](true, diffChanges,
function(err){
if(!err){
//console.log('\n\nForm data persisted -- setting pristine flag');
$formCtrl.$setPristine();
$formCtrl.$setUntouched();
}else{
@ -1992,12 +1991,10 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
//Update/Save Form if any Form fields are Dirty and Touched
$scope.$watch(function(newValue, oldValue) {
//console.log('introParagraphStartPage.$dirty: '+$scope.editForm.introParagraphStartPage.$dirty);
//console.log('introParagraphStartPage.$touched: '+$scope.editForm.introParagraphStartPage.$touched);
if($rootScope.finishedRender && $scope.anyDirtyAndTouched($scope.editForm) && !$rootScope.saveInProgress){
//console.log('Form saving started');
debounceSave();
//console.log('introParagraphStartPage.$dirty AFTER: '+$scope.editForm.introParagraphStartPage.$dirty);
delete newValue.visible_form_fields;
debounceSave(DeepDiff.diff(oldValue, newValue));
}
});
@ -2011,7 +2008,6 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
oldValue.form_fields = _.removeDateFields(oldValue.form_fields);
var changedFields = !_.isEqual(oldValue.form_fields,newValue.form_fields) || !_.isEqual(oldValue.startPage, newValue.startPage);
var changedFieldMap = false;
if(oldValue.hasOwnProperty('plugins.oscarhost.settings.fieldMap')){
changedFieldMap = !!oldValue.plugins.oscarhost.settings.fieldMap && !_.isEqual(oldValue.plugins.oscarhost.settings.fieldMap,newValue.plugins.oscarhost.settings.fieldMap);
@ -2039,7 +2035,7 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
}
//Save form ONLY IF rendering is finished, form_fields have been changed AND currently not save in progress
if( $rootScope.finishedRender && ((changedFields && !$formCtrl.$dirty) || changedFieldMap) && !$rootScope.saveInProgress) {
if( $rootScope.finishedRender && (changedFields && !$formCtrl.$dirty) && !$rootScope.saveInProgress) {
if(savePromise) {
$timeout.cancel(savePromise);
@ -2047,7 +2043,14 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
}
savePromise = $timeout(function() {
debounceSave();
$rootScope.saveInProgress = true;
console.log(newValue);
console.log(oldValue);
delete newValue.visible_form_fields;
delete newValue.visible_form_fields;
var _diff = DeepDiff.diff(oldValue, newValue);
debounceSave(_diff);
});
}
//If we are finished rendering then form saving should be finished
@ -2169,7 +2172,6 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
},
controller: ["$scope", function($scope){
console.log($scope.myform);
var field_ids = _($scope.myform.form_fields).pluck('_id');
for(var i=0; i<field_ids.length; i++){
$scope.myform.plugins.oscarhost.settings.fieldMap[field_ids[i]] = null;
@ -2268,7 +2270,7 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
}
}
var newField = {
title: fieldTitle,
title: fieldTitle + ' ' + $scope.myform.form_fields.length+1,
fieldType: fieldType,
fieldValue: '',
required: true,
@ -2285,7 +2287,6 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
});
}
if(modifyForm){
//Add newField to form_fields array
$scope.myform.form_fields.push(newField);
@ -2656,15 +2657,15 @@ angular.module('forms').service('FormFields', [
// },
// {
// name : 'stripe',
// value : 'Payment'
// value : 'Payment'
// },
{
name : 'statement',
value : 'Statement'
value : 'Statement'
}
];
}
]);
'use strict';
@ -2677,7 +2678,7 @@ angular.module('forms').factory('Submissions', ['$resource',
formId: '@_id'
}, {
'query' : {
method: 'GET',
method: 'GET',
isArray: true,
},
'update': {
@ -2854,23 +2855,25 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
if(scope.field.fieldType === 'number' || scope.field.fieldType === 'textfield' || scope.field.fieldType === 'email' || scope.field.fieldType === 'link'){
switch(scope.field.fieldType){
case 'textfield':
scope.field.input_type = 'text';
scope.input_type = 'text';
break;
case 'email':
scope.field.input_type = 'email';
scope.field.placeholder = 'joesmith@example.com';
scope.input_type = 'email';
scope.placeholder = 'joesmith@example.com';
break;
case 'number':
scope.field.input_type = 'text';
scope.field.validateRegex = /^-?\d+$/;
scope.input_type = 'text';
scope.validateRegex = /^-?\d+$/;
break;
default:
scope.field.input_type = 'url';
scope.field.placeholder = 'http://example.com';
scope.input_type = 'url';
scope.placeholder = 'http://example.com';
break;
}
fieldType = 'textfield';
}
console.log(scope.input_type);
var template = getTemplateUrl(fieldType);
element.html(template).show();
var output = $compile(element.contents())(scope);
@ -2961,7 +2964,7 @@ angular.module('forms').directive('onFinishRender', ["$rootScope", "$timeout", f
return {
restrict: 'A',
link: function (scope, element, attrs) {
//Don't do anything if we don't have a ng-repeat on the current element
if(!element.attr('ng-repeat') && !element.attr('data-ng-repeat')){
return;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -2,107 +2,108 @@
// coffeescript's for in loop
var __indexOf = [].indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++) {
if (i in this && this[i] === item) return i;
}
return -1;
};
for (var i = 0, l = this.length; i < l; i++) {
if (i in this && this[i] === item) return i;
}
return -1;
};
angular.module('view-form').directive('fieldDirective', ['$http', '$compile', '$rootScope', '$templateCache', 'supportedFields',
function($http, $compile, $rootScope, $templateCache, supportedFields) {
angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$rootScope', '$templateCache', 'supportedFields',
function($http, $compile, $rootScope, $templateCache, supportedFields) {
var getTemplateUrl = function(fieldType) {
var type = fieldType;
var getTemplateUrl = function(fieldType) {
var type = fieldType;
var supported_fields = [
'textfield',
'textarea',
'date',
'dropdown',
'hidden',
'password',
'radio',
'legal',
'statement',
'rating',
'yes_no',
'number',
'natural'
];
var supported_fields = [
'textfield',
'textarea',
'date',
'dropdown',
'hidden',
'password',
'radio',
'legal',
'statement',
'rating',
'yes_no',
'number',
'natural'
];
var templateUrl = 'modules/forms/base/views/directiveViews/field/';
var templateUrl = 'modules/forms/base/views/directiveViews/field/';
if (__indexOf.call(supportedFields, type) >= 0) {
templateUrl = templateUrl+type+'.html';
}
return $templateCache.get(templateUrl);
};
return {
template: '<div>{{field.title}}</div>',
restrict: 'E',
scope: {
field: '=',
required: '&',
design: '=',
index: '=',
forms: '='
},
link: function(scope, element) {
$rootScope.chooseDefaultOption = scope.chooseDefaultOption = function(type) {
if(type === 'yes_no'){
scope.field.fieldValue = 'true';
}else if(type === 'rating'){
scope.field.fieldValue = 0;
}else if(scope.field.fieldType === 'radio'){
console.log(scope.field);
scope.field.fieldValue = scope.field.fieldOptions[0].option_value;
console.log(scope.field.fieldValue);
}else if(type === 'legal'){
scope.field.fieldValue = 'true';
$rootScope.nextField();
}
};
scope.setActiveField = $rootScope.setActiveField;
//Set format only if field is a date
if(scope.field.fieldType === 'date'){
scope.dateOptions = {
changeYear: true,
changeMonth: true,
altFormat: 'mm/dd/yyyy',
yearRange: '1900:-0',
defaultDate: 0
};
}
var fieldType = scope.field.fieldType;
if(scope.field.fieldType === 'number' || scope.field.fieldType === 'textfield' || scope.field.fieldType === 'email' || scope.field.fieldType === 'link'){
switch(scope.field.fieldType){
case 'textfield':
scope.field.input_type = 'text';
break;
case 'email':
scope.field.input_type = 'email';
scope.field.placeholder = 'joesmith@example.com';
break;
case 'number':
scope.field.input_type = 'text';
scope.field.validateRegex = /^-?\d+$/;
break;
default:
scope.field.input_type = 'url';
scope.field.placeholder = 'http://example.com';
break;
}
fieldType = 'textfield';
if (__indexOf.call(supportedFields, type) >= 0) {
templateUrl = templateUrl+type+'.html';
}
var template = getTemplateUrl(fieldType);
element.html(template).show();
var output = $compile(element.contents())(scope);
}
};
}]);
return $templateCache.get(templateUrl);
};
return {
template: '<div>{{field.title}}</div>',
restrict: 'E',
scope: {
field: '=',
required: '&',
design: '=',
index: '=',
forms: '='
},
link: function(scope, element) {
$rootScope.chooseDefaultOption = scope.chooseDefaultOption = function(type) {
if(type === 'yes_no'){
scope.field.fieldValue = 'true';
}else if(type === 'rating'){
scope.field.fieldValue = 0;
}else if(scope.field.fieldType === 'radio'){
console.log(scope.field);
scope.field.fieldValue = scope.field.fieldOptions[0].option_value;
console.log(scope.field.fieldValue);
}else if(type === 'legal'){
scope.field.fieldValue = 'true';
$rootScope.nextField();
}
};
scope.setActiveField = $rootScope.setActiveField;
//Set format only if field is a date
if(scope.field.fieldType === 'date'){
scope.dateOptions = {
changeYear: true,
changeMonth: true,
altFormat: 'mm/dd/yyyy',
yearRange: '1900:-0',
defaultDate: 0
};
}
var fieldType = scope.field.fieldType;
if(scope.field.fieldType === 'number' || scope.field.fieldType === 'textfield' || scope.field.fieldType === 'email' || scope.field.fieldType === 'link'){
switch(scope.field.fieldType){
case 'textfield':
scope.input_type = 'text';
break;
case 'email':
scope.input_type = 'email';
scope.placeholder = 'joesmith@example.com';
break;
case 'number':
scope.input_type = 'text';
scope.validateRegex = /^-?\d+$/;
break;
default:
scope.input_type = 'url';
scope.placeholder = 'http://example.com';
break;
}
fieldType = 'textfield';
}
var template = getTemplateUrl(fieldType);
element.html(template).show();
var output = $compile(element.contents())(scope);
}
};
}]);

View file

@ -21,9 +21,9 @@
<div class="col-xs-12 field-input">
<input ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}"
name="{{field.fieldType}}{{index}}"
type="{{field.input_type}}"
ng-pattern="field.validateRegex"
placeholder="{{field.placeholder}}"
type="{{input_type}}"
ng-pattern="validateRegex"
placeholder="{{placeholder}}"
ng-class="{ 'no-border': !!field.fieldValue }"
class="focusOn text-field-input"
ng-model="field.fieldValue"

View file

@ -17,8 +17,6 @@ angular.module('forms').controller('AdminFormController', ['$rootScope', '$scope
$scope.formURL = "/#!/forms/" + $scope.myform._id;
console.log($scope.myform);
$scope.actualFormURL = window.location.protocol + '//' + $scope.myform.admin.username + '.' + window.location.host + "/#!/forms/" + $scope.myform._id;
@ -106,7 +104,7 @@ angular.module('forms').controller('AdminFormController', ['$rootScope', '$scope
};
// Update existing Form
$scope.update = $rootScope.update = function(updateImmediately, cb){
$scope.update = $rootScope.update = function(updateImmediately, diffChanges, cb){
refreshFrame();
var continueUpdate = true;
@ -120,7 +118,7 @@ angular.module('forms').controller('AdminFormController', ['$rootScope', '$scope
if(!updateImmediately){ $rootScope.saveInProgress = true; }
$scope.updatePromise = $http.put('/forms/'+$scope.myform._id, {form: $scope.myform})
$scope.updatePromise = $http.put('/forms/'+$scope.myform._id, { changes: diffChanges })
.then(function(response){
$rootScope.myform = $scope.myform = response.data;
// console.log(response.data);

View file

@ -32,7 +32,6 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
$rootScope.finishedRender = false;
$scope.$on('editFormFields Started', function(ngRepeatFinishedEvent) {
// console.log('hello');
$rootScope.finishedRender = false;
});
$scope.$on('editFormFields Finished', function(ngRepeatFinishedEvent) {
@ -52,13 +51,11 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
return false;
};
var debounceSave = function () {
$rootScope.saveInProgress = true;
var debounceSave = function (diffChanges) {
$rootScope[$attrs.autoSaveCallback](true,
$rootScope[$attrs.autoSaveCallback](true, diffChanges,
function(err){
if(!err){
//console.log('\n\nForm data persisted -- setting pristine flag');
$formCtrl.$setPristine();
$formCtrl.$setUntouched();
}else{
@ -70,12 +67,10 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
//Update/Save Form if any Form fields are Dirty and Touched
$scope.$watch(function(newValue, oldValue) {
//console.log('introParagraphStartPage.$dirty: '+$scope.editForm.introParagraphStartPage.$dirty);
//console.log('introParagraphStartPage.$touched: '+$scope.editForm.introParagraphStartPage.$touched);
if($rootScope.finishedRender && $scope.anyDirtyAndTouched($scope.editForm) && !$rootScope.saveInProgress){
//console.log('Form saving started');
debounceSave();
//console.log('introParagraphStartPage.$dirty AFTER: '+$scope.editForm.introParagraphStartPage.$dirty);
delete newValue.visible_form_fields;
debounceSave(DeepDiff.diff(oldValue, newValue));
}
});
@ -89,7 +84,6 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
oldValue.form_fields = _.removeDateFields(oldValue.form_fields);
var changedFields = !_.isEqual(oldValue.form_fields,newValue.form_fields) || !_.isEqual(oldValue.startPage, newValue.startPage);
var changedFieldMap = false;
if(oldValue.hasOwnProperty('plugins.oscarhost.settings.fieldMap')){
changedFieldMap = !!oldValue.plugins.oscarhost.settings.fieldMap && !_.isEqual(oldValue.plugins.oscarhost.settings.fieldMap,newValue.plugins.oscarhost.settings.fieldMap);
@ -117,7 +111,7 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
}
//Save form ONLY IF rendering is finished, form_fields have been changed AND currently not save in progress
if( $rootScope.finishedRender && ((changedFields && !$formCtrl.$dirty) || changedFieldMap) && !$rootScope.saveInProgress) {
if( $rootScope.finishedRender && (changedFields && !$formCtrl.$dirty) && !$rootScope.saveInProgress) {
if(savePromise) {
$timeout.cancel(savePromise);
@ -125,7 +119,12 @@ angular.module('forms').directive('autoSaveForm', ['$rootScope', '$timeout', fun
}
savePromise = $timeout(function() {
debounceSave();
$rootScope.saveInProgress = true;
delete newValue.visible_form_fields;
delete newValue.visible_form_fields;
var _diff = DeepDiff.diff(oldValue, newValue);
debounceSave(_diff);
});
}
//If we are finished rendering then form saving should be finished

View file

@ -10,7 +10,6 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
},
controller: function($scope){
console.log($scope.myform);
var field_ids = _($scope.myform.form_fields).pluck('_id');
for(var i=0; i<field_ids.length; i++){
$scope.myform.plugins.oscarhost.settings.fieldMap[field_ids[i]] = null;
@ -109,7 +108,7 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
}
}
var newField = {
title: fieldTitle,
title: fieldTitle + ' ' + $scope.myform.form_fields.length+1,
fieldType: fieldType,
fieldValue: '',
required: true,
@ -126,7 +125,6 @@ angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormField
});
}
if(modifyForm){
//Add newField to form_fields array
$scope.myform.form_fields.push(newField);

View file

@ -83,23 +83,24 @@ angular.module('forms').directive('fieldDirective', ['$http', '$compile', '$root
if(scope.field.fieldType === 'number' || scope.field.fieldType === 'textfield' || scope.field.fieldType === 'email' || scope.field.fieldType === 'link'){
switch(scope.field.fieldType){
case 'textfield':
scope.field.input_type = 'text';
scope.input_type = 'text';
break;
case 'email':
scope.field.input_type = 'email';
scope.field.placeholder = 'joesmith@example.com';
scope.input_type = 'email';
scope.placeholder = 'joesmith@example.com';
break;
case 'number':
scope.field.input_type = 'text';
scope.field.validateRegex = /^-?\d+$/;
scope.input_type = 'text';
scope.validateRegex = /^-?\d+$/;
break;
default:
scope.field.input_type = 'url';
scope.field.placeholder = 'http://example.com';
scope.input_type = 'url';
scope.placeholder = 'http://example.com';
break;
}
fieldType = 'textfield';
}
var template = getTemplateUrl(fieldType);
element.html(template).show();
var output = $compile(element.contents())(scope);

View file

@ -1,8 +1,8 @@
<div class="textfield field row"
ng-click="setActiveField(field._id, index, true)">
<div class="col-xs-12 field-title row-fluid" ng-style="{'color': design.colors.questionColor}">
<h3 class="col-xs-12">
<small class="field-number">
<h3 class="col-xs-12">
<small class="field-number">
{{index+1}}
<i class="fa fa-angle-double-right" aria-hidden="true"></i>
</small>
@ -12,54 +12,119 @@
<span class="required-error" ng-show="!field.required">
({{ 'OPTIONAL' | translate }})
</span>
</h3>
</h3>
<p class="col-xs-12">
<small>{{field.description}}</small>
</p>
</div>
<div class="col-xs-12 field-input">
</div>
<div class="col-xs-12 field-input">
<input ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}"
name="{{field.fieldType}}{{index}}"
type="{{field.input_type}}"
ng-pattern="field.validateRegex"
placeholder="{{field.placeholder}}"
ng-class="{ 'no-border': !!field.fieldValue }"
class="focusOn text-field-input"
ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }"
value="field.fieldValue"
ng-focus="setActiveField(field._id, index, true)"
on-enter-or-tab-key="nextField()"
on-tab-and-shift-key="prevField()"
ng-required="field.required"
ng-disabled="field.disabled"
aria-describedby="inputError2Status">
</div>
<div class="col-xs-12">
<div ng-show="forms.myForm.{{field.fieldType}}{{index}}.$invalid && !!forms.myForm.{{field.fieldType}}{{index}}.$viewValue " class="alert alert-danger" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
name="{{field.fieldType}}{{index}}"
type="{{input_type}}"
ng-pattern="validateRegex"
placeholder="{{placeholder}}"
ng-class="{ 'no-border': !!field.fieldValue }"
class="focusOn text-field-input"
ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }"
value="field.fieldValue"
ng-focus="setActiveField(field._id, index, true)"
on-enter-or-tab-key="nextField()"
on-tab-and-shift-key="prevField()"
ng-required="field.required"
ng-disabled="field.disabled"
aria-describedby="inputError2Status">
</div>
<div class="col-xs-12">
<div ng-show="forms.myForm.{{field.fieldType}}{{index}}.$invalid && !!forms.myForm.{{field.fieldType}}{{index}}.$viewValue " class="alert alert-danger" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
<span ng-if="field.fieldType == 'email'"> {{ 'ERROR_EMAIL_INVALID' | translate }} </span>
<span ng-if="field.validateRegex"> {{ 'ERROR_NOT_A_NUMBER' | translate }} </span>
<span ng-if="field.fieldType == 'link'"> {{ 'ERROR_URL_INVALID' | translate }} </span>
</div>
</div>
</div>
<div>
<div class="btn btn-lg btn-default hidden-xs"
style="padding: 4px; margin-top:8px; background: rgba(255,255,255,0.5)">
<button ng-disabled="!field.fieldValue || forms.myForm.{{field.fieldType}}{{$index}}.$invalid"
ng-style="{'background-color':design.colors.buttonColor, 'color':design.colors.buttonTextColor}"
ng-click="$root.nextField()"
class="btn col-sm-5 col-xs-5">
{{ 'OK' | translate }} <i class="fa fa-check"></i>
</button>
<div class="col-xs-6 col-sm-3" style="margin-top:0.2em">
<small style="color:#ddd; font-size:70%">
{{ 'ENTER' | translate }}
</small>
</div>
</div>
</div>
</div>
<div>
<div class="btn btn-lg btn-default col-xs-12 col-sm-4 hidden-xs"
style="padding: 4px; margin-top:8px; background: rgba(255,255,255,0.5)">
<button ng-disabled="!field.fieldValue || forms.myForm.{{field.fieldType}}{{$index}}.$invalid"
ng-style="{'background-color':design.colors.buttonColor, 'color':design.colors.buttonTextColor}"
ng-click="$root.nextField()"
class="btn col-sm-5 col-xs-5">
{{ 'OK' | translate }} <i class="fa fa-check"></i>
</button>
<div class="col-xs-6 col-sm-3" style="margin-top:0.2em">
<small style="color:#ddd; font-size:70%">
{{ 'ENTER' | translate }}
</small>
</div>
</div>
</div>
<div class="textfield field row"
ng-click="setActiveField(field._id, index, true)">
<div class="col-xs-12 field-title row-fluid" ng-style="{'color': design.colors.questionColor}">
<h3 class="col-xs-12">
<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' | translate }})
</span>
</h3>
<p class="col-xs-12">
<small>{{field.description}}</small>
</p>
</div>
<div class="col-xs-12 field-input">
<input ng-style="{'color': design.colors.answerColor, 'border-color': design.colors.answerColor}"
name="{{field.fieldType}}{{index}}"
type="{{input_type}}"
ng-pattern="validateRegex"
placeholder="{{placeholder}}"
ng-class="{ 'no-border': !!field.fieldValue }"
class="focusOn text-field-input"
ng-model="field.fieldValue"
ng-model-options="{ debounce: 250 }"
value="field.fieldValue"
ng-focus="setActiveField(field._id, index, true)"
on-enter-or-tab-key="nextField()"
on-tab-and-shift-key="prevField()"
ng-required="field.required"
ng-disabled="field.disabled"
aria-describedby="inputError2Status">
</div>
<div class="col-xs-12">
<div ng-show="forms.myForm.{{field.fieldType}}{{index}}.$invalid && !!forms.myForm.{{field.fieldType}}{{index}}.$viewValue " class="alert alert-danger" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
<span ng-if="field.fieldType == 'email'"> {{ 'ERROR_EMAIL_INVALID' | translate }} </span>
<span ng-if="field.validateRegex"> {{ 'ERROR_NOT_A_NUMBER' | translate }} </span>
<span ng-if="field.fieldType == 'link'"> {{ 'ERROR_URL_INVALID' | translate }} </span>
</div>
</div>
</div>
<div>
<div class="btn btn-lg btn-default col-xs-12 col-sm-4 hidden-xs"
style="padding: 4px; margin-top:8px; background: rgba(255,255,255,0.5)">
<button ng-disabled="!field.fieldValue || forms.myForm.{{field.fieldType}}{{$index}}.$invalid"
ng-style="{'background-color':design.colors.buttonColor, 'color':design.colors.buttonTextColor}"
ng-click="$root.nextField()"
class="btn col-sm-5 col-xs-5">
{{ 'OK' | translate }} <i class="fa fa-check"></i>
</button>
<div class="col-xs-6 col-sm-3" style="margin-top:0.2em">
<small style="color:#ddd; font-size:70%">
{{ 'ENTER' | translate }}
</small>
</div>
</div>
</div>